我有一个包含某种items
的表格,以及这些项目所属的两个表格(a
和b
)。
一个项目指的是a
中的 中的一行或b
中的一行。一个a
或b
可以包含多个项目。
是否有比以下更好的设计(使用Oracle 10)?
需要注意的任何陷阱?
id a_id(fk) b_id(fk)
1 1 NULL
2 1 NULL
3 NULL 1
4 2 NULL
答案 0 :(得分:4)
在许多方面,这是一个非常好的设计:
唯一的障碍是这个数据库结构本身不会检查项目是否只链接到A或B中的一个(而不是两者)。检查Items表上的约束将完成此任务。
伪代码示例:
CONSTRAINT a_eor_b CHECK
(
NOT (a_id IS NULL AND b_id IS NULL)
AND NOT (a_id IS NOT NULL AND b_id IS NOT NULL)
)
答案 1 :(得分:2)
我建议添加一个检查约束,该约束强制执行至少(或可能确切地)其中一个id字段为空。
值nvl(a_id,b_id)的基于视图和/或函数的索引也可能有用。使用Oracle11,您可以使用虚拟列。
答案 2 :(得分:0)
A
和B
是更一般类型的不相交的子类型。
我们称之为refs
:
CREATE TABLE refs (type CHAR(1) NOT NULL, id INT NOT NULL, PRIMARY KEY (type, id), CHECK (type IN ('A', 'B')))
CREATE TABLE a (type CHAR(1) NOT NULL, id INT NOT NULL PRIMARY KEY, FOREIGN KEY (type, id) REFERENCES refs (type, id) ON DELETE CASCADE, CHECK (type = 'A'))
CREATE TABLE b (type CHAR(1) NOT NULL, id INT NOT NULL PRIMARY KEY, FOREIGN KEY (type, id) REFERENCES refs (type, id) ON DELETE CASCADE, CHECK (type = 'B'))
CREATE TABLE items (id INT NOT NULL, type CHAR(1) NOT NULL, ref INT NOT NULL, FOREIGN KEY (type, id) REFERENCES refs)
使用此设计,您不应直接从A
或B
删除:请从父表refs
中删除。
答案 3 :(得分:0)
参考Mapping Inheritance Structures,其中提到了4种技术,
并查看专业人员的“2.6比较策略”缺点