如果不想改变表结构,看另外两个答案。
不过,更好的处理方法是创建一个包含可能组合的表格。示例(可以更好地选择名称):
CREATE TABLE contact_cat(
id INT NOT NULL,
desc NOT NULL VARCHAR(128),
CONSTRAINT PK_contact_cat PRIMARY KEY(id)
);
CREATE TABLE contact_sub(
id INT NOT NULL,
desc NOT NULL VARCHAR(128),
CONSTRAINT PK_contact_sub PRIMARY KEY(id)
);
CREATE TABLE contact_style(
cat_id INT NOT NULL,
sub_id INT NOT NULL,
CONSTRAINT PK_contact_style PRIMARY KEY(cat_id,sub_id),
CONSTRAINT FK_contact_style_contact_cat FOREIGN KEY(cat_id) REFERENCES contact_cat(id),
CONSTRAINT FK_contact_style_contact_sub FOREIGN KEY(sub_id) REFERENCES contact_sub(id)
);
CREATE TABLE tester(
cat_id INT NOT NULL,
sub_id INT NOT NULL,
information VARCHAR(128) NOT NULL,
CONSTRAINT FK_tester_contact_style FOREIGN KEY(cat_id,sub_id) REFERENCES contact_style(cat_id,sub_id)
);
用 cat + sub 填充表格,然后在contact_style 中允许组合:
INSERT INTO contact_cat(id,desc)VALUES(1,'Address');
INSERT INTO contact_cat(id,desc)VALUES(2,'Phone');
INSERT INTO contact_sub(id,desc)VALUES(1,'Primary');
INSERT INTO contact_sub(id,desc)VALUES(2,'Leisure');
INSERT INTO contact_style(cat_id,sub_id)VALUES(1,1); -- Address + Primary
INSERT INTO contact_style(cat_id,sub_id)VALUES(2,2); -- Phone + Leisure
向tester添加信息:
INSERT INTO tester(cat_id,sub_id,information)VALUES(1,1,'NY, 120 Boulevard Av'); -- succeeds
INSERT INTO tester(cat_id,sub_id,information)VALUES(2,2,'555 77 88 99'); -- succeeds
INSERT INTO tester(cat_id,sub_id,information)VALUES(1,2,'Blablabla'); -- fails
INSERT INTO tester(cat_id,sub_id,information)VALUES(2,1,'More blah'); -- fails
前两个语句成功,因为外键存在于contact_style 中允许的联系人样式中。最后两个失败是因为contact_style 中不存在外键。
这种工作方式的好处:
- 无需每次都重复联系人类别+子类别描述。
- 当这些表缓存在内存中时,可以节省磁盘空间和内存;表尽可能缓存在 SQL Server 中,以加快查询响应速度。
- 当需要新类别或子类别时,您不必重写任何约束(参见其他答案)。只需在适当的表中添加新猫/子猫的行,将行添加到
contact_style 以反映新的组合并快速完成。