我有三个表,表A具有自动递增的唯一主键,而另外两个(表B和C)具有主键,这些主键具有将它们与第一个表主键相关联的外键约束。
我想创建一个约束来维护第二个和第三个表中的所有行,它们不能包含任何重复,并且对于表A中的所有记录,在B或C中都有匹配的记录。
所以A类型的记录基本上可以是B型或C型,必须是B或C中的一种。
在没有MySQL的触发器的情况下,是否存在这种约束?或是必要的触发器?
感谢您的帮助。
答案 0 :(得分:1)
您可以使用“类型”表:
CREATE TABLE Type
( type_code CHAR(1) NOT NULL
, PRIMARY KEY (type_code)
) ;
只有2行(与您需要的不同子类型表一样多:
INSERT INTO Type (type_code)
VALUES ('B'), ('C') ;
超类型表(包括引用“类型”的列):
CREATE TABLE A
( a_id INT NOT NULL AUTO_INCREMENT
, type_code CHAR(1) NOT NULL
, PRIMARY KEY (a_id)
, UNIQUE KEY (type_code, a_id)
, FOREIGN KEY (type_code)
REFERENCES Type (type_code)
) ;
子类型表(现在引用A的主键和type_code的组合:
CREATE TABLE B
( a_id INT NOT NULL
, type_code CHAR(1) NOT NULL DEFAULT 'B'
, PRIMARY KEY (type_code, a_id)
, FOREIGN KEY (type_code, a_id)
REFERENCES A (type_code, a_id)
, CHECK (type_code = 'B')
) ;
CREATE TABLE C
( a_id INT NOT NULL
, type_code CHAR(1) NOT NULL DEFAULT 'C'
, PRIMARY KEY (type_code, a_id)
, FOREIGN KEY (type_code, a_id)
REFERENCES A (type_code, a_id)
, CHECK (type_code = 'C')
) ;
如果只有MySQL实现了CHECK
约束,上面的工作正常。但事实并非如此。因此,为了确保所有规范都得到强制执行,并且'B'
表中没有插入C
类型数据,您必须再添加2个“类型”表(并删除无用的表) MySQL CHECK
约束):
CREATE TABLE TypeB
( type_code CHAR(1) NOT NULL
, PRIMARY KEY (type_code)
) ;
CREATE TABLE TypeC
( type_code CHAR(1) NOT NULL
, PRIMARY KEY (type_code)
) ;
每个只有1行:
INSERT INTO TypeB (type_code)
VALUES ('B') ;
INSERT INTO TypeC (type_code)
VALUES ('C') ;
和其他FK:
ALTER TABLE B
ADD FOREIGN KEY (type_code)
REFERENCES TypeB (type_code) ;
ALTER TABLE C
ADD FOREIGN KEY (type_code)
REFERENCES TypeC (type_code) ;
使用这些约束,表A的每一行都将是B或C类型,它们将位于相应的表(B或C)中,而不会同时存在于两个表中。
如果您还想确保它们只在一个表中(并且从不在B和C中),那么在插入A时应该小心(所有插入都应该通过强制执行该要求的事务来完成)