web-dev-qa-db-ja.com

両方のプライマリ列が同じ外部列を指しているEAVのようなテーブル

背景:私はプログラマーであり、単純なデータベースを数回操作する必要がありましたが、複雑なデータベースを操作する必要はありませんでした。つまり私は基本的なものに精通していますが、高度な機能やデザインについては無知です。

2人のユーザー間の一致の結果を含むテーブルを作成する必要があります。

  • table_A:user_id(primary int)、その他
  • table_B:user1(table_A user_idを指すプライマリ外部キー)、user2(table_A user_idを指すプライマリ外部キー)、その他

user2<user1を強制できますか?これは、行がuser1==user2およびを持たないようにするためであり、カップルが反転される場合、つまりI (alice,bob)(bob,alice)の両方を持つ必要はありません。

-または-私はそもそもそれをすべて間違ってやっています、そしてそれをするための別の、完全に異なるアプローチがありますか?

明らかに値を追加する前にチェックできます(そしてチェックします)が、私が理解している限り、SQLで制約を追加できれば、一貫性があることを確認するために、追加することをお勧めします。

データベースは現在sqliteですが、これをsqliteで実行できないが、他のエンジンで実行できる場合(特に、InnoDBの場合)、これも有用な回答になる可能性があります。

PS:これがまだEAVとしてカウントされるかどうかはわかりません。これは、AFAIK EAVがdifferentテーブルからの2つのプライマリと、1つの追加の列を意味するためです。代わりに、複数あります。

3
o0'.

単純なCHECK制約は問題なく機能します。

$ sqlite
SQLite version 3.8.4.1 2014-03-11 15:27:36
...
sqlite> CREATE TABLE table_B(
   ...>     user1,
   ...>     user2,
   ...>     [other stuff],
   ...>     CHECK (user2 < user1)
   ...> );
sqlite> INSERT INTO table_B VALUES (1, 0);
sqlite> INSERT INTO table_B VALUES (2, 3);
Error: CHECK constraint failed: table_B

(これはEAVとは何の関係もありません。)

5
CL.

この質問はEAVとは関係ありません( エンティティ属性値 )-選択した検索エンジンを使用して「CelkoEAV」を探します

正確な構文についてはわかりませんが、

CREATE TABLE table_b
(
  user1 VARCHAR(25),  -- or INTEGER, ideally of same types, otherwise comparisons are difficult
  user2 VARCHAR(25),  -- or INTEGER
  --  
  -- other fields,
  --
  CONSTRAINT table_b_pk PRIMARY KEY (user_1, ...), 
  -- maybe other fields in the PK - not clear from question
  CONSTRAINT table_b_uq UNIQUE (user_1, user2), 
  -- so that the combination (user_1, user_2) can't be duplicated 
  CONSTRAINT user_1_ne_user_2  CHECK (user1 != user2)  
  -- this will enforce user_1 not equal to user_2 regardless of the sorting of the strings 
  -- you could have CHECK (user1 < user2) if that is key to your requirements
  -- it doesn't appear to be critical from the question.
);

動作するはずです-Firebird組み込みで動作します。

AIUI(私が理解しているように)、SQLiteはCHECK制約のサブクエリをサポートしていません(*赤いニシン-以下を参照-私の元の文はあいまいで混乱していました)。この状況では、FirebirdのみがサポートするCHECK制約のサブクエリは必要ありません。

制約があなたの(alice, bob)-(bob, alice) 問題。

1
Vérace