数据库中实现数据继承的设计方法

遇到这么一个场景:需要根据分类树层级,使每个分类中定义的数据(以下简称:变量)可以像继承一样传递给子分类,而每个分类又可以单独对继承的变量进行设置,有的设置是专属的,有的设置又可以继续继承。

方案选型

为了通过数据库保存继承关系,开发之前研究了两种方式:

  1. 在变量的定义中保存继承关系

    每次发生继承后,都复制一个变量副本,然后在变量的副本中,保存继承对象的 id。但这有一个很严重的问题,每当分类树结构变动时,都要去维护继承关系,这是一个繁杂易错的操作。

  2. 通过分类树来确定继承关系

    变量仅属于定义它的分类,通过分类的树形结构来自动确定继承关系,然后新建一个设置表,记录分类与变量对应的设置。

实现

数据表结构

category 表:

1
2
3
4
5
{
_id: '',
parentId:'',
name: ''
}

variable 表:

1
2
3
4
5
6
7
8
{
_id:'',
name:'',
categoryId:'',
privateSettings:{
color:''
}
}

setting 表:

只有当变量在某个分类中展示时,设置才会生效

1
2
3
4
5
6
7
8
{
_id:'',
categoryId:'',
variableId:'',
publicSettings:{
hidden:false
}
}

查询继承的变量

由于通过 category 树来确定继承关系,因此,要查询一个分类中对应的所有变量,应:

  1. 先找到分类对应的所有父分类,即继承链上所有的 categoryId
  2. 通过 categoryId 来查找变量

设置的继承

通过如下方式实现设置的继承:

  1. 先通过 variableId 找到所有的设置

  2. 求解每个变量的设置继承链

    根据 category 树,将变量对应的设置组装成一个链表形式的数据,如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    {
    categoryId:'',
    publicSettings:{},
    parent:{
    categoryId:'',
    publicSettings:{},
    parent:{...}
    }
    }

在使用时,写一个方法去递归这个设置继承链,就可以获得需要的设置参数。

当数据传递到前端后,前端可以将多个设置通过原型链连接在一起,使用时直接通过 obj.name 的方式读取。就不需要专门的方法去获取设置了。

参考

  1. 类的继承关系如何在关系型数据库体现
  2. How to Model Inheritance in a Database