![](/img/trans.png)
[英]PostgreSQL: create unique constraint on join table (multi-table constaint)
[英]postgresql: constaint to have unique values across 2 tables
我有 2 张桌子:
CREATE TABLE public."user"
(
id integer NOT NULL DEFAULT nextval('user_id_seq'::regclass),
username character varying(256) COLLATE pg_catalog."default",
CONSTRAINT user_pkey PRIMARY KEY (id)
)
CREATE TABLE public.user_tenant
(
user_id integer NOT NULL,
tenant_id integer NOT NULL,
CONSTRAINT user_fk FOREIGN KEY (user_id)
REFERENCES public."user" (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE CASCADE
)
我需要有唯一的值(user.username、user_tenant.tenant_id)。 如何声明这样的约束?
我会让用户名独一无二,就像另一个表中的租户一样。 完成后,您可以在 user_id 和 tenant_id 上放置一个主键:
CREATE TABLE public."user"
(
id integer NOT NULL DEFAULT nextval('user_id_seq'::regclass),
username character varying(256) COLLATE pg_catalog."default" unique,
CONSTRAINT user_pkey PRIMARY KEY (id)
);
CREATE TABLE public.user_tenant
(
user_id integer NOT NULL,
tenant_id integer NOT NULL,
CONSTRAINT user_fk FOREIGN KEY (user_id)
REFERENCES public."user" (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE CASCADE,
CONSTRAINT user_tenant_pk PRIMARY KEY (user_id, tenant_id)
);
顺便说一句,不要将“用户”之类的保留名称用作表名。
您可以创建一个 function ,它可以检查多个表的唯一性(此处示例: Postgres unique combination constraint across tables )但看起来您可能需要表结构或遵循弗兰克海肯斯的回答。
编辑:
CREATE TABLE public."user"
(
id SERIAL,
username character varying(256) COLLATE pg_catalog."default",
PRIMARY KEY (id)
);
CREATE TABLE public.user_tenant
(
user_id integer NOT NULL,
tenant_id integer NOT NULL,
CONSTRAINT user_fk FOREIGN KEY (user_id)
REFERENCES public."user" (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE CASCADE
);
CREATE OR REPLACE FUNCTION public.check_user_tenant(user_id integer, tenant_id integer)
RETURNS boolean AS
$$
DECLARE b_result boolean;
BEGIN
SELECT (COUNT(*) = 0) INTO b_result
FROM public.user u
JOIN public.user_tenant ut ON ut.user_id IN (SELECT id
FROM public.user i_u
WHERE i_u.username = u.username)
WHERE u.id = $1 AND ut.tenant_id = $2;
RETURN b_result;
END
$$ LANGUAGE 'plpgsql';
ALTER TABLE public.user_tenant
ADD CONSTRAINT check_filename CHECK
(public.check_user_tenant(user_id, tenant_id));
-- Testing:
insert into public."user" (username) VALUES ('foo');
insert into public.user_tenant (user_id, tenant_id) VALUES (1,3);
insert into public."user" (username) VALUES ('foo');
-- Violates constraint:
insert into public.user_tenant (user_id, tenant_id) VALUES (2,3);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.