关于桌子设计的问题

时间:2009-04-29 16:58:32

标签: database-design full-text-search

我正在为我的用户提供搜索选项。他们可以搜索城市名称。问题是我存储的城市名称是“圣路易斯”之类的东西。但即使用户输入“圣路易斯”或“圣路易斯”,我也希望找到圣路易斯。有关如何创建查找表的任何建议,以某种方式考虑到这一点?

8 个答案:

答案 0 :(得分: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');

答案 1 :(得分:3)

我要做的是,构建一个简写到普通的表,将任何含糊不清的单词映射到您将在主表中使用的单个一致拼写。您可以包含常见的拼写错误和拼写错误。

在查找用户的请求之前,请使用此表将所有单词转换为普通表单。

所以在shorthand-to-normal表格的情况下我们会有

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

答案 2 :(得分:1)

您可能希望查看功能更全面的全文搜索引擎,例如Apache Lucene/SolrSphinx - 它可以原生支持这种字符串映射。

答案 3 :(得分:1)

我看到了许多可能的方法来解决这个问题。一种是匹配英语字符串相似性的soundex查找算法。此外,在PostgreSQL等一些数据库中本地支持此功能。

另一种方法可能只是为用户提供自动完成的功能,因为他们会输入一些建议。这样,用户就可以直观地选择所需的查找城市名称。

答案 4 :(得分:1)

作为一般方法,您可以在插入和搜索时对项目进行标准化。

规范化规则可以是:

Saint => St
St. => St

然后,规范化名称应匹配。

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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

另一个想法是为用户提供更新的城市标记列。

纽约市是正式名称。

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

答案 7 :(得分:0)

您可以为同义词条目使用内置的SQL FTS属性。这允许您在全文搜索中添加自定义单词映射。这样你就可以将所有内容保存在FTS中,而不是混合使用FTS和其他查询。

不确定您在2005/8之间使用哪个版本的SQL作为其差异,因此2005/8版本有一个很好的演练http://arcanecode.com/2008/05/28/creating-custom-thesaurus-entries-in-sql-server-2005-and-2008-full-text-search/