我刚刚开始学习数据库设计,我正在使用Oracle 11G和SQL Developer。
我有一个DB的这3个业务规则:
。 。
到目前为止,非常好,我想出了五个表( INS_COY,OFFR,INS_TYPE,PROVIDE和SUBSCRIBE )。 PROVIDE和SUBSCRIBE作为复合表出现,因为INS_COY和INS_TYPE之间的关系,以及OFFR和INS_TYPE都是M:M关系。
每个表的PK和FK属性如下:
INS_COY TABLE
coy_id - PK
OFFR TABLE
offr_id - PK
coy_id - (FK引用INS_COY.coy_id))
INS_TYPE TABLE
type_id - PK
提供
coy_id 和 type_id - (复合PK)
coy_id - (FK引用COY.coy_id)
type_id - (FK引用ins_type.type_id)
SUBSCRIBE
naf_no 和 type_id - (复合PK)
naf_no - (FK引用offr.offr_id)
type_id (FK引用ins_type.type_id)
。
。
。
表已成功创建,并插入了样本数据。
所以,问题是 - 在SUBSCRIBE TABLE上,我如何确保TYPE_ID附加到OFFR_ID的完整性是由他所引入的COY提供的INS_TYPE?
即...来自表格,“offr 4250”在“coy 1”中注册,“coy 1”不提供“ins_type 13”,但是,因为没有约束来检查这个,“offr 1 “在SUBSCRIBE TABLE上订阅了”ins_type 13“。
答案 0 :(得分:1)
您可以使用受控冗余和复合FK约束来实现:
CREATE TABLE offr (
offr_id INT NOT NULL,
coy_id INT NOT NULL,
PRIMARY KEY (offr_id),
FOREIGN KEY (coy_id) REFERENCES ins_coy (coy_id),
UNIQUE KEY (offr_id, coy_id)
);
我添加了一个复合唯一键(offr_id,coy_id)来支持subscribe
表上的复合FK约束。
CREATE TABLE provide (
coy_id INT NOT NULL,
type_id INT NOT NULL,
PRIMARY KEY (coy_id, type_id),
FOREIGN KEY (coy_id) REFERENCES ins_coy (coy_id)
);
此处的复合主键非常适合subscribe
表上的复合FK约束。
CREATE TABLE subscribe (
naf_no INT NOT NULL,
coy_id INT NOT NULL,
type_id INT NOT NULL,
PRIMARY KEY (naf_no, type_id),
FOREIGN KEY (naf_no, coy_id) REFERENCES offr (offr_id, coy_id),
FOREIGN KEY (coy_id, type_id) REFERENCES provide (coy_id, type_id)
);
重叠的复合FK约束将确保官员只能订阅他/她注册的公司提供的保险。coy_id
在逻辑上是多余的,但是要求完整性,并且不存在更新异常的风险。 FK约束。
或者,您可以使用触发器通过内部联接检查值是否相关:
CREATE TRIGGER check_subscribe BEFORE INSERT OR UPDATE ON subscribe
FOR EACH ROW
WHEN NOT EXISTS (
SELECT 1
FROM offr
INNER JOIN provide ON offr.coy_id = provide.coy_id
WHERE offr.offr_id = new.naf_no AND provide.type_id = new.type_id
)
RAISE_APPLICATION_ERROR (num => -20000, msg => 'Officers can only subscribe to types provided by their company');
免责声明:我无法在SqlFiddle上测试这个并且没有安装Oracle,但希望它能指向正确的方向。