使用传递关系规范化模式

时间:2016-02-22 12:19:44

标签: database-design relational-database database-normalization

我需要创建三个这样的模型:

Company
* name ...

Order
* amount ...

OrderGroup
* description ...

即使订单不属于任何集团,订单也始终属于公司。即使没有订单,集团也始终属于公司。

  • 订单属于0或1组。
  • 一个组由0到n个订单组成。
  • 集团属于公司,因此集团的所有订单也必须属于同一公司。

如何为此创建架构?

如果我只是添加company_id和group_id添加到订单,数据库不知道它们已连接,我的应用程序可能会引入不一致:

Order 1, company1, group1
Order 2, company2, group1 #should not be possible

如果我将company_id添加到Group而不是Order,那么订单中的订单不属于任何组:

Order 1, Group=null #don't know the company

我可能必须将这两个连接的字段提取到一个单独的表中,但我不确定它应该具有哪些约束。

1 个答案:

答案 0 :(得分:1)

查询不需要约束(包括候选键,外键和基数)。它们反映了对基表和查询结果的可能值的限制。我们告诉DBMS有关约束,以便它不允许不可能的情况。外键不会“连接”表以进行查询;任何两个表都可以有意义地加入。

假设每个订单和组都有一个公司,并且ORDER和GROUP(ID)是独一无二的,那么直截了当的设计是:

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约束引用超级键: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列列表,这意味着包含列表必须也是UNIQUE / PK。)

PS以上是在您编辑每个订单的一个组的上限之前编写的。如果订单最多只能出现在一个组中,则包含PK(ORDER)。由于订单最多只能出现一次,因此它只能出现在一个组中。 (或者你可以有一个设计,你放弃包含并将NULLable GROUP添加到订单,FK(COMPANY,GROUP)到Group。)