sql-server – 在类型/子类型设计模式中实现具有互斥子类的子类
副标题[/!--empirenews.page--]
介绍 为了使这个问题对未来的读者有用,我将使用通用数据模型来说明我面临的问题. 我们的数据模型由3个实体组成,它们应标记为A,B和C.为了简单起见,它们的所有属性都是int类型. 实体A具有以下属性:D,E和X; 实体B具有以下属性:D,E和Y; 实体C具有以下属性:D和Z; 由于所有实体共享公共属性D,因此我决定应用类型/子类型设计. 重要提示:实体是互斥的!这意味着实体是A或B或C. 问题: 实体A和B具有另一个公共属性E,但该属性不存在于实体C中. 题: 如果可能的话,我想使用上述特性来进一步优化我的设计. 说实话,我不知道怎么做,也不知道从哪里开始尝试,因此这篇文章. 解决方法只要这个问题是 Is my implementation of type/subtype design pattern (for mutually exclusive subclasses) correct?的延续,这本身就是 Don’t know how to transform variable entity into relational table的延续,我会问:你究竟想要优化什么?存储?对象模型?查询复杂性?查询性能?在优化一个方面与另一个方面时存在权衡,因为您无法同时优化所有方面.我完全同意Remus’s points关于: >每种方法都有利弊(即永远存在的“依赖”因素),以及 也就是说,您所面临的选择是在以下之间,按照最不规范化的顺序排列到大多数规范化: >将属性E推广到基类表 让我们看看每个选项: 将属性E移动到基本类型表 投票站 >降低了需要E而不是X,Y或Z的查询的查询复杂性. CON外 >无法将E标记为NOT NULL 在每个子类型表中保留属性E. 投票站 >更清洁的数据模型(即不必担心教育其他人为什么不应该使用基类型表中的列E,因为“它确实不存在”) CON外 >需要JOIN到子类型表以获取此属性 将E归一化到基类和A& A之间的中间表.乙 (请注意,我确实喜欢@MDCCL’s answer作为一种可行的替代方案,具体取决于具体情况.以下并不是对该方法的严格批评,而是作为增加一些观点的手段 – 当然,我的评估方法是与我已经提出的两个选项相同的背景.这将使我更容易澄清我所看到的完全归一化与当前部分归一化方法之间的相对差异.) 投票站 >数据模型是完全标准化的(这不是任何固有的错误,因为它是RDBMS的设计目的) CON外 >稍微占用更多空间(Bar表复制了ID,并且有一个新列,BarTypeCode)[可忽略不计,但需要注意的事项] 这意味着,如果您需要对一般基本信息进行查询但需要按实体类型进行分类或过滤掉一个或多个实体类型,那么基类表没有足够的信息,在这种情况下您需要LEFT JOIN Bar表.这也会降低索引FooTypeCode列的有效性. 这意味着,如果每个实体直接与基类表相关联,使得只有一个JOIN可以获得完整的实体,那么每个人都可以更快速,更轻松地建立熟悉数据模型的工作.查询/存储过程将采用通用方法,这使得它们更快地开发并且不太可能存在错误.一致的方法还使得将来更快更容易地添加新的子类型. 意思是,事情总是会发生变化,如果它变得普遍适用于所有子类型,那么将E移动到基类表是相当容易的.如果实体性质的变化使得这种变化值得改变,那么将公共属性移动到子类型也很容易.将子类型分解为两个子类型(只需创建另一个SubTypeID值)或将两个或多个子类型合并为一个子类型就很容易了.相反,如果E后来成为所有子类型的共同属性怎么办?然后Bar表的中间层将毫无意义,增加的复杂性将是不值得的.当然,不可能知道这种变化是否会在5年甚至10年内发生,所以Bar表不一定,甚至不太可能是一个坏主意(这就是我说“可能不太适应”的原因) ).这些只是要考虑的要点;这是两个方向的赌博. 这意味着,仅仅因为实体类型A和B之间共享E属性并不意味着A和B应该组合在一起.仅仅因为事物“看起来”相同(即相同的属性)并不意味着它们是相同的. 摘要 就像决定是否/何时进行非规范化一样,如何最好地处理这种特定情况取决于考虑数据模型使用的以下几个方面,并确保收益大于成本: (编辑:威海站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |