为与 SQL Server 的 1 到 (0..1) 关系设计 1 或 2 个表

Posted

技术标签:

【中文标题】为与 SQL Server 的 1 到 (0..1) 关系设计 1 或 2 个表【英文标题】:Design 1 or 2 tables for a 1 to (0..1) relationship with SQL Server 【发布时间】:2012-08-23 20:17:41 【问题描述】:

我已经阅读了几篇关于 SO 的关于创建一对一关系的帖子:

how do i create a real one-to-one relationship in sql server

is there ever a time where using a database 11 relationship makes sense?

Database design 1 to 1 relationship

但我很乐意听取您对这个基本案例的建议:我有一个 USER 和一个 COMPANY 表。每个 USER 可以有 0 或 1 个 COMPANY。

使用以下关系的两个表是否更好:

或者我是否只需要使用一个包含所有所需字段的表格:

感谢您的解释。

注意:我正在使用 SQL Server(使用 Manager Studio 进行设置)并计划使用 EF。

更新:为了更明确,我想要实现的是以下内容: 用户可以拥有或不拥有公司。如果他拥有一家公司,那么他是唯一为该公司工作的人。

谢谢

【问题讨论】:

这里有几个问题。用户可以随着时间改变公司吗?如果可以,了解该用户工作的公司对您来说很重要吗?公司可以改名吗?无论如何,您的第一个设计并没有真正意义,因为桌子上没有CO_ID USER 供您创建关系 嗨 Lamak,请查看我的更新。感谢您的建议 【参考方案1】:

由于用户可能拥有一家公司,因此这不是真正的“一对一”关系。

其实这是“1 到 0..1”,你可以通过以下两种方式之一进行建模:

    把所有东西都放在一张桌子上:

    注意 COMPANY_ID 如何既是 UNIQUE(防止多个用户拥有同一家公司)又可以为 NULL(允许不拥有公司的用户)。 USER_ID 和 COMPANY_ID 的分离是允许公司级外键的原因(即允许子表引用公司,同时防止它们引用无公司用户)。

    如果没有公司级 FK,您可以完全省略 COMPANY_ID。

    您还需要一个 CHECK 以确保不能设置其他公司字段,除非设置了 COMPANY_ID(或至少公司字段的正确子集不为空)。

    有两张桌子:

    我们不能只让这两个表的 PK 也是 FK(双向),因为 MS SQL Server 不支持在插入新数据时解决先有鸡还是先有蛋的问题所需的延迟约束,也不会正确建模“1 到 0..1”关系(它会建模“1 到 1”并且不允许无公司的用户)。

您应该选择这两种策略中的哪一种,很大程度上取决于与用户相比的公司数量:

如果大多数用户拥有一家公司,请选择 (1)。 如果用户多于公司,请选择 (2)。

【讨论】:

【参考方案2】:

这对我来说实际上听起来像是多对多的关系:

多个用户可以为一个公司工作 一个用户可以为多家公司工作

也许你不想考虑后一种情况,但我不会受伤。在这种情况下,您将拥有一个 user 表、一个 user_company 表(n 到 n 映射)和一个 company 表。如果要将用户限制为一家公司,请将 user_company 表中的 user_id 列设为唯一。

希望对您有所帮助。

【讨论】:

【参考方案3】:

这取决于您将拥有哪些其他数据。如果这是唯一使用公司的地方,那么就在一张桌子上找它。如果公司在其他几个表中使用,那么您希望它是一个单独的表。

【讨论】:

【参考方案4】:

您的第一个选项是最好的。

索引...性能... 如果用户不是公司... 如果您想查询用户 不带回公司... ...反之亦然 如果您有其他表需要链接到用户而不是公司... 如果您希望能够以不同的方式保护表 (也许您的采购部门需要对公司进行 SELECT 访问, 但不是用户;您的人力资源部门需要访问用户,但不需要 公司)...

有一百万个理由......但这里有 5 或 6 个需要考虑/让你开始。

【讨论】:

【参考方案5】:

嗯嗯 如果您不太可能要求每个用户拥有一家以上的公司,并且大部分用户将拥有一家公司并且没有那么多领域来描述一家公司,那么我会保持简单并使用一张表。以后随时可以改变主意。

如果您想要更多的范围 1 到多个,那么您将 userid 放在 company 或 companyid 放在 user 中,您所拥有的选项 1 将不起作用,并且还会导致令人难以置信的混乱代码。

Select Company From Companies Where CompanyID = @UserID;// huh eh? What!!

正如其他人所说,如果您想要更大的范围以便可以进行多对多操作,则需要包含 CompanyID 和 UserID 的第三张表。

【讨论】:

以上是关于为与 SQL Server 的 1 到 (0..1) 关系设计 1 或 2 个表的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 到 PL/SQL

SQL Server 兼容级别

SQL Server 索引命名约定 [关闭]

哪个为与 Qlikview 的连接提供更好的性能?SQL 服务器或 SSAS Cube?

Kettle4SQL SERVER到SQL SERVER数据转换抽取实例

如何在 SQL Server 上将 LinkServer 添加到 MySQL