title: How do we design schema for user settings table for postgresql?
body: <p>How do we design schema for user settings/preferences table in a sql database like postgresql?</p>
  <p>I am interested to know the proper way to design the schema of <code>users_setting</code> table where users are able to modify their settings. This seems to be a 1-to-1 relationship because each row of <code>users</code> table corresponds to a single row in the <code>users_setting</code> table</p>
  <p>so this is like a 1-to-1 table relation between <code>users</code> and <code>users_setting</code>. Is this the wrong way to do this? I have searched online and could not really find any useful example schemas where users manage their settings. So here i am asking this question. I am certain this will help many people also</p>
  <p>Here is what my current design looks like</p>
  <p><a href="https://i.stack.imgur.com/YRs8S.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/YRs8S.png" alt="enter image description here" /></a></p>
  <pre><code>DROP TABLE if exists users cascade;
  DROP TABLE IF EXISTS &quot;users&quot;;
  DROP SEQUENCE IF EXISTS users_id_seq;
  CREATE SEQUENCE users_id_seq INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1;
  
  CREATE TABLE &quot;public&quot;.&quot;users&quot; (
      &quot;id&quot; bigint DEFAULT nextval('users_id_seq') NOT NULL,
      &quot;email&quot; text NOT NULL,
      &quot;password&quot; text NOT NULL,
      &quot;full_name&quot; text NOT NULL,
      &quot;status&quot; text NOT NULL,
      &quot;is_verified&quot; boolean NOT NULL,
      &quot;role&quot; text NOT NULL,
      &quot;created_at&quot; timestamptz NOT NULL,
      &quot;updated_at&quot; timestamptz NOT NULL,
      &quot;verified_at&quot; timestamptz NOT NULL,
      CONSTRAINT &quot;users_email_key&quot; UNIQUE (&quot;email&quot;),
      CONSTRAINT &quot;users_pkey&quot; PRIMARY KEY (&quot;id&quot;)
  ) WITH (oids = false);
  
  DROP TABLE if exists users_setting cascade;
  DROP TABLE IF EXISTS &quot;users_setting&quot;;
  DROP SEQUENCE IF EXISTS users_setting_id_seq;
  CREATE SEQUENCE users_setting_id_seq INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1;
  
  CREATE TABLE &quot;public&quot;.&quot;users_setting&quot; (
      &quot;id&quot; bigint DEFAULT nextval('users_setting_id_seq') NOT NULL,
      &quot;default_currency&quot; text NOT NULL,
      &quot;default_timezone&quot; text NOT NULL,
      &quot;default_notification_method&quot; text NOT NULL,
      &quot;default_source&quot; text NOT NULL,
      &quot;default_cooldown&quot; integer NOT NULL,
      &quot;updated_at&quot; timestamptz NOT NULL,
      &quot;user_id&quot; bigint,
      CONSTRAINT &quot;users_setting_pkey&quot; PRIMARY KEY (&quot;id&quot;)
  ) WITH (oids = false);
  
  
  ALTER TABLE ONLY &quot;public&quot;.&quot;users_setting&quot; ADD CONSTRAINT &quot;users_setting_user_id_fkey&quot; FOREIGN KEY (user_id) REFERENCES &quot;users&quot;(id) NOT DEFERRABLE;
  
  begin transaction;
  
  INSERT INTO &quot;users&quot; (&quot;id&quot;, &quot;email&quot;, &quot;password&quot;, &quot;full_name&quot;, &quot;status&quot;, &quot;is_verified&quot;, &quot;role&quot;, &quot;created_at&quot;, &quot;updated_at&quot;, &quot;verified_at&quot;) VALUES
  (1, 'users1@email.com', 'password', 'users1',   'active',   '1', 'superuser', '2022-07-05 01:05:50.22384+00',   '0001-01-01 00:00:00+00',   '2022-07-11 14:10:26.615722+00'),
  (2, 'users2@email.com', 'password', 'users2', 'active', '0', 'user', '2022-07-05 01:05:50.22384+00',    '0001-01-01 00:00:00+00',   '2022-07-11 14:10:26.615722+00');
  
  INSERT INTO &quot;users_setting&quot; (&quot;id&quot;, &quot;default_currency&quot;, &quot;default_timezone&quot;, &quot;default_notification_method&quot;, &quot;default_source&quot;, &quot;default_cooldown&quot;, &quot;updated_at&quot;, &quot;user_id&quot;) VALUES
  (1, 'usd', 'utc', 'email',  'google',   300, '2022-07-13 01:05:50.22384+00', 2),
  (2, 'usd', 'utc', 'sms',    'yahoo',    600, '2022-07-14 01:05:50.22384+00',    2);
  
  commit;
  </code></pre>
  <p>so lets say i want to return a single row where a users.email is <code>users1@email.com</code> for example, here is query i can run</p>
  <pre><code>select * from users, users_setting where users.id = users_setting.user_id AND users.email = 'users1@email.com';
  </code></pre>
  <pre><code>id  email               password    full_name   status  is_verified role    created_at  updated_at  verified_at id  default_currency    default_timezone    default_notification_method default_source  default_cooldown    updated_at  user_id
  1   users1@email.com    password    users1  active  1   superuser   2022-07-05 01:05:50.22384+00    0001-01-01 00:00:00+00  2022-07-11 14:10:26.615722+00   1   usd utc email   google  300 2022-07-13 01:05:50.22384+00    1
  </code></pre>
  <p>i can have a single table for this but the table will get really long row-wise as i add more and more thing. user settings is just one, there are other tables similar to this. So will be great to know how to design a situation like this properly</p>