父类别/子类别决定类别之间:完全不相交或不完全重叠


11

我正在建立一个库存数据库,用于存储IT硬件,例如台式计算机,笔记本电脑,交换机,路由器,移动电话等。被放入子类型表中。我的困境是在以下两种设计之间进行选择:

在此处输入图片说明

在顶视图中,所有设备共享相同的子类型。例如,台式计算机和便携式计算机将在下表中记录:设备,网络设备。交换机将在以下位置记录:设备,网络设备。路由器将在以下位置记录:设备,网络设备,WANDevice。我们跟踪位置的任何设备都会在“位置”中有一条记录。我在此设置中想到的一些利弊:

  • 优点:基于公共字段(例如主机名或LocationID)选择记录更加容易。
  • 优点:没有空字段。
  • 缺点:特定设备的CRUD操作中应包含的表并不明显,并且可能会使以后的DBA感到困惑。

在底图中,所有设备都有其自己的子类型(此处未显示更多类的设备)。在这种情况下,很明显哪些表记录被插入或选择。台式计算机和便携式计算机可以在“计算机”等中使用。对于此设置,我想到了一些利弊:

  • 优点:很明显,哪些表用于子类型的CRUD操作。
  • 优点:CRUD操作只需使用一张表。
  • 缺点:基于公共子类型字段选择记录需要合并所有表,例如,按主机名或LocationID进行搜索。

在这两种情况下,ClassDiscriminator字段都放在子类型表中,以与CHECK约束一起使用,以控制可以插入哪些类型。

是否有任何建议的设计更好,还是完全出于见解并取决于数据库的预期目的?

编辑:我有一个特定的问题有关表“ NetworkDevice”的重叠性质。该表用于保存具有主机名和/或IP地址的任何设备的网络信息,无论它是计算机,交换机还是路由器。该表的重叠性质是否会引起问题,还是可以通过这种方式实现?

预先感谢您提供任何输入。请询问是否需要其他信息。


Answers:


15

数据库中子类型的物理实现是一个复杂的问题。除非您有提供引人注目的优势的情况(请参阅下面的一个或两个示例),否则它会增加实现的复杂性,同时却提供相对较少的价值。

通过非常复杂的子类型(在法院案件管理系统上的申请和判决,完全不同的联合风险商业保险合同结构)来完成此操作,我想对此有一些发现。一些重要的极端情况是:

  • 如果跨子类型的数据库字段总数相对较低(例如:小于100),或者子类型之间存在明显的共性,则将子类型拆分为单独的物理表可能没有什么价值。这将大大增加报告查询和搜索的开销。在大多数情况下,最好只有一个表并在应用程序中管理子类型。 (可能是最接近您的问题)

  • 如果您的子类型非常不相干,并且不同的子类型具有依赖于它们的依赖于类型的数据结构(即子表或更复杂的结构),则子类型表才有意义。在这种情况下,每个子类型在应用程序中可能具有相对较少的通用性(即,应用程序中可能有一个专用于该子类型的整个子系统)。大多数报告和查询可能会发生在给定的子类型内,而跨类型查询主要限于少数几个公共字段。 (法院案件管理系统)

  • 如果您有大量具有完全不同的属性的子类型和/或要求使其具有可配置性,则通用结构和补充元数据可能更合适。请参阅此SO发布,以获取一些可能方法的摘要。 (保险单管理系统)

  • 如果您有大量字段,并且子类型之间的通用性很小,并且对子类型表进行查询的要求也很少(即,对子类型表进行多路外部联接的方式就没什么了),那么类型表可能有助于管理列蔓延。 (您问题的病理复杂版本)

  • 一些O / R映射器可能仅支持管理子类的特定方法。

在大多数情况下,数据库模式中的物理子类型表只是解决问题的一种解决方案,因为它们可能具有不良的副作用。

就您的情况而言,我假设您有相对少量的子类型和可管理的属性。您的图表和问题并不表示有意将子表挂离记录。我建议您考虑使用上面建议的第一个选项,并维护一个表并管理应用程序中的子类型。


感谢您的详细回答。我本来想将所有内容都保留在一个表中,但是设备的某些字段不适用于其他字段,最后我会得到一堆空字段。例如,所有清单记录将具有特定于路由器的电路类型和服务提供商的字段。所有记录还将具有电话号码字段,除非设备是电话,否则电话号码字段将无意义。有关如何处理此问题的任何建议?
TheSecretSquad 2012年

2
@reallythecrash-可空字段的开销约为每个字段一个字节,因此,在资源使用方面,其开销比对子类表进行联接要少得多。真正唯一的缺点是,该表看起来有些杂乱,包含许多null。
ConcernedOfTunbridgeWells 2012年

3
@reallythecrash-如果您确实想要(并且您的DBMS支持它-您尚未指定正在使用的内容),则可以基于类型鉴别符设置检查约束,该约束在适合于字段的字段上强制执行null / not-null类。
ConcernedOfTunbridgeWells

3

考虑首先使用由David Hay撰写的Enterprise Model Patterns中的数据建模分类层次结构的规则来开发合理的逻辑数据模型。创建分类层次结构时,每个事件(行)必须是一个且只能是一个子类型。这意味着子类型是互斥的。分类必须基于一个单一的,基本的,不变的特征。使用此基本规则将使您的模型更加清晰。在您拥有的模型中,要进行分类的唯一特征是设备的用途-电话,网络交换机,计算机,路由器等。每个设备都必须是其中一种,并且只能是其中一种。因此,例如location将不是子类型。IP地址等属性属于超级类型。

我认为您会发现设备类型的数量将足够大,可以保证另一个答案中提到的EAV模式。我参考的David Hay书非常有效地介绍了这种模式。但是,如果子类型的数量很少,则可以凭经验来决定仅实现具有许多可空列的超类型表,仅实现具有重复列的子类型表,或同时实现这两者。如果每个子类型的属性变化很大,并且在超级类型级别上没有任何关系,则可能只使用子类型表。如果相反,则可能仅使用超类型表。如果有混合,则同时实施。

最后请注意,您始终可以将EAV模式实现为基本表架构,然后创建视图抽象层,以超级和子类型表的形式向应用程序展示数据。这使您在存储层具有灵活性,但在应用程序视图层具有可理解性。


感谢您的信息托德。我有一个关于“网络设备”表的问题。该表旨在保存具有主机名和IP地址的任何设备的记录。这意味着交换机,计算机和路由器都将在其表中存储与网络相关的数据。根据我的阅读,这被称为重叠子类型,其中子类型表保存了不止一种类型的相关数据。您是否知道应该避免这种情况,还是我可以以这种方式实施?
TheSecretSquad 2012年

Todd,关于您的陈述“创建一个将数据呈现给应用程序的视图抽象层...”。这听起来是个好主意。我考虑过完全按照您的描述使用视图,但是对此有一些疑问。我知道可以使用视图查询和显示应用程序中的数据,但是使用视图进行插入和更新是否是常见的做法?我知道在如何使用视图插入/更新查询时,必须对查询的结构进行一些限制(无顺序的从句等)。如果查询的结构正确,是否建议使用该视图进行插入和更新?
TheSecretSquad 2012年

以我的经验,重叠的子类型在逻辑层次上使事情变得混乱,这就是为什么我建议首先回头开发一个完整的逻辑模型的原因。您可以使用LDM在处理存储之前阐明范围和理解。在当前提出的模型中,对事物(设备)的基本本质与该设备在太空中的位置之间的理解有些混淆。在LDM中进行澄清。还要避免物理数据库中的重叠子类型,除非您要使用它来垂直划分列,在这种情况下,它根本不会键入。
Todd Everett

关于抽象层,可以使用“代替”触发器来使视图可更新。您提到的限制(无排序依据)是视图SQL本身的限制,而不是其使用限制。对于插入/更新,无论如何都没有订购。您还需要编写其他模块来处理插入/更新的详细信息,或者编写存储过程来处理它。我认为使用这些方法都没有问题,因为性能可以接受。对于单例类型写入,应该没问题。大量更新可能是个问题。
Todd Everett

2

产品不是库存。库存和产品是不同的。

产品实际上是产品的规格,而不是物理的东西。

实物是公司拥有(或存储)的资产。您可以拥有按序列号跟踪的资产(离散资产)或仅按数量跟踪的资产(库存资产)。

我看一下Silverston的《数据模型资源手册》第1卷。他为骄傲,功能,价格,库存建立了良好的架构。这样可以节省您很多时间。


1
提及Silverston的数据模型资源书+1分。看了一眼,这很有启发性。希望阅读更多详细信息,我认为任何有数据建模问题的人都应该这样做。谢谢。
TheSecretSquad 2013年

0

我要问的问题之一是,为什么要跟踪库存物品的各种属性?-或者,更具体地说,您正在使用此属性信息做什么?

如果您有很多报告或表单具有特定属性的特定含义,则需要使用ConcernedOfTunbridgeWell建议的方法。另一方面,如果记录这些属性是为了列出它们,或者可能是将它们与类似设备的相似属性进行比较,那么您实际上可能(很少)有很好的借口来使用EAV。我知道“ EAV是纯粹的邪恶”有很多原因,除了极少数情况下,这些原因与特定应用无关。您的应用程序可能就是这样。

请查看有关设备清单系统设计的答案和有关产品目录系统设计的答案,以了解EAV方法如何简化您的应用程序,并讨论EAV的确切风险以及如何解决。判断这些风险是否可能不适用于您的特定应用程序。


谢谢您的意见。我考虑过EAV,但认为我可以实现一个足够好的模型,而不必诉诸于EAV所涉及的复杂性。
TheSecretSquad 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.