如何在 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:1DestinationAlias 的关系(以及与Destination 的隐含1:1 关系):

CREATE TABLE DestinationDefaultAlias
( idDestination
, alias
, PRIMARY KEY (idDestination)
, FOREIGN KEY (idDestination, alias)
    REFERENCES DestinationAlias (idDestination, alias)
) 

当您想找到默认名称时,您可以将DestinationDestinationDefaultAlias 连接起来。要搜索所有别名,请加入 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 中使用别名对城市进行建模的主要内容,如果未能解决你的问题,请参考以下文章

如何在关系数据库中进行继承建模?

如何在 MySQL LEFT JOIN 中使用别名

如何在mysql函数中使用别名

我应该如何在我的神经网络中对训练集进行建模?

如何使用注意力机制对 RNN 建模以进行非文本分类?

多个用户如何在 Node.js 中使用 Gmail 别名发送电子邮件,而无需 Google 开发人员控制台对每个用户进行用户身份验证?