Cri*_*ina 9 sql sql-server primary-key foreign-key-relationship relational-database
我认为以下示例将最好地解释这种情况.假设我们有以下表结构:
-------------------------------------
Member1 int NOT NULL (FK)(PK)
Member2 int NOT NULL (FK)(PK)
-------------------------------------
Statust char(1) NOT NULL
Run Code Online (Sandbox Code Playgroud)
以下是该表的表格内容:
Member1 Member2 Status
----------------------------
100 105 A
Run Code Online (Sandbox Code Playgroud)
我的问题是如何实现唯一性,以便下面的INSERT语句将基于表中已有的那一行失败.
INSERT status_table (Member1,Member2,Status) VALUES(105,100,'D');
Run Code Online (Sandbox Code Playgroud)
基本上,我试图模拟两个成员之间的关系.无论我们有(100,105)还是(105,100),状态字段都是相同的.
我知道我可以使用before_insert和before_update触发器来检查表中的内容.但我想知道是否有更好的方法来做到这一点......我的数据库模型应该是不同的......
如果你能确保所有应用/用户成员的ID存储在至少到最大的顺序(最低MEMBERID在Member1与最大的Member2),那么你可以简单地增加一个检查约束:
ALTER TABLE Status_table
ADD CONSTRAINT Status_table_Prevent_double_pairs
CHECK (Member1 < Member2)
Run Code Online (Sandbox Code Playgroud)
如果您不想这样做或者您希望存储额外的信息(因为您正在存储(仅仅是一个示例)"成员100邀请(喜欢,杀死,无论如何)成员150"而不是相反),那么你可以使用@ Tegiri的方法,稍微修改一下(乘以两个足够大的整数会产生溢出问题):
CREATE TABLE Status_table
( Member1 INT NOT NULL
, Member2 INT NOT NULL
, Status CHAR(1) NOT NULL
, MemberOne AS CASE WHEN Member1 < Member2 THEN Member1 ELSE Member2 END
--- a computed column
, MemberTwo AS CASE WHEN Member1 < Member2 THEN Member2 ELSE Member1 END
--- and another one
, PRIMARY KEY (Member1, Member2)
, UNIQUE (MemberOne, MemberTwo)
, ... --- FOREIGN KEY details, etc
) ;
Run Code Online (Sandbox Code Playgroud)