Foreign-Key
兩個主列都指向同一個外部列的類似 EAV 的表
背景:我是一名程序員,雖然不得不多次使用簡單的數據庫,但從未使用過複雜的數據庫。即我精通基本的東西,但對高級功能和設計一無所知。
我需要創建一個包含兩個使用者之間匹配結果的表,即:
- table_A: user_id (primary int), 其他東西
- table_B:user1(指向table_A user_id的主外鍵),user2(指向table_A user_id的主外鍵),其他東西
我可以強制執行
user2<user1
嗎?這是為了防止行具有user1==user2
,並防止在這對夫婦被倒置的情況下創建行,即我不需要同時擁有(alice,bob)
和(bob,alice)
。-或者- 我一開始就做錯了,還有另一種完全不同的方法來做到這一點?
顯然我可以(並且將)在添加它們之前檢查這些值,但據我所知,如果我可以在 SQL 中添加一個約束,我最好添加它,以確保它是一致的。
數據庫目前是sqlite,但如果這不能在 sqlite 中完成但可以用其他引擎完成(特別是如果 InnoDB),它也可能是一個有用的答案。
PS:我不確定這是否仍算作 EAV,因為 AFAIK EAV 意味著來自不同表的兩個主要元素和一個額外的列,而我將擁有多個列。
一個簡單的 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 無關。)
此問題與 EAV(實體屬性值)無關 - 使用您選擇的搜尋引擎查找“Celko EAV”
不確定確切的語法,但是
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
約束中的子查詢(* 紅鯡魚 - 見下文 - 我的原句模棱兩可且令人困惑)。這種情況不需要CHECK
約束中的子查詢,無論如何只有 Firebird 支持。約束將處理您的 (
alice, bob
) - (bob, alice
) 問題。