如何在 MySQL 中使用别名对城市进行建模
Posted
技术标签:
【中文标题】如何在 MySQL 中使用别名对城市进行建模【英文标题】:How to model cities with aliases in MySQL 【发布时间】:2012-02-29 15:18:46 【问题描述】:一个给定的位置(城市),可以有一个名字和其他可以知道它的别名。我需要在数据库中对此进行建模。
可以使用城市或其任何别名执行搜索:
例如
城市:
名称:洛杉矶 别名:LA指定搜索条件时,我可以指定 LA 或 Los Angeles,它应该返回相同的结果(例如好莱坞)。
我正在考虑使用一对多关系来实现,其中 1 个城市可以有多个别名,并且许多别名可以映射到一个城市。
在进行搜索时,我使用 city 和 cityAlias 表的连接来查找正确的城市。
有没有更好的方法来解决这个问题?
编辑: (对于遇到相同问题/要求并碰巧来到此页面的任何人) 请同时查看我的答案,因为我最终使用了它,但标记的答案可以帮助您识别独特的城市。
【问题讨论】:
我认为你的方向是正确的,禁止我不熟悉的任何 SQL 技巧。我会按照你建议的方式做的。 我知道我在 5 年多之后才开始这样做:) 但是你是如何处理删除的(如果它是一个有效的用例)?即删除城市与删除别名。您是否在应用程序代码中处理过这个问题? (我也有类似案例) 【参考方案1】:我可以添加到您的解决方案中的唯一一件事是,您可以尝试首先在城市表中查找完全匹配的内容,如果没有,然后加入别名。这样你可能会跳过一些非常昂贵的连接。
另外需要注意的是,这种双表解决方案可能会遇到重复条目的问题。我不是在谈论不同城市的相同别名(可以使用唯一列检查),而是与城市名称匹配的别名。这些“重复条目”的示例后跟详细说明:
城市
ID | Name
---------
1 | Los Angeles
2 | New York
别名
ID | CityId | Name
------------------
1 | 1 | LA
2 | 2 | NY
3 | 2 | Los Angeles
我知道这不应该发生......但你知道摩尔定律 :) 这些跨表重复可能会给你在查找表中带来麻烦(我想你正在使用它们作为查找来“猜测”什么当他/她写“LA”时,City实际上已经尝试选择用户)。但是如果用户写了“洛杉矶”,你就必须决定是优先考虑城市还是别名。我知道我提供的示例有点愚蠢,但作为非美国公民,我无法提供更好的示例。但是那里有很多城市,每个城市都有很多别名......我不会冒险:)
首先检查城市表将使城市优先于其他城市的同等命名别名。或者,您可以在插入之前检查城市的别名是否已经作为城市名称存在。
我能想到的就这么多:)
【讨论】:
感谢您的洞察力。我不明白trouble with duplicated entries
的意思。你能详细说明一下吗?
我添加了关于这些重复条目的详细说明。希望有帮助
谢谢,有帮助。我正在和其他人讨论这个问题,另一个事情来解决你所说的。在添加城市的时候,也在别名表中创建一个具有相同cityName的别名。这样,只需要在别名表中进行搜索。至于重复的条目,我想我会把这两个选项都给用户,让他们选择使用哪一个。
另外,请参阅我的回答,强调重复条目。【参考方案2】:
一些注意事项:
DestinationAlias
表不需要代理键。 (idDestination, alias)
(或相反)可以用作PRIMARY KEY
。
要消除两个表中(通用)名称的重复以及可能出现的问题,您可以从Destination
表中删除name
列并添加一个DestinationDefaultAlias
表,具有1:1
与DestinationAlias
的关系(以及与Destination
的隐含1:1
关系):
CREATE TABLE DestinationDefaultAlias
( idDestination
, alias
, PRIMARY KEY (idDestination)
, FOREIGN KEY (idDestination, alias)
REFERENCES DestinationAlias (idDestination, alias)
)
当您想找到默认名称时,您可以将Destination
与DestinationDefaultAlias
连接起来。要搜索所有别名,请加入 DestinationAlias
。
【讨论】:
我已将您的答案与其他答案结合起来,并提出了解决方案。你怎么看?【参考方案3】:假设:
La Aguardia 是一个随机的城市名称 LA 是 La Aguardia 的别名洛杉矶是纽约的别名
对于添加的每个城市,将城市名称本身作为条目添加到别名表中,因此我们只需在别名表上进行搜索。
城市表:
cityId | Name
1 | Los Angeles
2 | New York
3 | La Aguardia
别名表:
cityId | AliasName
1 | Los Angeles
1 | LA
2 | New York
2 | NY
2 | Los Angeles
3 | La Aguardia
3 | LA
用例 1:
搜索 LA:yield (cityID) => [1, 3] =unique> [Los Angeles, La Aguardia]
用例 2:
搜索洛杉矶:收益率 (cityID) => [1, 2] =unique> [洛杉矶,纽约]
用例 3:
搜索纽约:收益率 (cityID) => [2,2] =unique> [纽约]
【讨论】:
这闻起来像一个建议框 :) 所以你实际上允许重复显示给用户。如果是这样的话,那就太好了。我的解决方案实际上旨在通过以下方式不允许重复结果:在别名上应用唯一索引并首先在城市表中查找(例如,如果查找“洛杉矶”,城市表将首先匹配)。现在,如果您被允许返回多个结果,请继续执行此结果,但请确保您为表中的每个城市都有一个别名,并在添加新城市时记住这一点:) 我不是专门为建议框开发这个,但是是的,我认为它也将用于该功能:) 至于重复,我考虑过你所说的,(特别是使用case1 here),并认为最好让用户选择他想要的。稍后,如果我必须为给定别名确定一个唯一城市,我想我一定会将我的查询编辑为你所说的。以上是关于如何在 MySQL 中使用别名对城市进行建模的主要内容,如果未能解决你的问题,请参考以下文章
多个用户如何在 Node.js 中使用 Gmail 别名发送电子邮件,而无需 Google 开发人员控制台对每个用户进行用户身份验证?