代码之家  ›  专栏  ›  技术社区  ›  Rob Van Dam

链接表可以有两个互斥列吗?

  •  0
  • Rob Van Dam  · 技术社区  · 14 年前

    我有一个问题,因为以前的人设计决策不好,我不得不在一个链接表中有两列 总是互相排斥。我见过 SQL-Server: Define columns as mutually exclusive 但是MySQL没有强制检查约束,所以我正在寻找其他选项。有没有办法在两列之间强制互斥?

    以前的dev/admins构建了两个表,它们记录了基本相同类型的内容。我有一张新的a表,理论上是它们所代表的东西的1->多个表。因此,我的两个选择似乎是创建两个桥接表或一个具有两个外部键引用的桥接表。对我来说,这两个表似乎是一个丑陋的解决方案,我希望能够避免,但没有强制的互斥字段会让我容易腐败。

    具体的例子,因为我无法分享我的真实案例:

    Table 'full_time_students' stores full time students
    Table 'part_time_students' store part time students
    
    Table 'class' will store class info
    Table 'class_students' should store which students are in which class
    

    在一个理想的世界里,我将把这两个学生表结合起来,但是有很多代码会被破解,我没有时间/意志去修复所有这些,所以现在我不得不处理现存的模式/数据。我正在使用InnoDB,所以我已经计划在学生id上使用外键约束,但是正如我所说的,如果我使用一个表和两个列,我会打开自己的窗口,让一行和两个id一起使用。

    3 回复  |  直到 7 年前
        1
  •  1
  •   HLGEM    14 年前

    这里有一个在不破坏很多代码的情况下解决问题的方法。创建一个可更新的学生,并用来自其他表和标志字段的数据填充,以指示全日制或兼职。然后创建具有全职学生和兼职学生表名称的视图。这意味着所有的select仍然可以正常工作,您所要做的就是修复插入和更新代码以转到新表。

        2
  •  5
  •   Community CDub    9 年前

    根据评论修改。

    我不同意任何答案。

    使用“更多”表没有什么好害怕的,这是关系数据库的本质;特别是如果您想要关系的强大功能,并且允许用户访问数据库而不必通过您的应用程序。

    我假设有两件事:

    1. 你认为以前的开发人员犯了一个错误,学生全日制和学生兼职应该合并成学生, 因为 他们有许多共同的专栏

    2. 你有一个新的需求类,它需要类和学生之间的多对多关系。

      • 在关系术语中,这称为关联表:在逻辑模型中,它显示为n::n关系(无表);在物理模型中,它显示为表。(当然,如果它有列,那么它将在逻辑模型中显示为实体,而不是关系。)

    好的,(1)不正确。正如没有将公共列规范化为一个表是错误的一样,拥有一个包含不适用列(可为空列)的表也是错误的。他们应该做的是实施 三张桌子 ;不是一个;也不是两个,在普通的子类型超类型集群中。

      • 我的所有数据模型都符合 IDEF1X 标准。为了帮助刚接触IDEF1X的人,这里有一个文档解释 IDEF1X Notation 文件。如果你不明白圆圈、栅栏和鸦脚是什么意思;或者 关系线上的意思是;或者为什么水平线在那里,请现在阅读。

    Normalised Before

    所以你要来,你需要实现(2)。对于所有相关的人来说,生活是很容易的,因为数据库是标准化的:你可以添加你所需要的,而不必改变现有的表格结构,或者颠覆现有的代码。

    Normalised After

    所以你要来,你需要实现(2)。在寻找“互斥”列时,您已经确定了一个正常化错误(在您这边)。您需要的n::n关联表实际上是有学生的类;事实上,他们可能是全职或兼职的,这是在您确认基本需求后需要担心的一个过程。当然,在你考虑了这一需求之后,你必须实施一些措施来处理这两类学生。

    • 如果实现两个表,则只会使它们的错误更加复杂。最终会受到限制,而你的SQL代码将会很难看。

    Their Error Progressed by You

    我们所要求的,是让你在你这边正常化,因此避免妨碍你这边的分贝的力量。

    Normalised Yours

    • 关联表的一个表,以及两个子类型的一个表(基于两个子标准表的存在)。简单子类型超类型1::1群集。

    • 没有空值、完全完整性、FKs、可引用性等。每个表上都有简单的唯一索引。想想你的代码会是什么样子。

    请迁移现有的密钥,它们非常合适,它们已经有了意义,不要创建新的身份密钥。

        3
  •  0
  •   Community CDub    7 年前

    在MySQL中使用触发器强制执行业务规则之前已经出现过:

    Throw an error in a MySQL trigger