如何为树形关系创建数据库表
2006-07-01 12:08
267 查看
树形关系的数据例如:全国性的各个部门,商品的目录等。 特点是,数据间的关系呈树形,需求阶段无法确定结点的具体数量和树的层次到底有多少。存储这类数据不仅要体现树的结构,查询效率也要考虑,另外要考虑到树今后的扩展。
结构如图1:类别1
类别1.1
类别1.1.1
类别1.2
类别2
类别2.1
类别3
类别3.1
类别3.2
……
全国
省级1
市级1
市级2
县级1
省级2
市级1
..............
一种方法是:纪录每个节点的父结点,数据库表如:
这样构造整棵树是没有问题了,可是这样查询的效率却不高,如果需要重构整棵树,复杂度的数量级大家可以算一下。n*n ?
所以我们加入别的记录方法,回想一下数据结构中树的储存,我们可以采用编号的方法:
编号以不同的位数为单位展现节点的层次与关系。比如根节点 000000 ,以两位为 1 层次。前2位不为0,后面4位为0的代表第一层的节点,如 01 0000, 02 0000,以此类推 010100 为 010000 的第一个子节点,010101 为010100的第一个子节点。
ID 单位 父单位 编号
1 总类别 0 000000
2 类别1 1 010000
3 类别1.1 2 010100
4 类别1.2 2 010200
5 类别2 1 020000
6 类别2.1 5 020100
7 类别3 1 030000
8 类别3.1 7 030100
9 类别3.2 7 030200
10 类别1.1.1 3 010101
……
这样构造整棵树的时候 “SELECT * FROM table1 ORDER BY 编号” 树的结构出来了吧。如果要分析树的层次也不必一个一个找到根节点了,树的父结点也体现出来了。
当然父结点字段还是要保留的,这样插入,删除,或是经常有查询单位父单位的情况下,将会提高响应时间。符合“数据库设计中适当保留冗余数据的来降低程序复杂度的原则数据库设计中适当保留冗余数据的来降低程序复杂度的原则”。
这里我想多说2句,有时候保留数据的冗余是很重要的,相当于我们先把查询结果或计算结果为以后使用先保存好了,这样在使用系统时,就会节省大量时间。当然这样做唯一的缺点是浪费了硬盘空间,但是当空间不是问题,而需要重点考虑程序性能时,何去何从就显而易见了。空间换时间,还是很实用的。
言归正传,大家都知道上面的树编码,6位的话,每层次允只能许 99个节点,层次 不能大于3 层,扩充位数当然可以解决一部分问题,12位允许999个节点4层关系。且不说以后还需要扩展层次怎么办,这样对存储空间的利用率也不高。许多节点大部分位数都是0。
我的解决想法是,在增加一个“层次”字段, 值就是节点在树中的层次。编码位数不需要变,如果节点层次大于3,那么它的实际编码就是 父结点的编码+自己的编码 即可。
比如
ID 单位 父单位 编号 层次
10 类别1.1.1 3 010101 3
11 类别1.1.1.1 10 010000 4
比如 类别1.1.1.1 的实际编号是 父结点编号 010101+自己编号 010000=010101010000
这样只需要做一下判断就可以了,编号的位数都不用变。
关键是在需要判定节点层次的地方,我们又一次用空间换回了时间。
结构如图1:类别1
类别1.1
类别1.1.1
类别1.2
类别2
类别2.1
类别3
类别3.1
类别3.2
……
全国
省级1
市级1
市级2
县级1
省级2
市级1
..............
一种方法是:纪录每个节点的父结点,数据库表如:
ID | 单位 | 父单位ID |
所以我们加入别的记录方法,回想一下数据结构中树的储存,我们可以采用编号的方法:
编号以不同的位数为单位展现节点的层次与关系。比如根节点 000000 ,以两位为 1 层次。前2位不为0,后面4位为0的代表第一层的节点,如 01 0000, 02 0000,以此类推 010100 为 010000 的第一个子节点,010101 为010100的第一个子节点。
ID 单位 父单位 编号
1 总类别 0 000000
2 类别1 1 010000
3 类别1.1 2 010100
4 类别1.2 2 010200
5 类别2 1 020000
6 类别2.1 5 020100
7 类别3 1 030000
8 类别3.1 7 030100
9 类别3.2 7 030200
10 类别1.1.1 3 010101
……
这样构造整棵树的时候 “SELECT * FROM table1 ORDER BY 编号” 树的结构出来了吧。如果要分析树的层次也不必一个一个找到根节点了,树的父结点也体现出来了。
当然父结点字段还是要保留的,这样插入,删除,或是经常有查询单位父单位的情况下,将会提高响应时间。符合“数据库设计中适当保留冗余数据的来降低程序复杂度的原则数据库设计中适当保留冗余数据的来降低程序复杂度的原则”。
这里我想多说2句,有时候保留数据的冗余是很重要的,相当于我们先把查询结果或计算结果为以后使用先保存好了,这样在使用系统时,就会节省大量时间。当然这样做唯一的缺点是浪费了硬盘空间,但是当空间不是问题,而需要重点考虑程序性能时,何去何从就显而易见了。空间换时间,还是很实用的。
言归正传,大家都知道上面的树编码,6位的话,每层次允只能许 99个节点,层次 不能大于3 层,扩充位数当然可以解决一部分问题,12位允许999个节点4层关系。且不说以后还需要扩展层次怎么办,这样对存储空间的利用率也不高。许多节点大部分位数都是0。
我的解决想法是,在增加一个“层次”字段, 值就是节点在树中的层次。编码位数不需要变,如果节点层次大于3,那么它的实际编码就是 父结点的编码+自己的编码 即可。
比如
ID 单位 父单位 编号 层次
10 类别1.1.1 3 010101 3
11 类别1.1.1.1 10 010000 4
比如 类别1.1.1.1 的实际编号是 父结点编号 010101+自己编号 010000=010101010000
这样只需要做一下判断就可以了,编号的位数都不用变。
关键是在需要判定节点层次的地方,我们又一次用空间换回了时间。
相关文章推荐
- 如何从sqlserver2000恢复到sqlserver2005,能创建新的数据库关系图
- 如何从sqlserver2000恢复到sqlserver2005,能创建新的数据库关系图 (转)
- 如何从sqlserver2000恢复到sqlserver2005,能创建新的数据库关系图
- 【数据库设计-1】如何创建1对多、多对多的关系表
- android中如何读取已经在sqlite expert professional等sqlite工具设计好的数据库文件并且在程序中创建数据库
- 第十三节--如何在dos下,查看android创建的数据库和表
- 如何创建数据库快照 (Transact-SQL)
- Mysql数据库学习(1)——如何设置创建数据库和表的账户权限
- 树形数据在关系数据库的存储
- 如何创建一个简单的数据库
- jPA如何自动创建数据库表(如何将EntityBean自动映射成数据库表,而不需要先创建表再开发应用程序)
- Django如何在数据库中创建表
- 如何保证数据库结构的合理性(三、建立可靠的关系)
- 如何创建一个数据库连接池
- 如何在.cs中执行*.sql文件,来创建数据库
- 如何用VB.Net创建一个三层的数据库应用程序(转贴)
- C#中,如何在父窗体中创建子窗体?(如何确定父子窗体关系?)
- 如何在mysql中创建数据库与表
- 44、如何修改已经创建好的数据库的编码格式
- 如何在SD卡中创建数据库