【问题标题】:Is there ever a time where using a database 1:1 relationship makes sense?是否曾经有过使用数据库 1:1 关系有意义的时候?
【发布时间】:2010-10-05 18:27:15
【问题描述】:

前几天我在考虑规范化,突然想到,我想不出数据库中应该存在 1:1 关系的时间。

  • Name:SSN?我会把它们放在同一张桌子上。
  • PersonID:AddressID?同样,同一张桌子。

我可以想出无数个 1:many 或 many:many 的例子(带有适当的中间表),但从来没有 1:1。

我是否遗漏了一些明显的东西?

【问题讨论】:

  • 这样分离的数据库更容易拆分成多个物理设备。
  • 还有一个后续问题,如果它确实有意义,如何做到这一点?考虑了herehere——我的问题是如何选择两个表中的哪一个具有外键约束?我想这取决于您要解决的用例...

标签: sql database-design one-to-one database-normalization


【解决方案1】:

一个原因是数据库效率。拥有 1:1 的关系允许您拆分在行/表锁定期间将受到影响的字段。如果表 A 有大量更新,而表 b 有大量读取(或来自另一个应用程序的大量更新),则表 A 的锁定不会影响表 B 中发生的事情。

其他人提出了一个很好的观点。取决于应用程序等如何影响系统,安全性也可能是一个很好的理由。我倾向于采用不同的方法,但这可能是一种限制对某些数据的访问的简单方法。在紧要关头拒绝访问某个表真的很容易。

My blog entry about it.

【讨论】:

    【解决方案2】:

    就纯科学而言,是的,它们毫无用处。

    在实际数据库中,有时将很少使用的字段保留在单独的表中很有用:加快使用此字段且仅使用此字段的查询;避免锁等。

    【讨论】:

    • @Mark Brady:不,它没有,因为有 Na2SO4 和 KCl。制作 Universe 数据库时,应创建 t_atom (id INT, protons INT, neutrons INT)、t_molecule (id INT, atom_id INT) 并进行连接。这是一对多的关系。
    • 再想一想,INT 在这里可能不够用,因为宇宙中有 10^78 个原子。即使是两个粘合在一起的 GUID 也只能容纳 1/10 的原子。我们需要一个 RAW(40) 主键——以防我们的数据库增长过快。暗物质,你知道的。
    • 哦,所以只有关系理论才是纯科学。没有意识到化学不是一门纯粹的科学,除非我们为它建立一个数据库。
    • @Mark Brady:你能不能说一下你不同意什么?我不明白你的讽刺,真的:)
    • Quassnoi(和 Mark Brady)你刚刚给我的 LOL 获得了支持。
    【解决方案3】:

    如果您将数据与流行的 ORM 之一一起使用,您可能希望将一个表分解为多个表以匹配您的对象层次结构。

    【讨论】:

    • 伤心,伤心的理由。如果一个 ORM 不能处理对象模型和物理存储之间的分歧,那么......只是悲伤。
    • 其实,如果我理解正确的话,这意味着在关系数据库中实现分类层次结构。这是 1:1 关系的完全合法和自然的情况;没有什么“悲伤”的。
    【解决方案4】:

    与其使用视图来限制对字段的访问,有时将受限制的字段保存在一个只有特定用户可以访问的单独表中是有意义的。

    【讨论】:

      【解决方案5】:

      1:1 关系通常表明您出于某种原因对较大的实体进行了分区。通常是因为物理模式中的性能原因,但如果预计大量数据同时“未知”(在这种情况下您有 1:0或 1:1,但仅此而已)。

      作为一个逻辑分区的示例:您有关于员工的数据,但需要收集更多的数据,当且仅当他们选择有健康保险时。我会将有关健康保险的人口统计数据保存在不同的表中,以便更轻松地进行安全分区,并避免在与保险无关的查询中拖拽这些数据。

      物理分区的一个示例是托管在多台服务器上的相同数据。我可能会将健康保险人口统计数据保存在另一个州(例如,人力资源办公室所在的地方),并且主数据库可能只能通过链接服务器链接到它......避免将敏感数据复制到其他位置,但使其可用于(假设这里很少)需要它的查询。

      物理分区每当您的查询需要较大实体的一致子集时很有用。

      【讨论】:

      • 一个完美的例子可能是包含文件的表。您可能(出于显而易见的原因)想要一个只包含文件元数据(文件名、mime 类型等)的表和另一个包含实际 blob 数据的 1:1 映射表。在某些情况下,这将减少查询/排序文件的开销。
      • 是的。它取决于数据库(现代设计只是通过使用正确的类型将 blob 存储在文件系统中),即使有这样的支持,也必须小心排除列(在 SQL 中显式列列表是正常的,但一些 ORM 想要拖动整个记录)。诀窍是了解您的使用模式:如果大多数时候忽略实际数据,我将使用 1:1 的 blob 表。如果大多数访问是数据下载,我会使用本机存储机制。
      • @Ochado 虽然我同意你有许多自然发生的(非物理的)1:1 的原因,但“如果你没有历史信息”的空洞使这些情况我可能不会t 使用 1:1 的关系来执行。
      • @Ochado 我确实认为 IS-A 关系是一个很好的例子。我尽量避免在我的表上强制使用面向对象的概念(相反,使用 ORM 作为数据库),但我已经看到了我被诱惑的案例。不过,此类系统的大规模性能扼杀了这些实验。不过,这可能是与性能无关的最佳示例。
      • 实际上,即使存储了历史数据,IS-A 和匹配的预订方案也可能保持 1:1。
      【解决方案6】:

      大多数情况下,它更多的是物理结构而非逻辑结构。它通常用于对表进行垂直分区,以利用跨物理设备拆分 I/O 或与隔离不经常访问的数据或需要比同一对象上的其他属性更安全的数据相关的其他查询优化(SSN、工资等)。

      规定 1-1 关系的唯一合乎逻辑的考虑是某些属性仅适用于某些实体。但是,在大多数情况下,通过实体提取对数据建模有更好/更规范的方法。

      【讨论】:

        【解决方案7】:

        仅在某些情况下需要的扩展信息。在遗留应用程序和编程语言(例如 RPG)中,程序是在表上编译的(因此,如果表发生更改,您必须重新编译程序)。在您必须担心表大小的情况下,标记文件也很有用。

        【讨论】:

          【解决方案8】:

          我发现当我建立一对一关系时,完全是出于系统原因,而不是关系原因。

          例如,我发现将用户的保留方面放在 1 个表中,并将用户的用户可编辑字段放在不同的表中,可以更轻松地在逻辑上编写关于这些字段权限的规则。

          但你是对的,理论上,1:1 的关系完全是人为的,几乎是一种现象。然而从逻辑上讲,它允许程序和优化更容易抽象数据库。

          【讨论】:

          • 现象:是任何具有科学意义的事实或事件,可以进行科学描述和/或解释。我不认为你打算使用这个词。
          • 我确实是想使用它,就其内涵而言,它是一种罕见的东西。通常,现象用于描述异常值,尽管它的定义定义了您非常需要纠正我帖子中的每个单词。
          • @DevelopingChris 我同意 1:1 是一种现象。除了学校理论之外,现实世界中的情况很少。
          【解决方案9】:

          稀疏性。数据关系在技术上可能是 1:1,但不必为每一行都存在相应的行。因此,如果您有 2000 万行,并且某些值仅存在 0.5% 的行,那么如果将这些列推送到可以稀疏填充的表中,则可以节省大量空间。

          【讨论】:

          • "但不必为每一行都存在相应的行" 那不是 1:1。你说的是 1:0,1。
          • 是的。不知道 OP 是否有区别。
          • 好吧,我假设他们这样做了,因为 1:0,1 有很多用途,包括您的用途,但 1:1 的用途要少得多。他们正在努力寻找用途,所以我会说 OP 正在区分。
          • 我的工作假设正好相反,因为他列举了 1:1、1:many 和 many:many 而没有提到 1:0,1。
          【解决方案10】:

          我还可以考虑在 OO 模型中使用继承的情况,并且必须将继承树持久化到数据库中。

          例如,您有一个类 Bird 和 Fish,它们都继承自 Animal。 在您的数据库中,您可以有一个“Animal”表,其中包含 Animal 类的公共字段,Animal 表与 Bird 表具有一对一的关系,与 Fish 具有一对一的关系表。

          在这种情况下,您不必拥有一个包含大量可空列来保存 Bird 和 Fish-properties 的 Animal 表,其中包含 Fish-data 的所有列在记录表示鸟。

          相反,您在 Birds 表中有一条记录,它与 Animal 表中的记录具有一对一的关系。

          【讨论】:

          • 这个答案与另一个问题有关:1 到 0-1 的关系。
          【解决方案11】:

          如果您要进行规范化,则 1:1 关系实际上没有任何意义,因为任何 1:1 的关系都将保存在同一个表中。

          但在现实世界中,它通常是不同的。您可能希望分解数据以匹配您的应用程序界面。

          【讨论】:

          • 我不同意单表理论。有时 SuperType SubType 关系最好用 1:1 关系表示。
          • 实际上,如果您进行极端标准化,那么您将拥有更多的 1:1 关系。 Date 提出的早期规范化形式包括任何列都不应允许 NULL 的规则。这意味着如果一个表的列可能为 NULL,那么它应该在它自己的表中,并且只有在它被赋值时才添加一行。这条规则大部分都被抛弃了,包括 Codd。
          【解决方案12】:

          大多数时候,设计被认为是 1:1,直到有人问“嗯,为什么不能是 1:many”?在预料到这种常见情况时,会过早地将概念彼此分离。 Person 和 Address 没有绑定得那么紧密。很多人有多个地址。等等……

          通常两个独立的对象空间意味着一个或两个可以相乘(x:many)。如果两个对象是真正的,真正的 1:1,甚至在哲学上,那么它更像是一种关系。这两个“对象”实际上是一个完整对象的一部分。

          【讨论】:

            【解决方案13】:

            这也是一种扩展已经在生产中的表的方法,与“真正的”数据库更改相比,风险更小(可感知)。在遗留系统中看到 1:1 的关系通常是一个很好的指标,表明字段是在初始设计之后添加的。

            【讨论】:

            • 为什么模棱两可?您是否认为品牌 spankin 新表与更改现有表的风险一样大。请列出添加新表时出现的问题。我唯一能想到的是对元数据进行操作的代码,即 SELECT * From USER_TABLES loop end loop.
            • 与添加额外字段相​​比,正确添加 1:1 表格通常需要更多的工作。现在,一条新记录意味着更新两个表,而不仅仅是一个。删除记录?还有两个查询。现在我们正在维护更多代码,而不是一次更改。
            • @Mark Brady,在数据库中添加几个文件时,强类型数据集管理起来会很麻烦。如果数据集中的 tableadapter 有很多查询等,那么只需将新表拖入然后就完成了。
            • @Stefan:没有 Cascade 插入。
            • @Boofus,好吧.. 有时我们确实必须使用键盘和编程来赚取收入。 ;)
            【解决方案14】:

            我使用它们主要有几个原因。一是数据变化率的显着差异。我的一些表可能有审计跟踪,我可以在其中跟踪以前版本的记录,如果我只关心跟踪 10 列中的 5 列的以前版本,将这 5 列拆分到一个单独的表中,上面有审计跟踪机制会更有效。另外,我可能有只写的记录(比如会计应用程序)。您不能更改美元金额或它们所用于的帐户,如果您犯了错误,则需要进行相应的记录以注销不正确的记录,然后创建更正条目。我对表有约束,强制执行它们不能更新或删除的事实,但我可能对该对象有几个可延展的属性,这些属性保存在单独的表中,没有修改限制。我这样做的另一次是在医疗记录应用程序中。有与访问相关的数据一旦签署就无法更改,而与访问相关的其他数据可以在签署后更改。在这种情况下,我将拆分数据并在锁定表上放置一个触发器,在签署时拒绝对锁定表的更新,但允许对医生未签署的数据进行更新。

            另一位发帖人评论说 1:1 没有被规范化,在某些情况下我不同意这一点,尤其是子类型化。假设我有一个员工表,主键是他们的 SSN(这是一个例子,让我们把关于这是否是另一个线程的好键的争论)。员工可以是不同的类型,比如临时的或永久的,如果他们是永久的,他们有更多的字段需要填写,比如办公室电话号码,只有当 type = 'Permanent' 时才应该不为空。在第三范式数据库中,列应该只取决于键,即员工,但它实际上取决于员工和类型,因此 1:1 关系是完全正常的,在这种情况下是可取的。如果我有 10 个通常填充的列,但仅针对某些类型的 20 个附加列,它还可以防止过度稀疏的表。

            【讨论】:

            • @ShaneD +1 实词示例。我也喜欢“只读”的区别。
            【解决方案15】:

            我能想到的最常见的场景是当你有 BLOB 时。假设您想将大图像存储在数据库中(通常,不是存储它们的最佳方式,但有时约束使其更方便)。您通常希望 blob 位于单独的表中,以改进对非 blob 数据的查找。

            【讨论】:

            • 认真的吗?通常不是最好的方法?这家最大的在线音乐供应商将其、咳咳、MP3 存储在数据库中。
            • @Mark,有几个问题涉及存储图像的最佳方式,无论是在数据库中还是在数据库中,并且大多数情况下似乎一致认为文件系统更快。我想如果这是真的,那么 MP3 也是如此。
            • “您通常希望 BLOB 在单独的表中” - 通常 BLOB 不会内联存储(如果它们超过特定 db 的特定行长度)。 BLOB 如果不是内联的,则通常存储为指向它们在 DB 页面中的物理位置的“指针”。
            • 在数据库中存储大数据(文件)是否有意义是有争议的,有些人反对有些人有正当理由,但 +1 以 1:1 为例。
            • 这确实应该是我希望看到的自己的问题。来自测量不同硬盘驱动器/OS/RDBMS 的时间/prestanda 的聪明人的输入。这个问题应该有一个明确的答案,如果测量正确,它不应该是有争议的。有没有人已经做好了?
            【解决方案16】:

            如果您有太多信息,1-1 关系也是必要的。表中的每条记录都有记录大小限制。有时表被一分为二(最常查询的信息在主表中),只是为了不让记录太大。如果表很窄,数据库在查询方面也更有效。

            【讨论】:

              【解决方案17】:

              任何地方都有两个完全独立的实体共享一对一的关系。一定有很多例子:

              人 牙医 (它的 1:N,所以它错了!)

              人医生(它的1:N,所以也是错的!)

              人 配偶 (它的 1:0|1,所以它大部分是错误的!)

              编辑:是的,这些都是非常糟糕的例子,特别是如果我一直在寻找 1:1,而不是两边的 0 或 1。我猜我的大脑出了问题:-)

              所以,我会再试一次。事实证明,经过一番思考,你可以拥有两个必须(就软件而言)一直在一起的独立实体的唯一方法是让它们在更高的分类中一起存在。然后,当且仅当您陷入较低的分解时,事物是并且应该是分开的,但在较高的层次上,它们不能没有彼此。上下文,然后是关键。

              对于医学数据库,您可能希望存储有关身体特定区域的不同信息,将它们作为单独的实体保存。在那种情况下,一个病人只有一个头,他们需要它,否则他们就不是病人。 (他们也有一颗心脏,以及许多其他必要的单一器官)。例如,如果您对跟踪手术感兴趣,那么每个区域都应该是一个独特的独立实体。

              在生产/库存系统中,如果您要跟踪车辆的装配,那么您当然希望以不同于车身的方式观察发动机的进展,但存在一对一的关系。护理必须有一个引擎,而且只有一个(否则它就不再是“汽车”了)。一个引擎只属于一辆车。

              在每种情况下,您都可以将单独的实体生成为一个大记录,但考虑到分解的程度,这是错误的。在这些特定的上下文中,它们是真正独立的实体,尽管它们在更高级别上可能不会如此。

              保罗。

              【讨论】:

              • 一个牙医有一个病人?一个医生只有一个病人?如果您将一位配偶放在一张桌子上,另一位放在另一张桌子上(我正要说男人在一张桌子上,女人在另一张桌子上。哦,好吧),则人与配偶的比例只有 1:1。
              • 马克,你可以做一个“Couples”表,其中行总是成对出现。但除此之外,我同意你的,嗯……咆哮。 :P
              • 是的,我也同意马克的观点。 :-)(我可以拒绝我自己的愚蠢答案吗?)
              • 是的,承认“愚蠢”证明你有多聪明。真正的懦夫会删除他们愚蠢的答案……幸好他们不是医生,会删除医疗记录。实际上,我们也不是,这是一件好事。重新启动将是一种糟糕的治疗方法。
              • 我一直认为,即使是世界上最聪明的人(无论当时是谁)也有他们愚蠢的时刻。这是人类的诅咒 :-) 而我的电脑也有接近智能的时刻。
              【解决方案18】:

              由于您的措辞方式,您的问题可以有多种解释方式。回复显示了这一点。

              现实世界中的数据项之间肯定存在 1:1 的关系。毫无疑问。 “是”的关系通常是一对一的。汽车是交通工具。 一辆车就是一辆车。一辆车可能是一辆车。有些车辆是卡车,在这种情况下,一辆车不是汽车。几个答案解决了这种解释。

              但我认为您真正要问的是......当存在 1:1 关系时,是否应该拆分表?换句话说,您是否应该拥有两个包含完全相同键的表?在实践中,我们大多数人只分析主键,而不分析其他候选键,但这个问题略有不同。

              1NF、2NF 和 3NF 的规范化规则从不要求将表分解(拆分)为具有相同主键的两个表。我还没有弄清楚在 BCNF、4NF 或 5NF 中放置模式是否会导致两个表具有相同的键。在我的脑海中,我猜答案是否定的。

              有一个标准化级别称为 6NF。 6NF 的规范化规则肯定会导致两个表具有相同的主键。 6NF 与 5NF 相比具有可以完全避免 NULLS 的优势。这对某些(但不是全部)数据库设计人员很重要。我从来没有费心将模式放入 6NF。

              在 6NF 中,缺失的数据可以用省略的行来表示,而不是在某些列中带有 NULL 的行。

              拆分表还有其他原因。有时拆分表会带来更好的性能。使用某些数据库引擎,您可以通过对表进行分区而不是实际拆分它来获得相同的性能优势。这可以使逻辑设计易于理解,同时为数据库引擎提供加速处理所需的工具。

              【讨论】:

                【解决方案19】:

                在我看来,1:1 的关系映射了 RDBMS 上的类继承。 有一个表 A 包含公共属性,即partent class status 每个继承的类状态都映射到 RDBMS 上,表 B 具有 1:1 的关系 到一个包含特殊属性的表。 表名和 A 还包含一个表示“转换”功能的“类型”字段

                再见 马里奥

                【讨论】:

                  【解决方案20】:

                  在 SQL 中,不可能在两个表之间强制执行 1:1 关系,这对双方都是强制性的(除非表是只读的)。对于大多数实际用途,SQL 中的“1:1”关系实际上意味着 1:0|1。

                  在引用约束中无法支持强制基数是 SQL 的严重限制之一。 “可延迟”约束并不算数,因为它们只是表示有时不强制执行约束的一种方式。

                  【讨论】:

                    【解决方案21】:

                    我认为 1:1 关系的最佳原因是数据库设计的 SuperType SubType。我基于这个模型创建了一个房地产 MLS 数据结构。有五种不同的数据馈送;住宅、商业、多户家庭、酒店和土地。

                    我创建了一个名为属性的 SuperType,其中包含五个单独的数据馈送中的每一个都共有的数据。这允许对所有数据类型进行非常快速的“简单”搜索。

                    我创建了五个单独的子类型,它们为五个数据馈送中的每一个存储唯一的数据元素。每个 SuperType 记录与相应的 SubType 记录具有 1:1 的关系。

                    如果客户想要进行详细搜索,他们必须选择 Super-Sub 类型,例如 PropertyResidential。

                    【讨论】:

                      【解决方案22】:

                      如果您的数据库中有某种类型的对象。

                      假设在一张表中,T1,你有列 C1、C2、C3... 具有一对一的关系。没关系,它是标准化的形式。现在说在表 T2 中,您有列 C1、C2、C3、……(名称可能不同,但说类型和角色相同)也具有一对一的关系。 T2 可以,原因与 T1 相同。

                      然而,在这种情况下,我认为适合单独的表 T3,包含 C1、C2、C3……以及从 T1 到 T3 以及从 T2 到 T3 的一对一关系。如果存在另一个表,我什至更认为合适,其中已经存在一个对多个 C1、C2、C3 ......比如说从表 A 到表 B 中的多行。然后,你使用 B 而不是 T3,并且有从 T1 到 B 的一对一关系,从 T2 到 B 相同,从 A 到 B 仍然是相同的一对多关系。

                      我认为规范化不同意这一点,这可能是它之外的一个想法:识别对象类型并将相同类型的对象移动到它们自己的存储池中,使用来自某些表的一对一关系,以及来自其他一些表的一对多关系。

                      【讨论】:

                        【解决方案23】:

                        大多数排名靠前的答案都为 1:1 关系提供了非常有用的数据库调整和优化原因,但我只想关注自然发生 1:1 关系的“野外”示例。

                        请注意大多数示例的数据库实现的一个重要特征:没有保留有关 1:1 关系的历史信息。也就是说,这些关系在任何给定时间点都是 1:1。如果数据库设计者想要记录关系参与者随时间的变化,那么关系就变成 1:M 或 M:M;他们失去了 1:1 的本性。了解了这一点,接下来就是:

                        • “Is-A”或超类型/子类型或继承/分类关系:此类别是指一个实体是另一个实体的特定类型。例如,可能有一个 Employee 实体,其属性适用于所有员工,然后是不同的实体来指示具有该员工类型独有属性的特定员工类型,例如医生、会计师、飞行员等。这种设计避免了多个空值,因为许多员工不具有特定子类型的专门属性。此类别中的其他示例可以是 Product 作为超类型,ManufacturingProduct 和 MaintenanceSupply 作为子类型; Animal 作为超类型,Dog 和 Cat 作为子类型;请注意,每当您尝试将面向对象的继承层次结构映射到关系数据库(例如在对象关系模型中)时,这种关系就代表了这种情况。

                        • “老板”关系,如经理、董事长、总裁等,一个单位只能有一个老板,一个人只能是一个单位的老板.如果这些规则适用,那么您将拥有 1 对 1 的关系,例如一个部门的一位经理、一家公司的一位 CEO,等等。“老板”关系不仅适用于人。如果一家公司的总部只有一个商店,或者一个国家的首都只有一个城市,就会出现同样的关系。

                        • 某些稀缺资源分配,例如一名员工一次只能分配一辆公司汽车(例如,每位卡车司机一辆卡车,每位出租车司机一辆出租车等)。最近一位同事给我举了这个例子。

                        • 婚姻(至少在一夫多妻是非法的法律管辖区):一个人一次只能与另一个人结婚。我从一本教科书中得到了这个例子,当一家公司记录员工之间的婚姻时,它用它作为 1:1 一元关系的例子。

                        • 匹配预订:当做出唯一预订然后作为两个独立实体履行时。例如,汽车租赁系统可能会在一个实体中记录预订,然后在单独的实体中记录实际租赁。尽管这种情况也可以设计为一个实体,但将实体分开可能是有意义的,因为并非所有预订都得到满足,也不是所有租赁都需要预订,这两种情况都很常见。

                        我重复我之前提出的警告,即只有在没有记录历史信息的情况下,其中大多数都是 1:1 关系。因此,如果员工改变了他们在组织中的角色,或者经理负责不同的部门,或者员工被重新分配了车辆,或者某人丧偶并再婚,那么关系参与者可能会发生变化。如果数据库没有存储有关这些 1:1 关系的任何先前历史记录,那么它们仍然是合法的 1:1 关系。但是如果数据库记录了历史信息(例如为每个关系添加开始和结束日期),那么它们几乎都会变成 M​​:M 关系。

                        历史记录有两个值得注意的例外:首先,某些关系很少发生变化,以至于历史信息通常不会被存储。例如,大多数 IS-A 关系(例如产品类型)是不可变的;也就是说,它们永远不会改变。因此,历史记录点是没有实际意义的;这些将始终以自然的 1:1 关系实现。其次,预订-出租关系分别存储日期,因为预订和出租是独立的事件,每个都有自己的日期。由于实体有自己的日期,而不是 1:1 关系本身具有开始日期,因此即使存储了历史信息,这些也会保持 1:1 关系。

                        【讨论】:

                        • 我真的很喜欢你坚持最初的问题精神,即这种关系何时是正确的,而不是由于计算机的物理性质等世俗原因而有用。
                        【解决方案24】:

                        如果有任何显着的性能优势,您可以创建一个一对一的关系表。您可以将很少使用的字段放在单独的表中。

                        【讨论】:

                          【解决方案25】:

                          出于安全目的没有必要这样做,但有更好的方法来执行安全检查。想象一下,你创造了一把只能打开一扇门的钥匙。如果钥匙可以打开任何其他门,你应该敲响警报。本质上,您可以拥有“CitizenTable”和“VotingTable”。公民一号投票给存储在投票表中的候选人一号。如果公民一再次出现在投票表中,那么他们应该是一个警报。请注意,这是一对一的关系,因为我们不是指候选人字段,而是指投票表和公民表。

                          例子:

                           Citizen Table
                           id = 1, citizen_name = "EvryBod"
                           id = 2, citizen_name = "Lesly"
                           id = 3, citizen_name = "Wasserman"
                          
                           Candidate Table
                           id = 1, citizen_id = 1, candidate_name = "Bern Nie"
                           id = 2, citizen_id = 2, candidate_name = "Bern Nie"
                           id = 3, citizen_id = 3, candidate_name = "Hill Arry"
                          

                          那么,如果我们看到投票表是这样的:

                           Voting Table
                           id = 1, citizen_id = 1, candidate_name = "Bern Nie"
                           id = 2, citizen_id = 2, candidate_name = "Bern Nie"
                           id = 3, citizen_id = 3, candidate_name = "Hill Arry"
                           id = 4, citizen_id = 3, candidate_name = "Hill Arry"
                           id = 5, citizen_id = 3, candidate_name = "Hill Arry"
                          

                          我们可以说,3号公民是一个骗子,骗了聂伯尔尼。只是一个例子。

                          【讨论】:

                            【解决方案26】:

                            当您处理来自第三方产品的数据库时,您可能不想更改他们的数据库以防止紧密耦合。但您可能拥有与他们的数据 1:1 对应的数据

                            【讨论】:

                              猜你喜欢
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 2011-06-12
                              • 2016-07-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              相关资源
                              最近更新 更多