2011-01-06 1 views
3

Я хочу сохранить географические данные в реляционной базе данных и иметь возможность запрашивать данные на основе их местоположения (страна, состояние или аналогичные не координаты).Каков наилучший способ хранения географической информации в отношении db?

Мое текущее решение состоит в том, чтобы иметь 4 дополнительных поля (все страны, в которых я заинтересован, имеют 2 или 3 административных подразделения) в своей таблице и фильтровать строки. Но я понимаю, что это плохое решение и хотелось бы нормализовать мой стол.

Я также буду использовать эти данные, чтобы определить, какие страницы мои пользователи хотят посетить, поэтому он должен быть простым для поиска запрос типа «/ США/Калифорния/san_fransisco/...»

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

Есть ли лучший способ сделать это?

+0

Для того чтобы быть ясным, вы также заинтересованы в хранении данных, таких как координаты GPS, границы, геометрические данные? Это может привести к решению ГИС, но похоже, что вам это не нужно ... – FrustratedWithFormsDesigner

+0

Нет, кроме географических данных, я сохраню текст в каждой строке. – UllaBulla

ответ

2

Нормализация - это, безусловно, путь. Базы данных предназначены для работы таким образом. Да, запрос может выглядеть долго, но это не так уж плохо.Это может выглядеть примерно так:

select * --or whatever fields you need 
    from Customer 
     left outer join City on (Customers.CityID = City.CityID) 
     left outer join State on (City.StateID  = State.StateID) 
     left outer join Country on (State.CountryID = Country.CountryID) 
where CustomerID = 1234 
0

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

+0

Мне нравится идея отношений между городом и государством в том, как вы описываете, но кажется, что это нужно для поиска запроса. Разве мне не нужно было бы делать запрос с тремя объединениями для каждого веб-запроса? – UllaBulla

+0

Как подделка ниже меня говорит, что это не дорогое соединение. Поиск по строкам на самом деле МНОГО медленнее, чем объединение. – John

0

Мое текущее решение состоит в том, чтобы иметь 4 дополнительных поля (все страны, в которых я заинтересован, имеют 2 или 3 административных подразделения) в своем столе и фильтровать строки. Но я понимаю, что это плохое решение и хотелось бы нормализовать мой стол.

Я не думаю, что это плохое решение. Хранение простой географической/адресной информации в строке и использование WHERE для извлечения всех записей, которые соответствуют стандартной процедуре. Использование внешнего ключа для связи с отдельной таблицей будет дополнительной работой и не будет быстрее.

Однако поиск и запрос с использованием интерфейса RESTful (как вам было предложено) являются хорошей идеей.

+0

Да, возможно, мне не стоит беспокоиться о нормализации и держать его простым. Но я все еще боюсь блокировать себя в будущем; если я решит добавить поддержку для перевода на другие языки или аналогичные. – UllaBulla

+0

Запросы с использованием UPDATE WHERE отлично справляются с этими типами случаев. Что касается вашего другого комментария ниже: –

+0

Упс, не понимает, что введенный ключ Enter, а не помещается в строку. Во всяком случае, ваш комментарий: «Не нужно было бы делать запрос с тремя объединениями для каждого веб-запроса?» является правильным при использовании нескольких таблиц, подобных этому. Просто потому, что вы можете думать реляционно и чувствовать себя «мощным», в результате не делает его лучшим решением. Используйте DESCRIBE SELECT для сравнения производительности и убедитесь сами. –

0

Идите по нормализованному маршруту. Соединение таблиц НЕ медленное или сложное. PK каждой таблицы будет целым числом с кластеризованным индексом. У внешних ключей будет указатель. Присоединение будет летать.

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

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

Если вы хотите, чтобы ультра-гибкость обрабатывалась в разных странах, вы могли бы пойти на повторную курсивную модель. В некоторых странах могут не быть штатов, округов и т. Д. У всех их есть своя иерархия.

+0

Я хотел бы иметь нормализованное решение, но я не вижу никаких простых способов сделать поиск из веб-запроса. Я действительно новичок в базах данных, поэтому мне может не хватать чего-то, но не нужно ли делать что-то подобное для запроса в нормализованном решении: «SELECT * FROM data INNER JOIN city ON data.path_key = city.key INNER JOIN state ON city.parent = state.key INNER JOIN страна ON state.parent = country.key WHERE data.name = 'city_park' AND city.name = 'san_fransisco' AND state.name = 'california' AND country.name = 'usa '"(Извините за длинный запрос) – UllaBulla

+0

Не называйте таблицу« данные ». Имя должно описывать данные. Вот как я смогу его моделировать. С кластеризованными индексами на столбцах PK, регулярными индексами на FK. Страна --------- idCountry INT PK CountryName VARCHAR (60) уникальное ограничение на COUNTRYNAME государственный --------- idState INT PK idCountry INT FK StateName VARCHAR (60) уникальное ограничение на комбо idCountry/StateName Город --------- idCity INT PK idState INT FK CityName VARCHAR (60) уникальное ограничение на комбо idState/CityName PointOfInterest --------- idPOI INT ПК idCity INT FK POIName VARCHAR (60) уникальное ограничение на комбинированном idCity/POIName – Fake

Смежные вопросы