3

私はpostgres8.3.4データベースを持っています。トリプレットUNIQ(name、id、age)に一意の制約がある名前テーブルが存在します。どういうわけか、この制約の違反を引き起こすデータベースに追加されたいくつかの行があります。

私の質問は、これがどのように可能かということです。制約に違反する最初の行が追加されたときに、データベースがエラーをスローするべきではありませんか?

名前:テキスト
ID:nullではない整数(IDテーブルへのfk)
年齢:整数

4

2 に答える 2

5

私の推測では、NULL値が決してUNIQUEではないという事実を見逃していると思います。
複数回エントリー(NULL, 1, 20)(name, id, age)ても、固有の違反は発生しません。2 つのNULL値が「同じ」と見なされることはありません。

関連するすべての列を設定することもできますNOT NULL(NULL 値をダミー値に置き換えた後)。

または、追加の部分インデックスを実装して NULL をカバーすることもできます (で「重複」をクリーンアップした後NULL)。たとえば、nameNULL の列をカバーする必要がある場合:

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 まで。多数の修正が行われました。

于 2012-04-22T15:06:28.617 に答える
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)

ここに返された出力を投稿します。

于 2012-04-22T09:03:40.543 に答える