首页 > 数据库 >SqlServer 多叉树字典表设计最佳实践探索

SqlServer 多叉树字典表设计最佳实践探索

时间:2024-03-11 17:01:55浏览次数:31  
标签:Dictionary 多叉树 SqlServer 闭包表 FirstPlan 查询 节点 字典

目录

多叉树

在字典表设计中,常常需要存储树形结构的数据。
比如:国家、省、市、区县,公司部门信息等。
每一个节点下面的子节点数量是不确定的,这类的树我们称之为多叉树(N-ary Tree)

本文将以如何在字典表中存储省、市、区县数据为目标,探讨多叉树字典表设计最佳设计方案。

设计需求

我们设计的字典表需要满足以下需求:

a、支持查询任意层级的所有子级
b、支持查询任意层级的所有上级
c、支持分布式存储
d、数据安全,防止碰撞攻击
e、支持增、删、改、查
f、支持同级节点排序

设计思路

程序员们首先想到的是在字典表中增加ParantId列,指向该节点父级的Id。这种设计方式我们称之为“邻接表”。
但这样的设计有个弊端:满足a、b两个需求较为复杂,因为我们必须利用代码或者Sql语句实现递归。网上其他文章中还提到了路径枚举、嵌套集、闭包表等设计方案。接下来本文提供两种相对优秀的设计方案供参考。

方案一、范式设计(双表方案)

字典表+闭包表+ParantId+路径枚举

适用范围

这种设计是一种比较标准的、符合范式的设计方案。
它的适用范围是在无法确定某个节点下有多少个子节点。
如果我们无法评估整个字典表下所有节点究竟可能出现多少个子节点,这种情况下比较适用。

优点

a、支持查询任意层级的所有子级
b、支持查询任意层级的所有上级
c、支持分布式存储
d、数据安全,防止枚举攻击
e、支持增、删、改、查
f、支持同级节点排序
g、支持无限节点层级存储、节点数量没有限制

缺点

a、对程序员水平要求更高,维护字典表和闭包表代码有难度且不能有错
b、多了一张闭包表,维护闭包表数据有额外工作量和数据库开销
c、查询相对复杂,需要联表

D_Dictionary_FirstPlan字典表设计图

D_Dictionary_FirstPlan字典表模型图

D_Dictionary_FirstPlan字典表数据展示


D_Dictionary_FirstPlan_Closure闭包表设计图

D_Dictionary_FirstPlan_Closure闭包表模型图

D_Dictionary_FirstPlan_Closure闭包表介绍

闭包表存储的是D_Dictionary字典表所有上下节点之间的关系,是所有祖先节点和子节点的关系。比如父节点-子节点,祖先节点-孙子节点....

D_Dictionary_FirstPlan_Closure闭包表数据展示

查询演示

查询所有安徽省的下级

查询怀远县所有上级

方案二、反范式设计(单表方案)

字典表+Code编码+ParantId+路径枚举

适用范围

这种设计是一种极大提高查询速度和减少查询复杂度的方案。
但是这种设计有一定的前提条件,设计者必须确定字典表最多子节点数量。
如果我们明确知道整个字典表下所有节点都不超过8999个子节点,则方案二比较适用。

优点

a、支持查询任意层级的所有子级,高效,查询简单
b、支持查询任意层级的所有上级,高效,查询简单
c、支持分布式存储
d、数据安全,防止碰撞攻击
e、支持增、删、改、查
f、支持同级节点排序
g、支持无限节点层级存储、节点数量没有限制

缺点

a、每个节点最多支持8999个字节点(但可以通过拓展Code范围解决)

D_Dictionary字典表设计图

D_Dictionary字典表模型图

D_Dictionary字典表数据展示

D_Dictionary字典表Code介绍

Code从1001开始编码,最多支持到9999。
例:安徽:1002 安徽~安庆:10021001 安徽安庆迎江区:100210011001

查询演示

查询所有安徽省的下级

查询怀远县所有上级

生成Ulid的库:

https://github.com/Cysharp/Ulid
https://github.com/RobThree/NUlid

推荐:https://github.com/RobThree/NUlid

//参考代码
var rng = new MonotonicUlidRng();
Ulid.NewUlid(rng).ToString().ToLower();

Ulid作为主键遗留问题

NUlid库:

支持单机单位毫秒自增,(分布式、多线程、时间回退情况下尚未测试)
https://github.com/ulid/spec/issues/11

Ulid库:

单机和分布式都不支持单位毫秒内自增

标签:Dictionary,多叉树,SqlServer,闭包表,FirstPlan,查询,节点,字典
From: https://www.cnblogs.com/fuhua/p/18066527

相关文章

  • SqlServer常用监控查询语句
    --查询SqlServer总体的内存使用情况selecttype,sum(virtual_memory_reserved_kb)VM_Reserved,sum(virtual_memory_committed_kb)VM_Commited,sum(awe_allocated_kb)AWE_Allocated,sum(shared_memory_reserved_kb)Shared_Res......
  • SQlServer 高版本向低版本大量数据迁移
    SQlServer高版本向低版本大量数据迁移一、我的情况我们开发时数据库版本是Sqlserver2017,甲方的数据库版本是Sqlserver2014我们数据库中的数据量大约1亿条,.mdf文件有七十多GB我们数据库里存在一些外键约束和存储过程二、迁移步骤1.为整个数据库生成仅限架构的sql......
  • Dict【字典】
    定义:字典是一种映射类型,它的元素是键值对,字典的键必须为不可变类型,且不能重复;键可以是任意不可变类型(元祖/字符串/数字)推荐:字典的键推荐使用:英文字符创建字典的方式:(1)直接使用{}(2)使用dict() 字典的使用字典初始化:【1】字典的创建初始化:一个键一个值,一一对应a=......
  • SQLServer中sp_Who、sp_Who2和sp_WhoIsActive介绍和查看监视运行
    SQLServer中sp_Who、sp_Who2和sp_WhoIsActive介绍和查看监视运行使用sp_WhoIsActive监视活动sp_WhoIsActive存储过程可以监视SQLServer中当前正在运行的活动。介绍如果服务器速度变慢时,数据库管理员需要不断检查SQLServer实例上正在运行的操作。系统存储过程“s......
  • 常见的弱口令 密码字典 下载网站
    Weakpass:这是一个专门提供弱口令字典的网站,包括单词、数字、常用密码、常见手机号码等。官网地址:https://weakpass.com/SecList:这是一个安全研究者和渗透测试人员常用的资源库,其中收集了一个"Passwords"目录,包含着许多大型的字典文件,包括弱口令字典。官网地址:https://g......
  • python Ai 应用开发基础训练,字符串,字典,文件
    --------------------------------------  编程能是大模型应用的天花板..................................................................所以要好好将大模型应用在企业一定要好好练好最看不起的一环,基础能力字符串处理 本文档来自老男孩培训Alex课程记录,我在2017年......
  • python字典存入csv
     存入csvimportcsvfromconfig.globalparameterimportexecl_saveimportcsvtitle='这是一个标题'price=23.45deal=5location='广东广州'province='广东'city='广州'shop='门店'result=1#构建商品信息字典pr......
  • SqlServer:FOR XML PATH('')
    业务需求:需要将一个流程的所有节点办理人,接收时间,以每一条requestid为主,横向的排列起来展示。而OAe9里面,workflow_currentoperator表就是存节点接收人,接收时间的。 它的结构如下:一个requestid下面有很多节点数据,每个节点也可能重复,因为有办理人,抄送人。在结构上,我们需要将......
  • Navicat 无法连接Oracle / SQLserver
    报  cannotcreateocihandle cannotcreateocienviromentORA-XXXX等;排除用户名密码端口错误原因:Navicat本地的OCI版本与Oracle本地的不匹配查看Oracle本地的OCI版本,将Navicat升级至对应版本解决:下载新的oci进行替换https://www.oracle.com/database/technol......
  • sqlserver和mysql区别
    1.数据库管理系统SQLServer是由微软公司开发的关系型数据库管理系统,适用于Windows操作系统。而MySQL则是由瑞典MySQL公司开发的,后来被Oracle公司收购,适用于多个操作系统,包括Windows、Linux和UNIX。2.许可证和成本SQLServer是商业产品,需要购买许可证才能使用。它的价格相对......