`
LSQ6063
  • 浏览: 67446 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

无限层次扩展 和 查询性能 矛盾的解决

阅读更多

经典问题,刚好以前解决过,分享一下: 就是逻辑树,怎么存储的问题。

主要考虑点: 无限层次扩展 和 查询性能 矛盾的解决。

基本模式:
表:Location

 

编码 名称 父编码
CN 中国  
ZJ 浙江省 CN
HZ 杭州市 HZ
XH 滨江区 HZ
NB 宁波市 ZJ


优点: 模型简约而不简单, 支持任意层次扩展。
缺点:查询一个节点的所有子节点需要递归,效率不高。
一般解决: Oracle 中有这个语句可以解决查询问题 select * from XXX start with id=76 connect by prior parentid=id。 但是数据量大时效率有影响。
更好的解决:用好Cache。 一般这类数据都比较固定,而且量不会非常大,使用Cache,无论是程序递归查询,还是 connect by prior 语句,问题都不大。

索引表支持
如果属性结构数据量比较大或变动频繁, 应用比较关注性能,可以增加一个索引表来解决

行政区划索引表 ( Location_Index ) ( 主键:ID, PID)

编码 上线编码(非父级(PID)) 相差存次(offset)
CN    
ZJ CN 1
HZ CN 2
HZ ZJ 1
XH CN 3
XH ZJ 2
XH HZ 1


 这张索引表以扁平化结构存储任意层次两个节点间的关系。检索效率很高:
1.查询任意节点的子节点: select * from Location_Index where PID = ‘ZJ’;
2.查询任意节点的所有父节点: select * from Location_Index where ID = ‘XH’;
3.判断任意两个节点是否在同一分支上: select * from Location_Index where ID = ‘XH’ and PID = ‘CN’;

当然,高性能是以空间和处理复杂度为代价的。

a) 新增一个节点时:除了要在 Location 表中增加一条记录, 同时要在 Location_Index 表增加 若干条记录。
b) 删除一个节点是,除了要在 Location 表中增加一条记录, 同时要在 Location_Index 表删除 若干条记录。

当然,这个逻辑并不复杂。而且 Location_Index 所增加的空间也是值的的。原来的 0001.0001这样的索引可以不需要,也能节省很多空间。


总结:
1) 表结构:基本表和索引表, Location,Location_Index。
2) 特点:支持无限层次节点的树结构;
查询效率很高。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics