我的省市区三级联动下拉选择器的思路或者说一些相关的碎碎念。
在数据库课设中遇到了制作省市区三级联动下拉选择器的需求,因为是数据库课设,最开始就想到了用数据库的方法来实现,所以首先就把所有省市区三级地址信息在数据库中都以六位行政区划代码的形式来存储的。因为不是主要需求,把联动选择器放在了最后去做。
而我的行政区划代码与名字的对应是以这样的形式放在数据库中的:
code | name |
---|---|
110000 | 北京市 |
110101 | 东城区 |
110102 | 西城区 |
110105 | 朝阳区 |
… | … |
我们知道,行政区划代码具有这样的特点,即前两位可唯一确定省级行政区,前四位可唯一确定地级行政区(这里把“市辖区”“省辖县”等视作虚拟存在的地级行政区)。例如,130200为唐山市的行政区划代码,由13就知道其属于河北省;320321为丰县的行政区划代码,由32就知道其属于江苏省,再由03就进一步知道其属于徐州市。
code | name |
---|---|
… | … |
130000 | 河北省 |
130100 | 石家庄市 |
… | … |
130200 | 唐山市 |
… | … |
320000 | 江苏省 |
320100 | 南京市 |
… | … |
320300 | 徐州市 |
320302 | 鼓楼区 |
… | … |
320321 | 丰县 |
… | … |
本着不加入冗余信息的原则,我没有加两列外键指示所属的省、市之类的,打算全部交给数据库以外的层面去判断,确实数据库轻巧了,给自己挖的坑也多了。
三级选择器中,省份的列表是不会发生变化的,而市区两级都需要动态更新,JavaScript不可避,而且还不能直接写,还得用PHP给echo出来。
我开始好蠢地用了一些循环写,网页给我卡了几十秒才加载出来。数一数,我好像用了数量级达到1012次的SELECT语句……甚至,我还在用剪枝的思路跳过十的几次方次查询……
总之就是被自己蠢哭了!发现不对劲了就开始全部推倒重构,最终还是只想出了先SELECT *全部存起来再给JavaScript调用的办法。至少秒加载而且功能能用了。
好消息!我写的很蠢的代码已在MIT许可证下公开了!真的有人会用吗
我写的这个选择器一些特殊操作的处理是这样的:虚拟地级行政区直接在地市选择器中出现供选择,不设县的地级行政区下只出现与上级同名的一个虚拟县级行政区。这些都是在数据库层面上操作的。
然后我有一个把读出来的行政区划代码转换成人看的区划名的函数它是这样写的,上面仓库里没放,这个是还没开始设计选择器时就写好了的:
|
|
该函数避免了展示地名时出现不必要的文字。
|
|