Mysql 如何连接正确的一对一表(超级类型、子类型模型)?

Mysql 如何连接正确的一对一表(超级类型、子类型模型)?,mysql,database,normalization,one-to-one,database-normalization,Mysql,Database,Normalization,One To One,Database Normalization,我一直在研究第一、第二和第三范式,我想更好地规范化我的表。我意识到,其中的一部分原因是我从未理解一对一表格的用途。据我所知,“可选”数据应该分组到另一个表中,保留不同的实体不变,同时避免在一个整体表中维护几个空字段的细微差别 这是一个真实的场景。在CMS中,我希望维护几种不同类型的“页面”,使其可以通过附加插件进行扩展,而不会影响原始模式。到目前为止,我有以下示例表: 页面(标题、路径、类型等) 内容页面(与基本页面相同,但带有关键字/描述/内容字段) 链接页面(与基本页面相同,但包含对其他页

我一直在研究第一、第二和第三范式,我想更好地规范化我的表。我意识到,其中的一部分原因是我从未理解一对一表格的用途。据我所知,“可选”数据应该分组到另一个表中,保留不同的实体不变,同时避免在一个整体表中维护几个空字段的细微差别

这是一个真实的场景。在CMS中,我希望维护几种不同类型的“页面”,使其可以通过附加插件进行扩展,而不会影响原始模式。到目前为止,我有以下示例表:

  • 页面(标题、路径、类型等)
  • 内容页面(与基本页面相同,但带有关键字/描述/内容字段)
  • 链接页面(与基本页面相同,但包含对其他页面的引用)
  • 产品页面(与基本页面相同,但包含SKU和其他与ecomm相关的信息)
到目前为止,一切顺利。没有空值。自我记录的设计。超级类型/子类型在我的PHP模型和数据库之间是一致的。一切都很好

除此之外,给定任何页面ID,我不想首先进行查询以获取基本页面信息,找出它是什么类型的页面,然后通过另一个查询获取相应的子类型信息。我是否必须通过应用程序状态(或URL)来跟踪这一点,或者是否有一种方法可以知道要加入哪个表,而只知道页面ID而不知道其他内容

只有一个表(显然)就很容易做到这一点,因为空字段意味着类型,或者枚举可以告诉我它是什么。切换回1NF不是一个可以接受的答案,因为我已经知道怎么做了。我想这样学习;)


更新:还想指出,每个子类型属性对于该类型都是唯一的。因此,所有类型共享的任何公共属性都将进入基页表。子类型不会共享任何其他属性。这似乎是对子表进行分组的一种合乎逻辑的方式,但也许我用这种安排破坏了一对一表的目的…

您可以通过左外连接主
页面上的所有子类型来创建视图。该视图可以通过单个页面id进行查询,并返回一行多个空值,这与使用一个大的第一个普通表单页面表时得到的结果相同。

这取决于问问题的人。如果你的插件正在驱动查询,那么它可以从它的特定子类型开始,加入它知道必须存在的超类型

我不知道您的业务需求是什么,但在我看来,如果您试图保持模块化,那么您希望从子端(即插件端)驱动尽可能多的连接

如果要将查询从父类型驱动到子类型,那么可以使用外部联接,只要在不存在子类型的情况下在代码中准备好处理空列即可。显然,这种方法的模块化程度较低,但我认为有时这正是您需要或想要做的

是否有一种方法可以知道要在哪个表上联接,而只知道 页面ID和其他什么都没有

在超类型/子类型结构中,您应该知道的不仅仅是页面ID,还应该知道子类型

通常,“n”子类型的超类型/子类型结构映射到

  • n+1
    表格,每个子类型一个,超类型一个,以及
  • n
    可更新视图,每个视图都将超类型与相应的子类型连接起来
所以应用程序通常应该使用视图,而不是基表。(通常,但不总是。)


如果不使用视图,则从超类型检索页面id号时,还应检索标识子类型的列。没有这样的专栏吗?解决这个问题。请看另一个与超类型/子类型相关的代码、结构描述及其背后的逻辑。

这正是我的方向。这确实会影响模块化,因为我不想假设安装了哪些插件,以及随后在视图中包含哪些表。然而,我认为插件可以创建和管理自己的视图,而不影响“核心类型”。除非有一种方法可以动态连接到所有相关的表,否则这听起来是一个不错的选择,也是一个很好的观点。我现在的操作前提是控制器知道如何处理连接。如果是核心控制器,它们可以使用视图连接所有已知类型。如果它是一个插件,插件应该定义如何控制它。我喜欢你的答案和@bpgergo的结合。希望你能为答案分得一杯羹……我知道你的意思。我自己也有同样的感觉。无论是否单击复选标记,都可以随意向上投票!:)越来越近了。你们太棒了。现在,它是一个超级/子类型模型。但是,没有任何东西表明它不可能是具有相同超类型的多个子类型。这听起来像是一个观点问题。从super的角度来看,如果不检查每个视图或连接视图是否匹配,它对子类型一无所知。我已经修改了应用程序结构,以便始终知道它采用的是哪个子类型透视图,这很有帮助。我想可能会有一个“psedoo子类型”来组合多个子类型的属性。这三个答案一起解决了我的问题。谢谢