2009-04-29 66 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.但你不想在你的主要城市表中的所有垃圾或創建輔助子表,並必須進行連接。因此,將它放在一列中,然後根據搜索詞搜索它,但如果找到它,則返回正確的名稱。