3.2.2 继承关系
以上4种常见的关系,领域模型里有,数据库里也有,转换起来就比较得心应手。然而继承关系就不太一样了,在领域模型设计中有,但在数据库设计中没有。如何将领域模型中的继承关系转换成数据库设计呢?有3种方案可以选择。
先看看图3-8所示的设计方案。“执法行为”通过继承分为“正确行为”和“过错行为”。如果这种继承关系的子类不多(一般就二三个),且每个子类的个性化字段也不多,则可以使用一个表来记录整个继承关系。在这个表的中间有一个标识字段,标识表中的每条记录到底是哪个子类。这个字段的前面部分罗列的是父类的字段,后面依次罗列各个子类的个性化字段。
图3-8 继承关系数据库设计
这个方案的优点是简单,整个继承关系的数据全都保存在这个表里。但是,它会造成“表稀疏”。在该案例中,如果“过错行为”记录只有一条,则字段“加分”永远为空;如果“正确行为”记录只有一条,则字段“过错类型”与“扣分”永远为空。假如这个继承关系中各子类的个性化字段很多,就会造成该表中出现大量空字段,我们把这种情况称为“表稀疏”。在关系型数据库中,为空的字段是要占用空间的。这种“表稀疏”既会浪费大量存储空间,又会影响查询速度,因此需要极力避免。所以,子类比较多或者子类个性化字段多的情况是不适合该方案的。
如果执法行为按照考核指标的类型进行继承,分为“考核指标1”“考核指标2”“考核指标3”等,并且每个子类都有很多的个性化字段,则采用前面那个方案就不合适了。这时,我们有另外两个数据库设计方案。一个方案是将每个子类都对应到一个表,有几个子类就有几个表,如图3-9所示。
图3-9 领域模型继承关系的另一个案例
这些表共用一个主键,即这几个表的主键生成器是一个,某个主键值只能存在于某一个表中,不能存在于多个表中。每个表的前面是父类的字段,后面罗列各个子类的字段,如图3-10所示。
图3-10 为继承关系的每个子类设计一个表
如果业务需求是在前端查询时每次只能查询某一个指标,那么采用这种方案就能将每次查询落到某一个表中,方案就最合适。但如果业务需求是要查询某个过错责任人涉及的所有指标,则采用这种方案就必须要在所有的表中进行扫描,那么查询效率就比较低,并不适用。
如果业务需求是要查询某个过错责任人涉及的所有指标,则更适合采用第二个方案,将父类做成一个表,各个子类分别对应各自的表,如图3-11所示。这样,当需要查询某个过错责任人涉及的所有指标时,只需要查询父类的表就可以了。如果要查看某条记录的详细信息,再根据主键与类型字段查询相应子类的个性化字段,那么这种方案就是完美实现该业务需求的选择。
图3-11 将继承关系的父类与子类分别设计成表
综上所述,将领域模型中的继承关系转换成数据库设计有三种方案,并且每个方案都有各自的优缺点。因此,我们需要根据业务场景的特点与需求去评估,选择更适于该业务场景的方案。所以,在没有详细了解需求之前是不能进行架构设计的。