簡體   English   中英

我們如何為 postgresql 的用戶設置表設計模式?

[英]How do we design schema for user settings table for postgresql?

我們如何為像 postgresql 這樣的 sql 數據庫中的用戶設置/首選項表設計模式?

我很想知道設計users_setting表模式的正確方法,用戶可以在其中修改他們的設置。 這似乎是一對一的關系,因為users表的每一行對應於users_setting表中的一行

所以這就像usersusers_setting之間的一對一表關系。 這是錯誤的方法嗎? 我在網上搜索過,並沒有真正找到用戶管理其設置的任何有用的示例模式。 所以我在這里問這個問題。 我相信這也會幫助很多人

這是我目前的設計的樣子

在此處輸入圖像描述

DROP TABLE if exists users cascade;
DROP TABLE IF EXISTS "users";
DROP SEQUENCE IF EXISTS users_id_seq;
CREATE SEQUENCE users_id_seq INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1;

CREATE TABLE "public"."users" (
    "id" bigint DEFAULT nextval('users_id_seq') NOT NULL,
    "email" text NOT NULL,
    "password" text NOT NULL,
    "full_name" text NOT NULL,
    "status" text NOT NULL,
    "is_verified" boolean NOT NULL,
    "role" text NOT NULL,
    "created_at" timestamptz NOT NULL,
    "updated_at" timestamptz NOT NULL,
    "verified_at" timestamptz NOT NULL,
    CONSTRAINT "users_email_key" UNIQUE ("email"),
    CONSTRAINT "users_pkey" PRIMARY KEY ("id")
) WITH (oids = false);

DROP TABLE if exists users_setting cascade;
DROP TABLE IF EXISTS "users_setting";
DROP SEQUENCE IF EXISTS users_setting_id_seq;
CREATE SEQUENCE users_setting_id_seq INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1;

CREATE TABLE "public"."users_setting" (
    "id" bigint DEFAULT nextval('users_setting_id_seq') NOT NULL,
    "default_currency" text NOT NULL,
    "default_timezone" text NOT NULL,
    "default_notification_method" text NOT NULL,
    "default_source" text NOT NULL,
    "default_cooldown" integer NOT NULL,
    "updated_at" timestamptz NOT NULL,
    "user_id" bigint,
    CONSTRAINT "users_setting_pkey" PRIMARY KEY ("id")
) WITH (oids = false);


ALTER TABLE ONLY "public"."users_setting" ADD CONSTRAINT "users_setting_user_id_fkey" FOREIGN KEY (user_id) REFERENCES "users"(id) NOT DEFERRABLE;

begin transaction;

INSERT INTO "users" ("id", "email", "password", "full_name", "status", "is_verified", "role", "created_at", "updated_at", "verified_at") 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 "users_setting" ("id", "default_currency", "default_timezone", "default_notification_method", "default_source", "default_cooldown", "updated_at", "user_id") 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;

所以假設我想返回一個單行,其中 users.email 是users1@email.com例如,這是我可以運行的查詢

select * from users, users_setting where users.id = users_setting.user_id AND users.email = 'users1@email.com';
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

我可以為此設置一個表格,但隨着我添加越來越多的東西,表格會變得非常長。 用戶設置只是其中之一,還有其他類似的表。 所以很高興知道如何正確設計這樣的情況

在您的情況下,JSON 可以完成這項工作:

ALTER TABLE public.users ADD user_settings jsonb NULL;

設置更新將類似於:

UPDATE users
SET user_settings = '{"default_currency": "usd", "default_timezone" : "utc"}'
WHERE id = 1;

並選擇:

select * from users WHERE id  = 1;

你會找到: 在此處輸入圖像描述

還考慮在 Postgresql 中您可以索引 JSON,例如查詢特定設置。 參見此處: https ://www.postgresql.org/docs/current/datatype-json.html#JSON-INDEXING 具體:

盡管如此,通過適當使用表達式索引,上述查詢可以使用索引。 如果查詢“tags”鍵中的特定項目很常見,那么定義這樣的索引可能是值得的:

CREATE INDEX idxgintags ON api USING GIN ((jdoc -> 'tags'));

使用此解決方案,您可以避免使用 JSON。 缺點是與您的第一個想法相比,setting_value 無法根據您需要的確切類型進行定制。
例如,您可以創建:

CREATE TABLE public.user_setting (
    user_id bigint NOT NULL,
    setting_name text NOT NULL,
    setting_value text NULL,
    CONSTRAINT user_setting_pk PRIMARY KEY (user_id,setting_name)
);

ALTER TABLE public.user_setting ADD CONSTRAINT user_setting_fk FOREIGN KEY (user_id) REFERENCES public.users(id);

在這一點上,我建議你有 2 個查詢,一個用於用戶,一個用於設置:

SELECT *
FROM  user_setting us 
where user_id = 1;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM