【问题标题】:When to separate columns into new table何时将列分隔到新表中
【发布时间】:2009-07-16 21:39:49
【问题描述】:

我有公司、客户、供应商等表,它们都有地址信息相关的列。

我想弄清楚是否应该创建一个新表“地址”并将所有地址列分开。

在所有表上都有地址列很容易使用和查询,但从良好的设计角度来看,我不确定这是否是正确的做法,让这些相同的列在几个表上重复让我很好奇。

地址的内容对我来说并不重要,我不会在任何决策过程中检查或使用这些地址,它们纯粹是与信息相关的。目前我正在查看 5 个包含地址信息的表

【问题讨论】:

    标签: asp.net sql performance design-patterns


    【解决方案1】:

    所有设计问题的答案是这样的:

    视情况而定。

    因此,基本上,在地址的情况下,这取决于您是否会为每位客户提供超过 1 个地址。如果您有超过 1 个,请将其放入新的 Addresses 表中,并为每个地址指定一个 CustomerID。创建通用地址表并将其映射到公司/客户/供应商表是过度的(大多数时候,这取决于!)。

    在您的对象之间以多对多关系映射地址通常也有点矫枉过正(而且很危险)(因为如果您这样做,地址似乎会在用户身上神奇地改变)。

    一个重要的规则是:保持简单!

    【讨论】:

    • 你能举个例子说明你如何在多对多关系中使用地址
    • 感谢上帝在他们说出“应该盲目遵循规范化规则”之前思考的人
    • @korki:当然。您可能决定客户和供应商可以位于同一地点,并且他们可能有多个地址(帐单地址、收货地址)。然后,您将创建一个表以将客户/供应商记录映射到地址。这很可怕,因为它通常比您想要的要复杂,并且更新其中一个地址可能会产生意想不到的后果。
    • @balabaster 为了记录在案,我也投票支持戴夫。非规范化数据库会导致很多问题,以至于初学者不应该决定是否捏造,恕我直言。只有在他们意识到正确做事的原因之后,他们才应该偷工减料。
    • @Dave:我的情况要简单得多。我只存储地址信息以供参考,并不关心它是否与任何其他实体重复。我还不确定我是否还会使用单独的帐单和送货地址选项,但为什么我首先考虑表格分离是为了将来有这样不同的地址选项以备不时之需......
    【解决方案2】:

    这称为Database Normalization。是的,如果没有其他原因,您想将它们分开,因为如果您将来需要,当您有代码和查询时会更加困难。

    通常,您应该始终以第三范式设计您的数据库,即使对于简单的应用程序也是如此(在某些情况下,您不会出于性能或逻辑原因,但一开始我总是会尝试做到这一点第三范式,然后在你知道正确的做法后学会作弊)。

    编辑:为了对此进行扩展并添加我在其他帖子中所做的一些 cmets,我坚信在涉及代码时从简单的设计开始,并在很明显变得过于复杂时进行重构更深入的面向对象原则将是合适的。但是,重构生产中的数据库并不是那么简单。这一切都与投资回报率有关。从一开始就设计一个规范化的数据库来证明不这样做太容易了。设计不佳的数据库的后果可能是灾难性的,在您意识到这一点之前通常为时已晚。

    【讨论】:

      【解决方案3】:

      是的,您应该将地址分开到自己的表格中。知道问是件聪明的事。这里的关键是地址的一般格式是相同的,无论它是谁;客户、公司、供应商……他们都有相同的地址字段。

      之所以值得这样做,是因为它能够将地址视为原子元素;也就是说,您可以概括与地址相关的所有功能并让它只处理一个表,而不必担心它处理多个表以及可能发生的相关架构漂移。

      【讨论】:

      • 这并不总是必要的。通常不会有太多的地址架构漂移。
      • 我不同意。规范化本身并不总是正确的方法。这取决于数据的目的和重复数据的实际比例。如果重复数据的可能性为零,我会说没有目的对架构进行规范化。
      • 没错;通常不会有很多架构漂移,但我见过一家公司几乎倒闭,因为客户和供应商之间的地址字段长度之间存在架构差异(varchar(80) 与 varchar(120) )。 IMO,标准化涉及的工作量相对较小,值得在以后承担潜在的高风险。
      【解决方案4】:

      如果您只在它们自己的表范围内使用这些地址,那么将它们移动到它们自己的表中可能没有真正的好处。

      基本上,这听起来不值得。

      【讨论】:

      • 将它们移动到自己的表中并没有真正的好处,忽略了在一个地方维护单个连贯地址架构的价值,而不是在多个地方维护它。 (我看到公司为与此相关的错误而疯狂,当地址字段的长度最终对于公司和客户来说是不同的。)此外,双重否定令人困惑。
      • @McWaffle:但这就是“取决于”的地方。如果您只有 2 或 3 个具有地址的实体,那么它对您的系统实际上并没有太大的威胁。如果您有 10 个使用地址的实体,并且您需要一种通用的方式将地址本身作为一等对象处理,我倾向于同意您的观点。
      • @DaveMarkle:我不同意你的观点;我只是认为在这种类型的大多数系统中,随着时间的推移,扩展会让您处于希望您最初完成标准化的情况。
      • @McWafflestix-这真的归结为业务需求。如果您是一家 GIS 公司或加拿大邮政,您会想要它,但对于大多数其他公司来说,将它绑定到客户表是可以的。此外,有时您肯定希望将其绑定到单个表,例如当您发货时,您是否真的希望在客户移动时更改交付记录?以我的经验,这样做的理由通常是缺乏的。顺便说一句,感谢您的错字评论。
      • @Dave Markle - 我非常喜欢重构代码。从简单开始,仅在情况允许时创建复杂的设计。但是,数据库设计不同。重构数据库不能掉以轻心。在生产环境中重构数据库要比重构代码困难得多。这是不值得的,因为一旦您知道如何将数据库置于第 3 范式中,就真的很容易开始。
      【解决方案5】:

      如果表之间存在重叠(即在公司表和供应商表中都输入了相同的组织),并且两个表中的地址应该始终相同,那么可能值得将地址移到自己的表中,并且从其他三个表中获得外键。这样,您只需在它发生变化时在一个地方更新它。

      如果这三个表完全相互独立,那么将数据移动到另一个表并没有太大的好处,所以你还是不要管它。

      【讨论】:

        【解决方案6】:

        我认为这完全取决于数据库的用途。诚然,所有地址信息在结构上都是相同的,从理论上讲,它们都应该在一个通过键与父表链接的单个表中。

        但是从性能和查询的角度来看,将它们保存在各自的表中确实从报告的角度简化了事情。

        我目前的公司 [物流] 有一种情况,地址在逻辑上实际上是相同的 - 它们都是位置,无论它们是取货地点、送货地点、客户等。

        就我而言,我会说他们绝对应该都在一张桌子上。但如果从供应商、客户、联系信息的角度来看,我会说虽然理论上将地址放在一个表中很好,但实际上它不会给你买很多东西,因为数据不太可能重复。

        【讨论】:

          【解决方案7】:

          我不同意戴夫的观点。多对多方法(地址 用户)既安全又非常有利。

          当客户移动时,地址表中的地址不会改变。而是在地址表中找到新地址,并将客户等链接到该记录。如果新地址尚未在表中,则会将其添加到其中。

          那么地址记录本身会改变吗?是的,在这样的情况下:

          • 原来地址有错别字
          • 美国邮政服务更改街道名称

          在这些情况下,将所有地址放在一个表中而不重复会得到回报;任何其他安排都需要烦人且重复的数据输入。

          当然,如果数据库被滥用,那么避免多对多关系会更安全。但是从这个意义上说,如果数据库被坏人掌握,最好将所有内容打印出来,将其存储在文件柜中,并根据纸质副本验证每笔交易。因此,在我看来,“防止误用”并不是一个好的设计原则。

          【讨论】:

            猜你喜欢
            • 2017-08-10
            • 1970-01-01
            • 2023-03-05
            • 1970-01-01
            • 2021-06-03
            • 2021-05-14
            • 2021-11-01
            • 2014-03-08
            • 1970-01-01
            相关资源
            最近更新 更多