如何在不破坏范式的情况下为多对多关系构建连接表

Posted

技术标签:

【中文标题】如何在不破坏范式的情况下为多对多关系构建连接表【英文标题】:How to construct a Junction Table for Many-to-Many relationship without breaking Normal Form 【发布时间】:2013-12-22 22:13:07 【问题描述】:

我有这两张表,Company 和 Owner。 现在它们都处于正常形式,但我需要在它们之间创建Many-to-Many 关系,因为一个公司可以有很多所有者并且一个所有者可以有很多公司 .

我之前得到了一个答案,即向公司添加一组 CompanyOwners(带有所有者 UUID)是否会破坏正常形式 It will break Normal Form,并且已经能够收集到可以使用的是 Junction Table,请参阅thread.

我的问题如下:如下所示创建一个额外的连接表会破坏正常形式吗?

-- This is the junction table.
CREATE TABLE CompanyOwners(
    Connection-ID UUID NOT NULL, // Just the ID (PK) of the relationship.
    Company-ID UUID NOT NULL REFERENCES Company (Company-ID),
    Owner-ID UUID NOT NULL REFERENCES Owner (Owner-ID),
    CONSTRAINT "CompanyOwners" PRIMARY KEY ("Connection-ID")
)

【问题讨论】:

看准了,别担心,继续吧:) 没有特定的“范式”。标准化有很多级别:en.wikipedia.org/wiki/Database_normalization#Normal_forms。过多的标准化可能与过少的标准化一样糟糕,如果不是更糟的话。您所做的完全正确,尤其是包含表的主键。 【参考方案1】:

您的结构允许重复数据。例如,它允许这样的数据。 (UUID 被缩写以防止水平滚动。)

Connection_id            Company_id               Owner_id
--
b56f5dc4...af5762ad2f86  4d34cd58...a4a529eefd65  3737dd70...a359346a13b3
0778038c...ad9525bd6099  4d34cd58...a4a529eefd65  3737dd70...a359346a13b3
8632c51e...1876f6d2ebd7  4d34cd58...a4a529eefd65  3737dd70...a359346a13b3

关系中的每一行都应该有不同的含义。该表允许数百万行具有相同含义。

按照这些思路做的更好。它在 5NF 中。

CREATE TABLE CompanyOwners(
    Company_ID UUID NOT NULL references Company (Company_ID),
    Owner_ID UUID NOT NULL references Owner (Owner_ID),
    PRIMARY KEY (Company_ID, Owner_ID)
);

标准 SQL 不允许在标识符中使用“-”。

【讨论】:

我知道一个所有者不能拥有一个单一的公司两次,我认为这是您所指的重复事件。但它并没有破坏范式,这是我主要关心的问题。关于禁止“-”的信息非常有用,非常感谢。你知道新版本的 PostgreSQL 9.x 是否允许比标准 SQL 更多的符号? Mike,非常感谢您对添加的重复 UUID 示例的澄清。我现在了解您在说什么,并将更改设计以纳入您的建议。非常感谢。 ;)【参考方案2】:

这很好,但您可以添加更多列,例如

DateOwned Datetime  --<-- when the owner bought the company 
DateSold Datetime  --<-- when a the owner sold the compnay

毕竟,您想知道公司是否仍归同一所有者所有,并跟踪公司的所有权历史等。

【讨论】:

以上是关于如何在不破坏范式的情况下为多对多关系构建连接表的主要内容,如果未能解决你的问题,请参考以下文章

实体框架将纯连接查找表转换为多对多关系

将表拆分为多对多关系:数据迁移

如何在 Rails 4.2 中为多对多关联创建表单

如何在不更新具有多对多关系的子实体的情况下保留父实体?

多对多关系如何运作。

学说2:在多对多关系中引用连接表