2009-04-29 65 views
7

我为我的用户提供了一个搜索选项。他们可以搜索城市名称。问题是我存储的城市名称是“圣路易斯”。但即使用户输入“圣路易斯”或“圣路易斯”,我也希望找到圣路易斯。有关如何创建查找表来对此进行考虑的任何建议?表格设计问题

+1

一个很好的演练? – Jeremy 2009-04-29 17:08:12

+0

对不起 - 从.Net的SQL Server - 这是一个web服务,所以查询传递给我,我不会从用户收集它。 – 2009-04-29 17:57:09

回答

5

创建两个表。

一个包含了一个城市的一切。

其中一个包含一堆城市名称,以及一个外键关联这些naes与第一个表的id。所以你在city和city_names之间有一对多的关系。

现在唯一的问题是区分每个城市的名称,这是首选名称。我们可以通过以下几种方法来实现:1)第一个表可以有一个fk到第二个表,该表保存到首选名称的id。但是,这会产生循环依赖。所以更好,2)只需将一个布尔/位列添加到第二个表is_preffered。

create table city (id not null primary key, other columns) ; 

create table city_name (
id not null primary key, 
city_id int references city(id), 
name varchar(80), 
is_preferred bool 
) ; 

然后让所有的名字,与优选的名头:

select name from city_names where city_id = ? 
    order by is_preffered desc, name; 

这有一个额外的好处:如果你不覆盖所有城市和城镇,你可以使用第二个表地图城镇/农村/县您不包括全国各大城市这样做:

insert into city_name(city_id, name) values 
($id-for-New-York-City, 'New York'), 
($id-for-New-York-City, 'Manhattan'), 
($id-for-New-York-City, 'Big Apple'), 
($id-for-New-York-City, 'Brooklyn'); 
+0

我不明白为什么我需要一个“首选”的名字 - 我的意思是,如果他们在纽约打字,我会马上匹配。如果他们键入曼哈顿,并且它连接纽约,那么为什么我会关心首选城市ID? – 2009-04-29 17:46:59

+0

你可能不会;在这种情况下,请不要使用它。我一直在想办法不把名字放进城市,在这种情况下,我们希望能够在报告中显示“规范”名称。 – tpdi 2009-04-29 18:01:08

+0

我与这个答案一起去了,它的作用像一个魅力到目前为止。我的查询使用别名表进行外部连接,where子句具有“WHERE(venue.city ='st louis'OR alias.city_slang ='st louis')”,我加入cityname = city_canonical的表格。这些列很快就会改变名称。 – 2009-04-29 20:18:49

1

您可能想要查看更全面的全文本搜索引擎,例如Apache Lucene/SolrSphinx - 它可以本机支持这种类型的字符串映射。

1

我看到了一些处理这个问题的可能方法。一种是soundex查找算法,其匹配英文字符串的相似性。此外,这在一些数据库中本地支持,如PostgreSQL

另一种方法可能仅仅是为您的用户提供自动完成功能,因为他们输入了许多建议。这样用户将直观地选择所需的查找城市名称。

3

我会做的是,建立一个速记到普通表,这将任何歧义词映射到一个一致拼写你会在主表中使用。您可以包含常见的拼写错误和拼写错误。

在查看用户请求之前,使用此表将所有单词转换为标准格式。

所以在shorthand-to-normal表的情况下,我们将有

______________ 
| short|normal | 
|______|_______| 
|St |Saint | 
|St. |Saint | 
1

作为一般的方法,您可以正常化的项目都将和搜索时,他们的时候。

规范化规则可能是:

Saint => St 
St. => St 

标准化的名称应该然后匹配。

0

恕我直言,我会离开数据库,而是在你的应用程序中有一个下拉列表的城市。更简单,更清洁,并且不需要太多额外。

0

我喜欢第一个答案中的选项。

另一个想法是为用户coudl更新该城市的标签列。

纽约市是正式名称。

这座城市的标签可能是可以计算的(曼哈顿,纽约,纽约市,大苹果..)e.t.c.但你不想在你的主要城市表中的所有垃圾或创建辅助子表,并必须进行连接。因此,将它放在一列中,然后根据搜索词搜索它,但如果找到它,则返回正确的名称。