层级系统

2017-10-20  本文已影响57人  JSON_NULL

目标

抽象层级结构,构建统一的层级管理系统。

要解决的问题:

  1. 系统层级管理困难
  2. 因系统层级变动所引发的系统重构。

重点

  1. 可重用,场景的覆盖一定要全面,可适合用于各种各样的场景。
  2. 可扩展,在应用到不同场景时,可以方便的扩展以支持对应场景的附加要求。

数据表结构

system_level 表

字段:

  1. level_id,唯一标识,在system_level表中唯一标识一个层级记录。
  2. level_name,层级名称,需要限制长度。
  3. level_pid,上级层级记录的唯一标识,记录自己的父层级。
  4. is_deleted,是否已经删除,如果已经删除则存储一个非0值,为数据安全而做的软删除功能。

表说明:

  1. system_level 表 负责存储层级结构,所有level_pid为零的记录表示一个顶级,每个顶级下可以扩展多个子层级,子层级还可以继续扩展子层级,如此往复不限制深度。
  2. level_id做主键,为了提高查询效率还需要对level_name,level_pid,is_deleted分别做索引。

字段说明;

is_deleted,如果记录是正常可用状态,则其值为0。如果是删除状态(软删除)则其中存储的是用户直接操作删除的层级记录的id值。这里需要详细说明一下,在对system_level表中的记录进行删除操作时,需要级联删除其下所有的子层级;如果用户操作删除一个层级,则所有需要删除的层级记录(包含用户直接操作删除的和被级联删除的子层级)的is_deleted字段中都会存储用户直接操作删除的那个层级记录的id值。

system_level_relationship 表

字段:

  1. level_id,system_leve表中的唯一标识,在这里用于确定一个作为子层级的记录。
  2. level_ppid,system_level表中的唯一标识,在这里用于确定一个祖先层级的记录。

表说明:

  1. system_level_relationship表用于记录一个层级的所有祖先。level_id用于确定这里记录的是谁的祖先,level_ppid用于确定祖先是谁。一个记录可以有多个祖先(父、祖父等),一个记录也可以有多个子孙(多个孩子,多个孙子)。
  2. level_id和level_ppid 做联合主键,为了提高连接查询效率还需要分别对level_id和level_ppid做索引。

应用场景及方案

场景1:

  1. 层级结构为省、市、县、校,每一个层级下都可以有多个球队(省队、市队、县队、校队)。
  2. 每个球队下面还可以有教练、球员等。
  3. 在层级结构中上级可以查看所有直属或非直属下级所有的球队、教练、球员。

方案:

  1. 使用层级系统中的 system_level 和 system_level_relationship 表。
  2. 球队表需要有唯一标识squad_id,还需要存储它所属的层级level_id。
  3. 教练表、球员表需要有自己的唯一标识coach_id、player_id,还需要存储它们所属的球队和层级squad_id和level_id。
  4. 查询所有下级的球队 select s.* from squad s left join system_level_relationship slr on s.level_id = slr.level_id where slr.ppid = ?
  5. 查询所有下级的教练 select c.* from coach c left join system_level_relationship slr on c.level_id = slr.level_id where slr.ppid = ?

场景2:

  1. 在与(场景1)要求相同的情况下增加以下需求。
  2. 层级结构省、市、县、校要求存储除了名字之外的其他信息

方案:

  1. 增加一张省表province,需要level_id字段记录省所属的层级,同时用level_id做主键。
  2. 增加一张市表city,用level_id记录其所属的层级、同时也用level_id做主键。
  3. 增加一张县表county,用level_id记录所属的层级,同时也用level_id做主键。
  4. 增加一张学校表club,也用类似上面(1、2、3)中的处理方式。
  5. 针对(1,2,3,4)中的表进行分析,如果有结构相同或相似的表则可以进行合并。

场景3:

  1. 在与(场景2) 要求相同的情况下增加以下需求。
  2. 在查看教练、球员时,需要附带其所属层级(省、市、县、校)的详细信息,不仅仅是名称还需要在附加表(provicen/city/county/club)中的信息。

场景分析:

在(场景2)的方案中,从教练、球员可以得到其所属的层级,但从层级记录中无法确定其类型(省、市、县、校)。因为不同的类型对应着不同的详细信息表,所以在知道层级而不知识其类型时,是无法确定详细信息是在哪张表中存储着的。

方案一:

在system_level中添加一个level_type字段,用于记录该层级的类型,从而确定详细信息在哪一张表中。

方案二:

新增一张表system_level_meta(level_id,level_key,level_value),通过level_id和level_key='type'时的level_value值来确定层的类型,从而确定详细信息在哪一张表中。

方案比较:

  1. 方案一需要改动原设计中的表,且只能解决当前问题;方案二不影响原设计中的表,除解决当前问题外,还对以后的扩展留有可扩展的灵活性。
  2. 方案二因需要增加表而增加了系统的复杂度,方案一只是中一个字段相对来说因变更而增加的系统复杂度较小。
上一篇 下一篇

猜你喜欢

热点阅读