类目中城市,省份可多选情况下数据库设计

需求背景:

在很多场景中常见的情况:选择一些城市,城市是多选,省份是多选,且城市和省份是有层级关系。主要需求是,当选择一个城市范围,获取与该范围有交集的所有返回对象。

例子:选择江苏,得查询数据库总江苏-(南京、扬州)、江苏、江苏-(南京)等。

这个需求中层级只有两层、存在一对多的关系、需要根据ID去查询一棵树。

解决方案:

在sql反模式书中概括了常用解决该方案方法解决:

参考:http://www.cnblogs.com/kissdodog/p/3297894.html

https://www.cnblogs.com/mfrank/p/7992709.html

根据上述需求叙述,该几张方案都可以实现,但相对来说邻接表相对较容易:

数据库表设计:

CREATE TABLE `tree` (
  `id` int(11) unsigned NOT NULL COMMENT 'id',
  `text` varchar(11) DEFAULT NULL COMMENT '地址信息',
  `textId` int(11) DEFAULT NULL COMMENT '地址Id',
  `parentId` int(11) DEFAULT NULL COMMENT '父ID',
  `levels` int(11) DEFAULT NULL COMMENT '国家为1,省份2,城市为3',
  `class` int(11) DEFAULT NULL COMMENT '分类',
  `haveChildren` tinyint(1) DEFAULT NULL COMMENT '是否有子节点',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

简单创建数据:

1.存储的话按照树的层次遍历存储。

2.业务查询时注意带入地址层级:

1输入国内查询

sql:select class from tree where textId = 1 

分别查询1和2和3的类别

结果为:国内、国内-北京、国内-江苏-(南京、扬州)

输入查询:国内-江苏

查询:level 为2 为江苏的 ,level 为1 的国内,且没有孩子的时候

select * from tree join (select class from tree where (levels = 2 and textId = 3) or (levels = 1 and textId = 1 and haveChildren = 0)) as pp on pp.class = tree.class

输入查询为:国内-江苏-南京

转化为:国内,国内-江苏,国内-江苏-南京

select * from tree join
 (select class from tree where (levels = 2 and textId = 3 and haveChildren = 0) 
 or (levels = 1 and textId = 1 and haveChildren = 0)
 or (levels = 3 and textId = 4)
 ) as pp 
 on
 pp.class = tree.class

结果为:

本次解决方案的实现中的解决方案中有一个限制条件:

树的层次不高,所以可以增加一个havechildren来判断是否有孩子。

总结:本次解决方案的实行,主要是为了解决地址类目查询问题,当层级比较深时,这种做法基本很难实现。在不同业务场景中,尽量选择相对简单满足需求的方法解决。缺陷在于无法很快的判断量层级之间的关系。本文实现的方法适用于层级较低的情况。由于本人用的数据库是mysql,在递归查询没有sqlServer方便,所以一般尽量避免递归查询。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值