加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

sql-server – 在范例/子范例计划模式中实现具有互斥子类的子类

发布时间:2020-12-31 14:43:04 所属栏目:编程 来源:网络整理
导读:先容 为了使这个题目对将来的读者有效,我将行使通用数据模子来声名我面对的题目. 我们的数据模子由3个实体构成,它们应标志为A,B和C.为了简朴起见,它们的全部属性都是int范例. 实体A具有以部属性:D,E和X; 实体B具有以部属性:D,E和Y; 实体C具有以部属性:D和Z
副问题[/!--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完全归一化到与C沟通的新的中间子类表,A和B将直接成为(@MDCCL’s answer)的子类

让我们看看每个选项:

将属性E移动到根基范例表

投票站

>低落了必要E而不是X,Y或Z的查询的查询伟大性.
>因为没有JOIN,对付必要E而不是X,Y或Z(尤其是聚合查询)的查询,服从也许更高.
>可以在(D,E)上建设索引(假如是这样,也许是(D,E)上的过滤索引,个中EntityType<> C,假如应承这样的前提)

CON外

>无法将E标志为NOT NULL
>在基范例表上必要特另外CHECK CONSTRAINT以确保当EntityType = C时E IS为NULL(尽量这不是一个大题目)
>当EntityType = C时,必要向数据模子的用户先容为什么E必需为NULL,乃至应该完全忽略.
>当E是牢靠长度范例时服从略低,而且大部门行用于C的EntityType(即不行使E因此它为NULL),而且不行使列上的SPARSE选项或数据压缩聚积指数
>对付不必要E的查询,服从也许较低,由于基范例表中存在E将增进每行的巨细,从而镌汰可以得当数据页的行数.但这高度依靠于E简直切数据范例,FILLFACTOR,根基范例表中有几多行等.

在每个子范例表中保存属性E.

投票站

>更洁净的数据模子(即不必担忧教诲其他工钱什么不该该行使基范例表中的列E,由于“它确实不存在”)
>也许更靠近于物体模子
>假如这是实体的必须属性,则可以将列标志为NOT NULL
>在基范例表上不必要特另外CHECK CONSTRAINT,以确保当EntityType = C时E IS为NULL(尽量这不是一个庞大的收益)

CON外

>必要JOIN到子范例表以获取此属性
>因为JOIN,在必要E时也许服从稍低,这取决于你拥有的A B行数,而不是有几多行.
>对付仅将实体A和B(而非C)作为沟通“范例”处理赏罚的操纵轻微更坚苦/伟大.虽然,您可以通过一个View来实现这一点,该视图在A的JOINed表的SELECT和B的JOINed表的另一个SELECT之间执行UNION ALL.这将低落SELECT查询的伟大性,但对INSERT和UPDATE查询没有那么有效.
>按照特定查询及其执行频率,假如(D,E)上的索引确实有助于一个或多个常用查询,则也许会导致服从低下,由于它们无法一路编入索引.

将E归一化到基类和A& A之间的中间表.乙

(请留意,我确实喜好@MDCCL’s answer作为一种可行的更换方案,详细取决于详细环境.以下并不是对该要领的严酷品评,而是作为增进一些概念的本领 – 虽然,我的评估要领是与我已经提出的两个选项沟通的配景.这将使我更轻易澄清我所看到的完全归一化与当前部门归一化要领之间的相对差别.)

投票站

>数据模子是完全尺度化的(这不是任何固有的错误,由于它是RDBMS的计划目标)
>镌汰了必要A和B但不是C的查询的查询伟大度(即不必要通过UNION ALL插手两个查询)

CON外

>轻微占用更多空间(Bar表复制了ID,而且有一个新列,BarTypeCode)[可忽略不计,但必要留意的事项]
>查询伟大性略有增进,由于必要特另外JOIN才气达到A或B.
>增进锁定的外貌地区,首要是在INSERT上(DELETE可以通过将外键标志为ON CASCADE DELETE来隐式处理赏罚),由于事宜将在基类表(即Foo)上保持打开稍长一些[可忽略不计,可是要意识到]
>没有直接相识现实范例 – A或B – 在基类表中,Foo;它只知道可所以A或B的Br型:

这意味着,假如您必要对一样平常根基信息举办查询但必要按实体范例举办分类或过滤掉一个或多个实体范例,那么基类表没有足够的信息,在这种环境下您必要LEFT JOIN Bar表.这也会低落索引FooTypeCode列的有用性.
>没有同等的要领来与A& amp; B vs C:

这意味着,假如每个实体直接与基类表相干联,使得只有一个JOIN可以得到完备的实体,那么每小我私人都可以更快速,更轻松地成立认识数据模子的事变.查询/存储进程将回收通用要领,这使得它们更快地开拓而且不太也许存在错误.同等的要领还使得未来更快更轻易地添加新的子范例.
>也许不太顺应随时刻变革的营业法则:

意思是,工作老是会产生变革,假如它变得广泛合用于全部子范例,那么将E移动到基类表是相等轻易的.假如实体性子的变革使得这种变革值得改变,那么将民众属性移动到子范例也很轻易.将子范例解析为两个子范例(只需建设另一个SubTypeID值)或将两个或多个子范例归并为一个子范例就很轻易了.相反,假如E其后成为全部子范例的配合属性怎么办?然后Bar表的中间层将毫有时义,增进的伟大性将是不值得的.虽然,不行能知道这种变革是否会在5年乃至10年内产生,以是Bar表不必然,乃至不太也许是一个坏主意(这就是我说“也许不太顺应”的缘故起因) ).这些只是要思量的要点;这是两个偏向的打赌.
>也许不恰当的分组:

这意味着,仅仅由于实体范例A和B之间共享E属性并不料味着A和B应该组合在一路.仅仅由于事物“看起来”沟通(即沟通的属性)并不料味着它们是沟通的.

择要

就像抉择是否/何时举办非类型化一样,怎样最好地处理赏罚这种特定环境取决于思量数据模子行使的以下几个方面,并确保收益大于本钱:

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读