【问题标题】:Is it necessary to create a table for all repeated data?是否需要为所有重复数据创建一个表?
【发布时间】:2011-11-02 14:07:42
【问题描述】:

我希望这不会是一个愚蠢的问题。我对数据库规范化的概念有些困惑,这似乎表明在特定字段/列中有任何类型的可预测或重复数据时,最好创建一个新表并通过外部 ID 链接,这真的是每种情况都需要?

例如,GenderBusiness Type 等字段(没有严格的功能用途,只有信息) , Salutation(先生、夫人等),所有这些都会在整个表格中重复出现,这似乎有点过头了,让我不得不创建一个新表格对于这些?它还使我在检索数据时必须使用更多的 JOIN。

什么时候有必要对重复数据使用单独的表,或者最好的做法是对所有内容都这样做?

【问题讨论】:

标签: mysql sql database database-normalization


【解决方案1】:

我对数据库规范化的概念有点困惑,它 似乎暗示有任何可预测的或 在特定字段/列中重复数据,那么最好创建一个 新表和外国ID链接,这对每个人来说真的有必要吗 情况?

你读错书了。规范化有时涉及将属性从一个关系移动到另一个关系;规范化从不涉及用 ID 号代替文本。

当您需要对允许用户放入列中的值进行某种控制时,您可以使用附加表。

要限制允许用户在列中输入的值,例如“业务类型”,您可以添加一个包含所有已知有效值的表,然后为其设置外键引用。

您还可以使用 CHECK 约束来限制值,但是当您发现新的有效值时,您必须更改架构。如果使用表和外键约束,则只需在表中插入一行。在您的情况下, CHECK 约束将适用于“性别”;表格可能更适合“业务类型”和“称呼”。

【讨论】:

    【解决方案2】:

    一般来说,当您关心正确的数据输入时,我建议您使用 ENUM。例如,如果你想找到所有性别为 MALE 的人,如果你能保证性别字段中总是有一个大写的 M,而不是小写的 m,或者一个代表“guy”的 G,那就太好了,因为前面-end 应用程序包含错误。

    如果您关心正确的数据输入并且有与该概念相关的其他信息,我建议您将其分解到单独的表格中。例如,如果“业务类型”与 TAX_RATE 相关联,您可能想要创建一个 business_types 表。

    如果您信任您的前端应用程序,并且您没有与字段关联的真正业务逻辑 - 并且数据没有固有的业务限制,例如在问候语中,只需有一个 varchar 字段,前端可以在其中转储其数据。

    【讨论】:

    • @Mark-Bannister 没有关于不使用 ENUM 的任何争论。
    【解决方案3】:

    将任何单个属性删除到另一个表并用另一个表示相同事物的单个属性替换它与规范化无关。出于其他原因做这样的事情可能有用也可能没用,但这不是规范化。

    【讨论】:

      【解决方案4】:

      你只需要使用常识。 除非遗传学提出新的东西,否则您可以安全地在 Gender 字段中使用 M/F 值(当然要注意本地化)。 对于这些往往是动态的列表,您需要单独的表格 - 因此可以从一个地方获得所有可能的选项。

      【讨论】:

      • 性别代码是特定于应用程序的。 ISO 5218 定义了四种:男性、女性、未知和不适用。 (“不适用”让你想知道,不是吗?)但有些应用程序可能需要区分出生时的男性和性别重新分配后的男性。但更重要的一点是,规范化是一门硬科学(好吧,有点硬,允许语义);常识,以“你可以有你的意见;我可以有我的意见”的形式,真的没有一席之地。
      【解决方案5】:

      对于像性别这样的事情,我想说一个简单的 CHAR 字段就足够了。即“M”、“F”、“U”(未知)。但是对于业务类型,我建议将其分解为单独的表格。一方面,业务类型可能会相当长,您可能需要在任何给定时间添加更多,并且您可能希望更改业务类型。

      【讨论】:

        【解决方案6】:

        规范化的重点是确保关于一个实体的相同信息不会被存储两次(因为它可能而且很可能会变得不一致)。显然,同一张表中的不同实体将具有相同的字段,当然其中许多将是 F 和许多 M。这不是问题。您唯一不应该做的事情是存储冗余数据每条记录,例如 GENDER:f,TERM_OF_ADDRESS:Ms - 最好通过查找表来完成。

        此外,您不需要仅仅因为架构中的不同表具有相似的字段(例如 TYPE 或 GENDER)而进行规范化。只要确保那些真的是独立的表!例如,如果您在表 EMPLOYEE 中描述员工,并且该表包含性别信息,那么即使性别可能与医学相关,也可能不应该将其存储在链接的 HEALTH_RECORD 表中。

        【讨论】:

          【解决方案7】:

          如果您想要一个完全规范化的数据库设计,那么,是的,您应该将所有重复实体放在单独的表中。

          对于像 gender 这样的字段,它会带来包含男性/女性等描述性信息的好处,而不是像 M/F 或 True/False 这样的代码。

          另一方面,正如您所说,每个新表都使获取数据变得更加复杂,因此在实践中您尝试找到一个相当好的标准化平衡。

          【讨论】:

          • 没有一种范式询问列中是否有重复值。如果您在列中发现重复值,则没有一种范式要求您在不更改原始表的情况下创建附加表。这不是标准化;这是数据库设计的一个完全不同的方面。
          • 那我确实理解正确。问题是你完全错了。规范化不涉及用 ID 号替换值。规范化不涉及用值的短代码替换值。规范化涉及从一个表中删除列,然后将这些相同的列插入到另一个表中。在表的多行中重复业务类型的名称,与在表的多行中重复业务类型的 id 号或在表的多行中重复业务类型的短代码一样冗余。
          • 将任何单个属性删除到另一个表并用另一个表示相同事物的单个属性替换它与规范化无关。这些值是否“重复”或它们是否是“短代码”都没有关系。 2NF、3NF、BCNF、4NF、5NF 等只关心删除 非关键依赖项,并且完全不知道属性包含什么类型的数据。
          • @Guffa:您写的是“完全规范化的数据库设计......将任何重复实体放在单独的表中”。如果“重复实体”是指任何单个属性,例如“业务类型”,那是不正确的。用外键替换属性并不能消除逻辑术语中的任何冗余,因为新的 FK 值与旧值完全相同。我希望您的意思是旧值可以被需要更少存储的新值替换。但这与规范化无关,规范化特别是由于非关键依赖导致的冗余。
          • @Guffa 您误解了数据库规范化是什么。我也曾经有同样的想法并为这个概念而苦苦挣扎,但 catcall 说的是对的
          【解决方案8】:

          您可以将 ENUM(Mr, Mrs) 或 ENUM(Male,Female) 用于此类数据。

          http://dev.mysql.com/doc/refman/5.1/en/enum.html

          【讨论】:

          • 对不起,Andrej,我以为我在这里留下了评论。它是“使用 ENUM 时为 -1”。
          • 你能解释一下你的想法吗? Enums 非常适合 Gender/Types 之类的列或具有静态值的列。它们还在 Mysql 中进行了优化以进行搜索。
          • 取消投票。我最初的反对意见是,由于这是一个规范化问题,而不是一个特定于 MySQL 的问题,一个特定于 MySQL 的技术(如 ENUM)将不如更广泛适用的技术(如检查约束)有用。但是,我已经检查过了,似乎在 MySQL 中实现检查约束的唯一方法是作为 ENUM!
          猜你喜欢
          • 2020-05-26
          • 2013-04-10
          • 2012-07-23
          • 1970-01-01
          • 2019-12-17
          • 1970-01-01
          • 1970-01-01
          • 2019-12-11
          • 1970-01-01
          相关资源
          最近更新 更多