何时在数据库中使用1对1表

时间:2010-11-08 17:46:18

标签: mysql database-design

让我首先说我不是数据库专家。我正在研究其他人编写的一些代码,我注意到表之间有很多1-1关系。这是一个例子:

tblPropertyRecord
   pID
   hasPhotos
   hasVideo
   comment
   headline

tblPropertyLocation
   ID
   pID
   country
   region
   city
   zip
   street_address

tblPropertyOther
   ID
   pID
   upload_path
   isApproved
   isPaid

这并不包含属性的每个字段 - 每个记录总共有大约35个字段,但是每个表都有,并且每个记录只能有一个条目1到1到1 ...我猜是描述它的方式?

这有什么好处而不仅仅是拥有35个字段的tblPropertyRecord?我理解许多人的观点是1,1对1,多对多......但这似乎更加混乱而没有真正的好处。

8 个答案:

答案 0 :(得分:5)

表可能是1-1但是关系实际上可能是1到0..1 - 他们可能正在使用额外的表来避免填充非常稀疏的表。

答案 1 :(得分:3)

一个常见的情况是由于遗留数据库支持(即您正在扩展到现有lecacy数据库的数据存储,您不希望通过添加新列来冒险破坏现有功能)。

如果这是绿地,并且如果您100%确定相关字段将始终是一对一,那么(通常)没有理由不将它们包含在同一个表中。我希望有一些边缘情况,如数据分区,或优化特定页面大小的记录等。

答案 2 :(得分:2)

来自Hibernate documentation on this subject

的快速报价
  

有三种情况   一对一协会:要么是   关联实体共享相同的内容   主键值,外键是   其中一个实体持有(注意到   数据库中的这个FK列应该   被限制为模拟独特   一对一的多样性),或a   关联表用于存储   两个实体之间的联系(一个独特的   必须在每个上定义约束   fk确保一对一   复数)。

如果上述情况不符合您的情况,那么您应该考虑重构。

修改评论后的说明

  1. 如果两个实体共享相同的PK,那么它们实际上是一个实体(1:1)
  2. 如果两个实体中的一个具有唯一 FK到另一个实体,则它们实际上是一个实体,但具有存在选项(1:0..1) - 可选的额外属性
  3. 如果关联表中唯一 FK进入两个实体中的每一个,那么它们实际上是一个实体,但具有双向存在选项(0..1:0..1) - 可选的2组属性组合
  4. 希望清除引用的略微抽象的语言。

答案 3 :(得分:1)

通常来说,当我有一组在某些情况下可能为NULL的属性时,我会将这些属性分解为多个表。如果这是分离这些信息的合理解释,那么很难从您发布的模式中判断出来。

tblPropertyRecord是所有这些关系中的父表吗?如果是这样,是否有用户可以为新属性创建记录而不填写其他表中包含的部分信息的情况?

或者,您的网站是否允许用户在一个页面上输入一些数据,然后再继续执行另一个步骤并输入更多信息?如果是这种情况,那么原始设计师可能会在用户进展时保存信息。

无论如何,我要说如果这两个条件都不成立,那么就没有一个真正有理由将数据分成多个表格。

编辑:我看到您对该网站的评论总是输入所有字段,因此您可以安全地假设此数据应位于单个表格中。

答案 4 :(得分:1)

我认为很清楚,鉴于您的答案中的信息,并且没有Nullable列,所有五个表都应该归入一个表。然而,这听起来并不合理(35个“字段”几乎是一个读取标志,你有一个平面文件,而不是标准化)。你可以彻底检查真实数据,所有用例。

为应用程序要求设计数据库不是设计这么差的可接受原因。如果该列与PK为1 :: 1,那么必须在表中。而不是,如果不是。

将某些列拆分为单独的1 :: 1表的唯一合法理由是:

  • 可以为Nullable列(可选或缺少值)

  • 因此,该列与PK为1 :: 0-1。

    (商业DBMS自动将[所有] BOLB放置在不同的设备上,并允许设备管理;对于城镇的免费软件,当然您必须自己进行所有那种基本的物理验证。)

    (城镇的小端也不能处理大行,所以这是另一种在这种情况下合法的商业非法原因。)

然后,您可以在其中一列上支持唯一索引:

CREATE TABLE Part (
    PartId,
    Description,
    EtCetera                   -- Optional SerialNo here cannot be made Unique
    )
CREATE UNIQUE CLUSTERED INDEX UC_PartId
    ON Part (PartId)
CREATE TABLE PartSerial ( PartId, SerialNo, EtCetera ) CREATE UNIQUE NONCLUSTERED INDEX UC_PartId ON PartSerial (PartId) CREATE UNIQUE CLUSTERED INDEX U_SerialNo ON PartSerial (SerialNo) -- SerialNo can now be Unique ALTER TABLE PartSerial ADD CONSTRAINT FOREIGN KEY (PartId) REFERENCES Part (PartId)

这四张桌子还有另一个错误。 ID列(和唯一索引)完全冗余。 pID既是主键,也是tblPropertyRecord的外键。

答案 5 :(得分:0)

1-1表格也是建模继承时的一种方法。从你的例子中的表名来看,情况似乎并非如此。

How do you effectively model inheritance in a database?

答案 6 :(得分:0)

我们有时会根据模块化功能实现1到1个表。例如,假设我们有一个跨模块使用的Person对象。现在,某些模块可能需要为该Person提供其他属性。像邮政地址或电话号码,而其他人没有。

这是表“继承”的一种形式,因为我们可以扩展Person的功能而不会影响以前的代码。对我们来说,这意味着这种关系是一对一或零。

我能想到分离出这样的字段的另一个原因是表格是否很大并且大多数字段都没有在查询中使用。例如,如果几乎所有的查询都只关注主表,那么可以想象整个表在ram中缓存以获得更快的响应。或者,如果数据大小有问题,您可以将子表分区到不同的驱动器上。

但是,如果您的大量查询将这些表连接在一起,那么我认为这绝对是浪费。

答案 7 :(得分:0)

任何数据库管理方案中的第一件事:了解您的数据

如果您了解自己的数据,并且知道自己永远不需要多个大表。不要因为它看起来不正确或没有那种标准化的感觉而变得更复杂。

了解您的数据并采取适当的行动。