查询不需要约束(包括候选键、外键和基数)。它们反映了对基表和查询结果的可能值的限制。我们将约束告诉 DBMS,这样它就不会出现不可能的情况。外键不会出于查询目的“连接”表;任何两个表都可以有意义地连接。
假设每个订单和组都有一个公司,并且 ORDER 和 GROUP (ids) 是唯一的,那么简单的设计是:
Company -- company COMPANY has name NAME ...
PRIMARY KEY (COMPANY)
Order -- company COMPANY's order ORDER is for amount AMOUNT ...
PRIMARY KEY (ORDER)
FOREIGN KEY (COMPANY) REFERENCES Company (COMPANY)
OrderGroup -- company COMPANY's order group GROUP has description DESCRIPTION ...
PRIMARY KEY (GROUP)
FOREIGN KEY (COMPANY) REFERENCES Company (COMPANY)
Contains -- order group GROUP contains order ORDER
PRIMARY KEY (GROUP, ORDER)
FOREIGN KEY (GROUP) REFERENCES Company (GROUP)
FOREIGN KEY (ORDER) REFERENCES Order (ORDER)
关系外键约束表示表中子行中的值列表必须作为候选键的表子行中的值列表出现在其他地方。 (一个 SQL FOREIGN KEY 约束 REFERENCES 一个超键:UNIQUE NOT NULL 或 PRIMARY KEY。)
在该设计中,当一个组包含一个订单时,我们不能以声明方式将组和订单限制为拥有一个共同的公司。但是,如果我们改为使用为组和订单提及该共同公司的设计,那么我们可以声明性地约束:
Contains -- for company COMPANY order group GROUP contains order ORDER
FOREIGN KEY (COMPANY, GROUP) REFERENCES OrderGroup (COMPANY, GROUP)
FOREIGN KEY (COMPANY, ORDER) REFERENCES Order (COMPANY, ORDER)
-- add to Orders
UNIQUE NOT NULL (COMPANY, ORDER)
-- add to OrderGroup
UNIQUE NOT NULL (COMPANY, GROUP)
(这是 SQL 的一个怪癖,您必须将引用的列列表声明为 UNIQUE/PK,即使每个列表都包含一个较小的声明的 UNIQUE/PK 列列表,这意味着包含列表必须也是唯一/PK。)
PS 以上是在您编辑每个订单的一组上限之前编写的。如果一个订单最多可以出现在一个组中,则包含 PK (ORDER)。由于一个订单最多只能出现一次,因此它只能出现在一个组中。 (或者你可以有一个设计,你删除包含并将 NULLable GROUP 添加到 Order 中,并将 FK(COMPANY,GROUP)添加到 Group。)