** 这里使用的PHP / MySQL **
情境:
送货公司在全国各地有许多仓库/仓库,每个仓库只覆盖选定的城市/城镇。当用户访问他们的网站时,他们可以搜索最近的/本地软件仓库。
我调查了两个选项,每个选项都在下面解释:
选项一(不起作用):
我使用纬度和经度存储每个仓库并进行简单的半径搜索。因此,当用户进入他们的城市/城镇时,我使用Google地图进行地理编码并运行半径查询以将所有仓库带到25英里内,这样做工作
但它有一个很大的缺点,一些仓库不包括选定的城镇/城市,而半径搜索没有考虑到这一点,因此即使它们不覆盖该区域,也会在结果中显示仓库/仓库。
选项二:
将城镇/城市列表存储在一个db表中,并将depot存储在另一个表中。然后有一个关系表,链接到他们覆盖的城镇/城市的仓库。用户必须输入确切的城市(此处使用的my LIKE
)名称才能返回结果,这将搜索城市表,然后执行LEFT JOIN
到depots表。
这里的缺点是关系表会迅速增长,最多可能有500万条记录,这可能会在后期出现性能问题。
选项二的数据库设计:
仓库表
- ID
- D_NAME
- D_ADDRESS
- D_POSTCODE
- D_TEL
- AND SO ON…
城市表
- ID
- NAME
关系表
- ID
- CITY_ID
- DEPOT_ID
问题:
我还有其他选择吗?
选项二,正确的方法,在性能方面是否合适?
感谢。
答案 0 :(得分:0)
我发现您描述的关系表没有问题。只要city表在搜索词(城市名称,我假设)和外键ID上有一个综合索引,那就应该完美无缺。
您不希望提供完整的通配符搜索(LIKE %ancouv%
来查找温哥华),但应将搜索限制为前缀搜索(LIKE vancou%
)。否则索引将没有用,数据库服务器必须进行全表扫描。
测试时,使用EXPLAIN SELECT ...
命令确保使用索引。此外,您应该始终使用实际数量的测试数据进行测试。如果您只有一小组测试数据,那么查询优化器可能会选择与上述数百万行不同的路径。例如,对于一个非常小的表,它可能会决定执行完全扫描而不是索引查找可能是一种更好的方法,这会让您相信索引永远不会被使用。