我有一个postgres 8.3.4数据库。存在名称表,其对三元组UNIQ(名称,id,年龄)具有唯一约束。不知何故,有几行已添加到数据库中,导致违反此约束。
我的问题是这怎么可能?当添加违反约束的第一行时,数据库是否应该抛出错误?
姓名:文字
id:integer not null(fk到id表)
年龄:整数
答案 0 :(得分:5)
我的猜测是您错过了 NULL
值永远不会UNIQUE
的事实。
如果您多次为(NULL, 1, 20)
输入(name, id, age)
,则不会遇到任何违规行为。两个NULL
值永远不会被视为“相同”。
您可以设置所有涉及的列 NOT NULL
(在用虚拟值替换NULL值之后)。
或者你可以实现additional partial indexes来覆盖NULL(在使用NULL
清理“dupes”之后)。例如,如果您需要覆盖NULL name
列:
CREATE UNIQUE INDEX tbl_id_age_name_null_idx ON my_table (id, age)
WHERE name IS NULL;
然后你可以在你的表中为(名字,身份,年龄)拥有('pete',1,20)和('jane',1,20)和(NULL,1,20),但这些都不是第二次。我最近写了a more detailed assessment for this case on dba.SE。
顺便说一句:您应该考虑更新version of PostgreSQL。优选地,当前版本为9.1。或至少到最新的点发布8.3.18。已经有很多修复。
答案 1 :(得分:4)
这几乎不可行。
最有可能的是,你在名字或类似的东西中有额外的空格。
请发布确切的表格定义。
另外,请运行此查询:
SELECT q2.*
FROM (
SELECT name, id, age
FROM mytable
GROUP BY
name, id, age
HAVING COUNT(*) > 1
) q
JOIN mytable q2
ON (q2.name, q2.id, q2.age) IS NOT DISTINCT FROM (q.name, q.id, q.age)
并发布一些返回的输出。