使用一对一的表关系有啥好处? (MySQL)

Posted

技术标签:

【中文标题】使用一对一的表关系有啥好处? (MySQL)【英文标题】:What are advantages of using a one-to-one table relationship? (MySQL)使用一对一的表关系有什么好处? (MySQL) 【发布时间】:2011-02-01 01:56:24 【问题描述】:

与简单地将所有数据存储在一个表中相比,使用一对一的表关系有哪些优势?我理解并一直在使用一对多、多对一和多对多,但实现一对一关系似乎是一项乏味且不必要的任务,尤其是如果您使用命名将 (php) 对象关联到数据库表的约定。

我在网上或这个网站上找不到任何可以提供一对一关系的真实示例的内容。起初,我认为将“用户”分成两个表可能是合乎逻辑的,一个包含个人资料页面的“关于我”之类的公共信息,另一个包含登录/密码等私人信息。但是为什么要去当您可以选择从该表中选择哪些字段时,通过使用不必要的 JOINS 的所有麻烦?如果我要显示用户的个人资料页面,显然我只会选择 id、用户名、电子邮件、aboutme 等,而不是包含他们私人信息的字段。

有人愿意用一对一关系的真实例子来启发我吗?

【问题讨论】:

【参考方案1】:

一种可能的用途是当部分信息是可选的。这样你就不需要在一个大表中有一堆可以为空的字段,而是可以在逻辑上将它分成必填表和可选表。

其他用途是当某些数据与不同的表共享时。例如,假设您有一个销售计算机零件的网站。您可以将所有组件共享的详细信息放入例如。 “parts”表,但将细节放在“motherboards”、“cpus”等中,这将只使用具有一对一关系的parts表。

【讨论】:

【参考方案2】:

我已经使用一对一的关系来扩展现有应用程序中的某些功能,而不会影响应用程序数据库结构。这是扩展现有数据库表的一种不显眼的方式。

使用一对一关系的另一个原因是为了实现类表继承,其中层次结构中的每个类都有一个表,并且一个对象在他的表类中有对应的行,在他的父类表中,在他的祖父母类表中等等。

例如,参见《教义 2》Class Table Inheritance Page

【讨论】:

-1 表示在关系数据库中使用装饰器模式是个好主意。 是的,我的意思是在 byronh 给出的意义上扩展。但是,我并没有说这是“一个好主意”,我只是说这可能是一个原因。一件事情好与不好也取决于上下文。有时我不想要也无法更改第三方数据库,因此我以一对一的关系“扩展”该表 是的,还请注意,在大(数千万行)表上添加一列的 ALTER TABLE 可能需要很多时间(小时)。与此同时,桌子被锁定,系统管理员可能在夜里醒来......【参考方案3】:

这里有两个,我相信其他人会发布更多

您希望在不实际修改表的情况下扩展现有表。也许它是由第三方供应商提供的,而您希望通过简单地使用第二个共享相同键的表来分隔您的扩展。 可能在表中有固定宽度的列经常被访问,而可变的列则不是。在这种情况下,使用具有固定行长的表来存储经常出现的内容,而使用辅助表来存储其他所有内容,可能会提高效率。

此外,在规范化数据库时,对 3rd Normal Form (3NF) 说,您可能会发现有些列并不是真正“关于”键,需要将其拉出到单独的表中。

【讨论】:

【参考方案4】:

专门针对您的示例: 您不希望将姓名和地址等用户信息与登录名和密码信息存储在同一个表中,因为这样您可以授予组织中的某个人对用户信息表而不是登录数据表的权限。我不同意其他人关于“一张表有太多字段”的主题。如果有很多字段,而您的表单或报表中不需要它们,您可以使用 sql 只选择您需要的字段,甚至使用视图来确保您不会获得太多数据。

【讨论】:

您还可以授予对特定列而不是整个表的访问权限。但是表格(不仅仅是单元格)会受到性能影响。如果不选择所有字段,表空间仍然需要加载到内存中;这对视图没有什么不同。此规则的唯一例外是可以直接从键索引中检索请求的数据。【参考方案5】:

最常见的原因是这种关系可能是非强制性的。即,有一组属性适用于每个基本实体,但有些属性仅适用于子集。

这样做的另一个正当理由是控制访问权限 - 您可能有一个在整个应用程序中使用的客户表,虽然每个客户都有密码和信用卡,但您可能希望限制可见性/更新权限。

Marga Keuvelaar 对 Ignacio Vazquez-Abrams 答案的评论是错误的。您可以使用更好的 DML/DDL 来减轻影响,但并非在所有情况下都如此。但是,您需要在数据模型的透明度与性能优势之间进行权衡 - 这始终需要仔细考虑。

C.

【讨论】:

此答案中提到的评论现已消失。【参考方案6】:

数据库引擎可能必须将整行加载到内存中才能从中提取数据,即使只读取字段的子集也是如此。每行更少的字段意味着每页有更多的行,这意味着更少的磁盘访问。

【讨论】:

如果您使用合适的数据库引擎,并且明智地编写 sql 和索引,则不应该是这种情况。 如果你使用 mysql (MyISAM/InnoDB),除了 key-only SELECT 之外的任何东西都会影响性能。表空间越大,获取请求数据所需的内存就越多。 UPDATE 性能也受到很大影响。【参考方案7】:

在 OO 中你有继承。因此,您可以拥有一个包含父对象数据的表,以及包含特定于子对象的字段的其他表。

【讨论】:

【参考方案8】:

当我们需要用too many fields(96 个字段!)扩展我们的一张表时,我们使用了“一对一关系”;因此,我们创建了另一个表并将每个新字段都放入其中。

无论如何,我喜欢的一种方法是:

Table_Base:
    ID
    MANDATORY_FIELD
Table_Option:
    ID
    OPTIONAL_FIELD

【讨论】:

【参考方案9】:

除了已经说过的,

某些列的“安全许可”要求可能与其他列不同。例如。员工的名字可能比他的薪水“更公开一些”。现在,DBMS 通常不强制执行列级安全性,但通常会强制执行表级安全性。

因此,通过在单独的表中单独列出工资,您可以为自己购买仅使用 DBMS 的安全设施来实现用户安全要求的可能性。

【讨论】:

【参考方案10】:

根据我的经验,还有一件事没有被提及:

分成两个表也有助于创建模型类。假设您有 Customers 表和 DriverLicense 表以及它们之间的一对一关系。如果您使用实体框架,我敢打赌如果您有两个单独的表应该会更好,因为您的应用程序中可能有两个模型类,客户类和 DriverLicense。通过这种方式,实体框架可以很容易地在以后向现有客户添加新的驾驶执照信息,或者删除和更新它。简而言之,考虑到 Web 开发方面,我相信如果它们是两个不同的实体,即使它们是一对一的关系,它们也应该有自己的表。

【讨论】:

以上是关于使用一对一的表关系有啥好处? (MySQL)的主要内容,如果未能解决你的问题,请参考以下文章

使用实体框架 4.1 代码优先方法将一对一的表关系映射到单个实体

创建一对一关系的表

多表继承模型和相同两个模型之间的简单一对一关系有啥区别?

python开发mysql:表关系&单表简单查询

在mysql中如何查看各表之间的关系图

给出一对五和多对一的关系有啥问题。为啥会发生这个错误