From 64b6f04b6ae4f118507b2021543e1a2c244c43c0 Mon Sep 17 00:00:00 2001 From: stormbroken <181250184@smail.nju.edu.cn> Date: Sat, 25 Sep 2021 20:59:00 +0800 Subject: [PATCH] update data structure --- ...02\346\254\241\347\273\223\346\236\204.md" | 156 +++++++++++++++++- 1 file changed, 155 insertions(+), 1 deletion(-) diff --git "a/2021-Database-Development/Lec6-\346\225\260\346\215\256\345\272\223\346\250\241\345\274\217\350\256\276\350\256\241\344\271\213\345\261\202\346\254\241\347\273\223\346\236\204.md" "b/2021-Database-Development/Lec6-\346\225\260\346\215\256\345\272\223\346\250\241\345\274\217\350\256\276\350\256\241\344\271\213\345\261\202\346\254\241\347\273\223\346\236\204.md" index 1e1b401..8f89f72 100644 --- "a/2021-Database-Development/Lec6-\346\225\260\346\215\256\345\272\223\346\250\241\345\274\217\350\256\276\350\256\241\344\271\213\345\261\202\346\254\241\347\273\223\346\236\204.md" +++ "b/2021-Database-Development/Lec6-\346\225\260\346\215\256\345\272\223\346\250\241\345\274\217\350\256\276\350\256\241\344\271\213\345\261\202\346\254\241\347\273\223\346\236\204.md" @@ -1,5 +1,5 @@ -Lec6-数据库模式设计之层次结构 +0.1. Lec6-数据库模式设计之层次结构 --- # 1. 处理层次结构(Hierarchical Data) @@ -104,3 +104,157 @@ where inventory.id = 'AZE087564609' ![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/6.png) +# 6. 用SQL访问树的结构 +1. 为了检查效率和性能,分别用不同模型解决如下两个问题: +2. 法国将军Dominique Vandamme指挥哪些部队,以缩排方式或简单列表的方式显示他们。注意,所有的commander字段都构建了索引 (简称Vandamme查询) +3. Scottish Highlanders的每个团各属于哪个部队(自底向上的查询)。在部队的名称.(description字段).上没有索引, 唯- -的方法是在description字段中查找"Highland" 字符串,在没有任何全文索引的情况下,这个问题简称highland问题 + 1. 注:层次结构Corp-division-brigade regiment + 2. Oracle + +## 6.1. 自顶向下查询:Vandamme 查询 + +### 6.1.1. 邻接模型 +1. `connect by < a column of the current row > = prior a column of the previous row` +2. `connect by < a column of the previous row > = prior a column of the current row` + +```sql +select lpad(description, length(description) + level) description, commander +from adjacency_ model +connect by parent_ id = prior id +start with commander = 'Général de Division Dominique Vandamme' +``` + +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/7.png) + +- 邻接矩阵:递归实现 + +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/8.png) + +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/9.png) + +- 添加排序:加粗部分完成排序(优化器会避免出现重复计算) + +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/10.png) + +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/11.png) + +- 那么MySQL呢?两个方法 + 1. 手动union + 2. 在一个查询汇总多次连接 + 3. 前提都是已知深度(人工获取) + +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/12.png) + +### 6.1.2. 物化路径模型 +1. 查询编写不困难 +2. 计算由路径导出的层次不方便 +3. 假设mp_depth()函数返回当前节点深度 + +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/13.png) + +### 6.1.3. 嵌套集合模型 +1. 很简单,某节点的后代的 left_num 和 right_num 都会在该节点的 left_num 和right_num 范围内 + +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/14.png) + +2. 缩排怎么办? + +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/15.png) + +### 6.1.4. 比较各模型下的Vandamme模型 +1. 返回40条记录,循环执行各个查询5000次,比较每秒返回的记录数 +2. 邻接模型最高:parentId +3. 物化路径模型 + 1. 计算深度:字符串相关操作效率低 + 2. 缩排:反复处理字符串效率低 +4. 嵌套集合模型: + 1. 查找子代完胜其他模型 + 2. 缩排成本太高了 + 3. 改进:每个节点都冗余存储深度,但是维护成本高:树结构不改变、不需要所有节点排序时最好。 + +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/16.png) + +## 6.2. 自底向上访问:Highland查询 +1. 在 description 字段中查找“ Highland ”字符串 +2. 必然导致完整的表扫描:无法使用索引 +3. 不同模型下 Highland 查询的差异 + +### 6.2.1. 邻接模型 +Connect by 非常容易实现:Connect by不是关系操作 + +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/17.png) + +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/18.png) + +### 6.2.2. 物化路径模型 +- 仅找出适当的记录并缩排显示算容易 + - 重复记录的问题 + - 顺序的问题 + +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/19.png) + +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/20.png) + +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/21.png) + +### 6.2.3. 嵌套集合模型 +1. 动态计算深度依旧是个问题 +2. 不要显示人造根节点 +3. 硬编码最大深度(为了缩排显示) + +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/22.png) + +### 6.2.4. 比较各种模型下的Highland查询 +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/23.png) + +由于邻接模型中会有重复语句,我们可以使用有效结果的行数来衡量 + +### 6.2.5. 一些问题 +1. 物化路径不该是KEY,即使他们有唯一性:主键最好不要经常被更新 +2. 物化路径不该暗示任何兄弟节点的排序 +3. 所选择的编码方式不需要完全中立 + +# 7. 聚合来自树的值 +- 一共有2个大部分 + - 保存叶节点的值 + - 计算某个值散布在整个树中的百分比 + +## 7.1. 对保存于叶节点的值做聚合 +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/24.png) + +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/25.png) + +## 7.2. 计算每一层的人数 + +### 7.2.1. 计算每一层的人数(邻接模型) +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/26.png) + +### 7.2.2. 计算每一层的人数(物化路径) +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/27.png) + +### 7.2.3. 不同模型的性能 +- 执行查询5000次,比较单位时间返回的记录数 + +## 7.3. 散布在各层的百分比 +1. 假设我们经营魔药。每种魔药由多种成分( ingredient )组成,处方 recipe 列出成分及百分比。处方可以共享某种“基础魔药”,以复合成分 compound ingredient )的形式表示。 +2. 百分比被分到了每一个部分中 + +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/28.png) + +3. 某一种可以选择的建模方法 + 1. Components 表为通用类型 + 2. 它有 recipes 和 basic_ingredients 两种子类型 + 3. Composition 表保存处方成分(可以是处方或基本成分及其数量) + +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/29.png) + +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/30.png) + +![](https://spricoder.oss-cn-shanghai.aliyuncs.com/2021-Database-Development/img/lec6/31.png) + +## 7.4. 树状结构的问题 +1. 本章的方法,在数据量很少的情况下效果令人满意 +2. 对大数据量的处理“像老爷车一样慢” +3. 同样可以采用非规范化模型、或基于触发器的扁平化数据模型。 +4. 不建议对关系模型“屡遭诟病的缓慢本性”反规范化,这很容易遮掩程序设计中的问题。 +5. 不过, SQL 确实缺乏处理树结构的强大的、可伸缩的手段。 \ No newline at end of file