Нормализация базы данных с пользовательским вводом - PullRequest
2 голосов
/ 15 сентября 2011

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

Проблема в том, что город изанятие каждого пользователя берется из поля ввода, что означает, что пользователи могут вводить «NYC» или «New York» или «New York City» и миллионы других комбинаций для каждого города, например.

Является ли этоХорошая идея - игнорировать эту проблему, создайте собственную таблицу "town", содержащую все города, добавленные пользователями, а затем вставьте идентификатор записи города в таблицу user, или было бы более целесообразно использовать столбец VARCHAR "town" впользовательская таблица и не нормализует базу данных относительно этого отношения?Я хочу отобразить данные из трех таблиц на страницах профиля пользователя.

Я обеспокоен нормализацией, потому что не хочу иметь слишком много избыточных данных в моей базе данных, потому что она занимает много места изапросы будут медленнее, если я использую индекс varchar вместо целочисленного индекса, например (насколько я знаю):

Спасибо

Ответы [ 3 ]

3 голосов
/ 16 сентября 2011

У нас была эта проблема. Наше решение состояло в том, чтобы собрать различные синонимы и опечатки, содержащие версии, которые люди используют, и явно сопоставить их с известным каноническим названием города. Это позволило правильно угадать имя из пользовательского ввода в 99% случаев.

Для оставшихся 1% мы создали новую запись о городе и отметили ее как неканоническую. Периодически мы просматривали неканонические записи. Для узнаваемых известных городов мы переназначили неканоническую запись в каноническую (обновив FK связанных записей и добавив синоним). Для действительно нового названия города, о котором мы не знали, мы сохранили созданную запись как каноническую.

Итак, у нас было что-то вроде этого:

 table city(
   id integer primary key,
   name varchar not null, -- the canonical name
   ...
 );

 table city_synonym(
   name varchar primary key, -- we want unique index
   city_id integer foreign key references(city.id)
 );
0 голосов
/ 15 сентября 2011

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

@ Предложение Варелы о «псевдониме» для города, вероятно, хорошо сработало бы в этой ситуации.Но вы должны вернуть сообщение в духе «Вы ввели« Теперь Йерк ». Возможно, вы имели в виду« Нью-Йорк »?».На самом деле, вы хотите получать такие исправления независимо от ...

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

State:
Id   State
============
AL   Alabama
NY   New York

City:
Id   State_Id   City
========================
1    NY         New York 
2    NY         Buffalo

Zip_Code:
Id  Code         City_Id
=========================
1   00001-0001   1

А затем сохраните ссылку на Zip_Code.Id всякий раз, когда у вас есть адрес.Вы хотите точно знать , почтовый индекс которого пользователь (как утверждается) является участником.Причины включают:

  1. Налоги для розничной торговли (независимо от того, как действует Amazon).
  2. Адреса для доставки (например, в Вашингтоне и Нью-Йорке есть Bellevue. Почтовые индексы).разные).
  3. Социальное картирование.Если вы сохраните его как города с «пользовательским вводом», вы не сможете (легко) проанализировать данные, чтобы выяснить, например, какие пользователи живут рядом друг с другом, а тем более в одном городе.

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

0 голосов
/ 15 сентября 2011

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

Нет хорошего решения для группировки городов без создания отдельной таблицы, в которой вы будете хранить все названия для каждого города в пределах одного идентификатора. Поэтому будет хорошо иметь 3 таблицы: user (user_id, city_id), city (city_id, правильное имя), city_alias (alias_id, city_id, name).

...