[英]How do we design schema for user settings table for postgresql?
我們如何為像 postgresql 這樣的 sql 數據庫中的用戶設置/首選項表設計模式?
我很想知道設計users_setting
表模式的正確方法,用戶可以在其中修改他們的設置。 這似乎是一對一的關系,因為users
表的每一行對應於users_setting
表中的一行
所以這就像users
和users_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.