2つのテーブルがあります。user
テーブルとfriendship
テーブルです。 friendship
テーブルが次のようになっているとします。
friendship
------------
user_one_id
user_two_id
other_fields
(user_one_id, user_two_id)
の値の組み合わせの一意性を適用し、orderingを無視する必要があるため、次のようにします。
user_one_id | user_two_id
------------+------------
1 | 2
2 | 1 -- the DBMS should throw a unique constraint error when trying to insert a row like this one.
もう1つの重要な点は、user_one_id
がfriendship
の開始者を表し、user_two_id
が受信者なので、2つのidsuser_one_id
を「小さく」することはできません。
質問
制約を使用してこれを行う方法はありますか、これを他の方法で実装する必要がありますか?
あなたのコメントに照らして、
私の使用例では、user_one_idは友情の開始者を表し、user_two_idは友情の受信者を表します。 したがって、user_one_idとして最小値を使用することはできません。
まあ、あなたはまだそれを行うことができます。ユースケースでは、それを確実にするために行制約を除外しています。あなたが望むのは、このようなテーブル制約を使用することです。
_CREATE TABLE friendship (
user_one_id int NOT NULL,
user_two_id int NOT NULL,
CHECK (user_one_id != user_two_id ),
PRIMARY KEY (user_one_id, user_two_id)
);
-- you can do least first if you want. doesn't matter.
CREATE UNIQUE INDEX ON friendship (
greatest(user_one_id, user_two_id),
least(user_one_id, user_two_id)
);
_
ここでは多くのことが起こっています。
NOT NULL
_ですUNIQUE (user_one_id, user_two_id)
です可換一意性の問題が1つ残っていますが、インデックスで実装されたカスタムの一意のテーブル制約を使用してそれを解決します。
プリンの証明
_INSERT INTO friendship VALUES ( 1,2 );
INSERT 0 1
test=# INSERT INTO friendship VALUES ( 2,1 );
ERROR: duplicate key value violates unique constraint friendship_greatest_least_idx"
DETAIL: Key ((GREATEST(user_one_id, user_two_id)), (LEAST(user_one_id, user_two_id)))=(2, 1) already exists.
_
重要な友好的なメモとして、あなたの名前はあらゆる種類のばかげています。関係は結構です。本番環境では、pleaseより良い名前を付けてください。
_friendship
----------
request_initiator
request_target
other_fields
_
ソリューションは非常に優れています。ただし、最初に2つの列に数値の重複がないことを確認する必要があります。つまり、番号は列に対して一意になります。
次のシンプルトンソリューションをお勧めします。
2つのシーケンスを作成します。
1。
user_one_id_seq:偶数
奇数のuser_two_id_seq
2。
user_one_id_seq:たとえば1から10000までの数字
user_two_id_seqは、たとえば10001から20000までの数値
User_friendshipという名前の交差テーブルを作成して、設計を正規化する必要があります。
create user_friendship(user id int NOT NULL、friendship id int NOT NULL、PRIMARY KEY(user_id、friendship_id)、FOREIGN KEY friendship_id REFERENCES friendship(friendship_id)、FOREIGN KEY user_id REFERENCES user(user_id)
);