Вопрос по оформлению стола - PullRequest
7 голосов
/ 29 апреля 2009

Я предлагаю опцию поиска для моих пользователей. Они могут искать по названию города. Проблема в том, что названия моего города, которые я сохранил, - это что-то вроде «Сент-Луис». Но я хочу найти Сент-Луиса, даже если пользователь наберет «Сент-Луис» или «Сент-Луис». Любые предложения о том, как я мог бы создать справочную таблицу, чтобы как-то это учитывать?

Ответы [ 8 ]

5 голосов
/ 29 апреля 2009

Создать две таблицы.

Один содержит все о городе.

В одном содержится набор названий городов, а внешний ключ связывает эти имена с идентификатором первой таблицы. Таким образом, у вас есть отношения один ко многим между city и name_names.

Теперь единственной проблемой является выделение одного названия для каждого города, которое является предпочтительным именем. Мы можем сделать это несколькими способами: 1) первая таблица может иметь fk для второй таблицы, которая содержит идентификатор предпочтительного имени. Это создает круговую зависимость, хотя. Так что лучше 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');
3 голосов
/ 29 апреля 2009

То, что я хотел бы сделать, это создать сокращенную таблицу, чтобы сопоставить любое неоднозначное слово с единым непротиворечивым написанием, которое вы будете использовать в своей основной таблице. Вы можете включить туда типичные орфографические ошибки и опечатки.

Прежде чем искать запрос пользователя, преобразуйте все слова в обычную форму, используя эту таблицу.

Так что в вашем случае в таблице shorthand-to-normal у нас будет

 ______________
| short|normal |
|______|_______|
|St    |Saint  |
|St.   |Saint  |
1 голос
/ 29 апреля 2009

Как правило, вы можете нормализовать элементы как при вставке, так и при поиске.

Правила нормализации могут быть:

Saint => St
St. => St

и т.д.

Нормализованные имена должны совпадать.

1 голос
/ 29 апреля 2009

Я вижу несколько возможных способов справиться с этим. Одним из них является алгоритм поиска soundex , который соответствует сходству английских строк. Кроме того, это поддерживается изначально в некоторых базах данных, таких как PostgreSQL .

Другим подходом может быть просто предложить вашим пользователям функцию автозаполнения, когда по мере ввода появляется ряд предложений. Таким образом, пользователи будут интуитивно выбирать название города для поиска.

1 голос
/ 29 апреля 2009

Возможно, вы захотите взглянуть на более полнофункциональную систему полнотекстового поиска, такую ​​как Apache Lucene / Solr или Sphinx - которая может изначально поддерживать такой тип сопоставления строк.

0 голосов
/ 29 апреля 2009

Вы можете использовать встроенные свойства SQL FTS для записей тезауруса. Это позволяет вам составить пользовательскую карту слов внутри полнотекстового поиска. Таким образом, вы можете хранить все внутри FTS, а не смешивать FTS и другие запросы.

Не уверен, какую версию SQL вы используете в качестве отличия между 2005/8, поэтому здесь есть хороший обзор для 2005/8 http://arcanecode.com/2008/05/28/creating-custom-thesaurus-entries-in-sql-server-2005-and-2008-full-text-search/

0 голосов
/ 29 апреля 2009

Мне нравится опция в первом ответе.

Еще одной идеей было бы иметь столбец для тегов для этого города, который пользователи могут обновлять.

т.е.

Нью-Йорк - официальное название.

Теги для этого города были бы исчисляемыми (Манхэттен, Нью-Йорк, Нью-Йорк, город, большое яблоко ..) e.t.c. но вы не захотите, чтобы весь этот мусор был в вашей главной таблице Cities или создавал связанные дочерние таблицы и должен был делать соединения. Так что просто поместите его в столбцы и выполните поиск по критерию поиска, а затем верните правильное имя, если оно найдено.

0 голосов
/ 29 апреля 2009

ИМХО, я бы оставил базу данных в покое и вместо этого имел бы список спадающих городов в вашем приложении. Проще, чище и не требует много лишних.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...