PostgreSQL - 不同数据类型的约束
PostgreSQL - Constraint with differents data types
在 PostgreSQL
中,我需要一个 constraint
来控制值 is/are 是否存在。此 constraint
应用于 uuid[]
数据类型列。它必须检查 array
的每个值是否存在于同一 table 的另一列中,在 uuid
数据类型列中。
我可以用两种相似的数据类型编写 constraint
,但是如何使用两种不同的数据类型 运行 相同的逻辑?
在我的例子中:检查 uuid[]
array
中 uuid
类型的值。
Table
CREATE TABLE IF NOT EXISTS public.contact
(
uuid uuid NOT NULL DEFAULT uuid_generate_v4(),
name character varying COLLATE pg_catalog."default" NOT NULL,
parent_uuid uuid,
parent_name character varying COLLATE pg_catalog."default",
child_uuids uuid[],
child_names character varying[],
CONSTRAINT contact_pk PRIMARY KEY (uuid),
CONSTRAINT name_uk UNIQUE (name)
)
TABLESPACE pg_default;
第一个约束(parent): 好的
-- Check if parent_uuid exists in public.contact
ALTER TABLE public.contact ADD CONSTRAINT parent_uuid_fk FOREIGN KEY (parent_uuid)
REFERENCES public.contact (uuid) MATCH FULL
ON DELETE SET NULL ON UPDATE CASCADE;
第二个约束(children): 不兼容的类型:uuid[] 和 uuid
-- Check if child_uuids exists in public.contact
ALTER TABLE public.contact ADD CONSTRAINT child_uuids_fk FOREIGN KEY (child_uuids)
REFERENCES public.contact (uuid) MATCH FULL
ON DELETE SET NULL ON UPDATE CASCADE;
没有好的办法。
您不能创建这样的约束。
您可以做的是创建一个触发器函数,尝试验证条件并在违反条件时抛出错误。但是 such triggers are always susceptible to race conditions 除非你使用 SERIALIZABLE
事务隔离级别,这会导致性能下降。
我想说这里唯一好的解决方案是重新设计并使用联结 table 来实现关系而不是数组。那么问题就迎刃而解了。
在 PostgreSQL
中,我需要一个 constraint
来控制值 is/are 是否存在。此 constraint
应用于 uuid[]
数据类型列。它必须检查 array
的每个值是否存在于同一 table 的另一列中,在 uuid
数据类型列中。
我可以用两种相似的数据类型编写 constraint
,但是如何使用两种不同的数据类型 运行 相同的逻辑?
在我的例子中:检查 uuid[]
array
中 uuid
类型的值。
Table
CREATE TABLE IF NOT EXISTS public.contact
(
uuid uuid NOT NULL DEFAULT uuid_generate_v4(),
name character varying COLLATE pg_catalog."default" NOT NULL,
parent_uuid uuid,
parent_name character varying COLLATE pg_catalog."default",
child_uuids uuid[],
child_names character varying[],
CONSTRAINT contact_pk PRIMARY KEY (uuid),
CONSTRAINT name_uk UNIQUE (name)
)
TABLESPACE pg_default;
第一个约束(parent): 好的
-- Check if parent_uuid exists in public.contact
ALTER TABLE public.contact ADD CONSTRAINT parent_uuid_fk FOREIGN KEY (parent_uuid)
REFERENCES public.contact (uuid) MATCH FULL
ON DELETE SET NULL ON UPDATE CASCADE;
第二个约束(children): 不兼容的类型:uuid[] 和 uuid
-- Check if child_uuids exists in public.contact
ALTER TABLE public.contact ADD CONSTRAINT child_uuids_fk FOREIGN KEY (child_uuids)
REFERENCES public.contact (uuid) MATCH FULL
ON DELETE SET NULL ON UPDATE CASCADE;
没有好的办法。
您不能创建这样的约束。
您可以做的是创建一个触发器函数,尝试验证条件并在违反条件时抛出错误。但是 such triggers are always susceptible to race conditions 除非你使用
SERIALIZABLE
事务隔离级别,这会导致性能下降。
我想说这里唯一好的解决方案是重新设计并使用联结 table 来实现关系而不是数组。那么问题就迎刃而解了。