【问题标题】:Many-to-many relationship simplification多对多关系简化
【发布时间】:2014-10-03 13:21:53
【问题描述】:

考虑以下两个表:

Messages
MessageId (PK)
Text  

Languages
LanguageId (PK)
Language

Messages 和 Languages 表之间存在多对多的关系(即每个 Message 可以有多个 Languages,每个 Language 可以由多个 Messages 共享)。为此,我添加了以下联结表:

Messages_Languages
MessageId (PK)(FK)
LanguageId (PK)(FK)

但是,这似乎有些不必要,因为语言从根本上是消息的属性。使用上面的 Messages_Languages 表而不只是将 LanguageId 作为外键添加到 Messages 表有什么好处? (见下文)

Messages  
MessageId (PK)
LanguageId (PK)(FK)
Text  

似乎少一张桌子也能完成同样的事情。

【问题讨论】:

    标签: sql sql-server many-to-many data-modeling


    【解决方案1】:

    做某事不重要,重要的是做正确的事。 问问自己:

    是单个消息将与多种语言和 语言可以连接到许多消息?

    这是多对多的关系,你应该有它的联结表。

    如果您只需要为单个消息提供一种语言,则使用语言 id 作为消息的属性。这称为一对多关系。

    为了向您展示这两者在某些数字上的区别:

    在表Messages_Languages 中可以有行:

    1,1
    1,2
    1,3
    2,1
    2,2
    2,3
    

    在最后一张桌子上:

    Messages  
    MessageId (PK)
    LanguageId (PK)(FK)
    Text  
    

    你可以输入:

    1,1
    2,3
    3,2
    

    【讨论】:

      【解决方案2】:

      它似乎完成了同样的事情......

      没有。联结表建模多对多,而 FK 建模一对多。

      所以问题不是哪个更好,而是你需要哪个

      【讨论】:

      • 只需将语言标识添加到消息表即可满足我的需要。但是,我基本上不明白为什么我能够使用该方法对这种多对多关系进行建模,而通常建模这种关系需要一个联结表。
      • 为什么你认为你只是用一个 FK 来建模多对多?在这种情况下,一条消息可以只有一种语言,从而形成“一种(语言)对多(消息)”的关系。
      • 基本上我的帖子的重点是您选择的解决方案取决于您的要求,我们无法为您定义您的要求。如果您需要一条消息使用多种语言(例如多种翻译),那么您需要多对多(联结表)。如果给定的消息一次只能使用一种语言,那么您需要的是一对多 (FK)。
      • 谢谢,我明白了!看来我误解了这种关系的性质。
      【解决方案3】:

      这是一个很好的简单例子。根据您的简单示例,最好将 LanguageID 作为属性添加到表中,因为您是正确的:它实际上只是一个属性。大概有固定数量的语言,并且您的应用程序的用户在使用您的应用程序时不会添加新的语言。

      随着您进一步开发应用程序,这是否成立是另一个问题。如果您添加消息版本或其他一些附加列的概念,也许有一个单独的表是有意义的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-04
        • 2014-11-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-28
        • 1970-01-01
        相关资源
        最近更新 更多