私はpostgres8.3.4データベースを持っています。トリプレットUNIQ(name、id、age)に一意の制約がある名前テーブルが存在します。どういうわけか、この制約の違反を引き起こすデータベースに追加されたいくつかの行があります。
私の質問は、これがどのように可能かということです。制約に違反する最初の行が追加されたときに、データベースがエラーをスローするべきではありませんか?
名前:テキスト
ID:nullではない整数(IDテーブルへのfk)
年齢:整数
私はpostgres8.3.4データベースを持っています。トリプレットUNIQ(name、id、age)に一意の制約がある名前テーブルが存在します。どういうわけか、この制約の違反を引き起こすデータベースに追加されたいくつかの行があります。
私の質問は、これがどのように可能かということです。制約に違反する最初の行が追加されたときに、データベースがエラーをスローするべきではありませんか?
名前:テキスト
ID:nullではない整数(IDテーブルへのfk)
年齢:整数
私の推測では、NULL
値が決してUNIQUE
ではないという事実を見逃していると思います。
複数回エントリー(NULL, 1, 20)
し(name, id, age)
ても、固有の違反は発生しません。2 つのNULL
値が「同じ」と見なされることはありません。
関連するすべての列を設定することもできますNOT NULL
(NULL 値をダミー値に置き換えた後)。
または、追加の部分インデックスを実装して NULL をカバーすることもできます (で「重複」をクリーンアップした後NULL
)。たとえば、name
NULL の列をカバーする必要がある場合:
CREATE UNIQUE INDEX tbl_id_age_name_null_idx ON my_table (id, age)
WHERE name IS NULL;
次に、テーブルの (name, id, age) に対して ('pete', 1, 20) と ('jane', 1, 20) と (NULL, 1, 20) を使用できますが、これらのいずれも 2 回目は使用できません. 最近、dba.SE でこのケースのより詳細な評価を書きました。
ところで: PostgreSQL のバージョンを更新することを検討する必要があります。できれば現在のバージョン 9.1 に。または、少なくとも最新のポイント リリース 8.3.18 まで。多数の修正が行われました。
それはほとんど実現可能ではありません。
ほとんどの場合、名前などに余分なスペースがあります。
正確なテーブル定義を投稿してください。
また、次のクエリを実行してください。
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)
ここに返された出力を投稿します。