postgresql – 复合PRIMARY KEY对涉及的列强制执行NOT NULL约束
这是我在Postgres遇到的一个奇怪的,不受欢迎的行为:
当我使用复合主键创建Postgres表时,它会对复合组合的每一列强制执行NOT NULL约束. 例如, CREATE TABLE distributors (m_id integer,x_id integer,PRIMARY KEY(m_id,x_id)); 在列m_id和x_id上强制执行NOT NULL约束,这是我不想要的! 我知道PRIMARY KEY自动强制执行UNIQUE和NOT NULL,但这对于单列主键是有意义的.在多列主键表中,唯一性由组合确定. 有没有简单的方法来避免Postgres的这种行为? CREATE TABLE distributors (m_id integer,x_id integer); 我当然没有得到任何NOT NULL约束.
如果您需要允许NULL值,请使用
UNIQUE constraint而不是PRIMARY KEY(并添加代理PK列,我建议使用
serial ).这允许列为NULL:
CREATE TABLE distributor ( distributor_id serial PRIMARY KEY,m_id integer,UNIQUE(m_id,x_id) ); 但请注意(per documentation):
在您的情况下,您可以为(m_id,x_id)输入(1,NULL)任意次数而不违反约束. Postgres从不认为两个NULL值相等 – 根据SQL标准中的定义. 如果您需要将NULL值视为等于禁止此类“重复”,我会看到两个选项: 1.两个部分索引 除了上面的UNIQUE约束: CREATE UNIQUE INDEX dist_m_uni_idx ON distributor (m_id) WHERE x_id IS NULL; CREATE UNIQUE INDEX dist_x_uni_idx ON distributor (x_id) WHERE m_id IS NULL; 但是,如果两列以上的列可以为NULL,则会快速失控. > Create unique constraint with null columns 2.表达式的多列UNIQUE索引 而不是UNIQUE约束.我们需要一个在相关列中永远不会出现的自由默认值,例如-1.添加CHECK约束以禁止它: CREATE TABLE distributor ( distributor serial PRIMARY KEY,x_id integer ,CHECK (m_id <> -1),CHECK (x_id <> -1) ); CREATE UNIQUE INDEX distributor_uni_idx ON distributor (COALESCE(m_id,-1),COALESCE(x_id,-1)) 某些RDBMS如何处理事情并不总是正确行为的有用指标. Postgres manual hints at this:
大胆强调我的. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |