Связать 3 таблицы в 2 разных случаях в MySQL - PullRequest
1 голос
/ 17 февраля 2012

Я не нашел решения этой проблемы, поэтому хочу спросить вас.

Все дело в том, что у меня есть 3 таблицы: города, районы, учреждения.Округа имеют отношения с городами

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

PS Районы и города должны оставаться связанными

Ответы [ 3 ]

2 голосов
/ 17 февраля 2012

Имеют 2 таблицы: «Учреждения» и «Области»

Разрешить «Областям» ссылаться на себя, т.е. area_id, parent_area_id

Таким образом, вы всегда связываете Учреждение с area_id, итогда внутренняя логика может определить, считается ли эта область Районом или Городом.

Таким образом, теперь у вас есть

institutions (
    id UNSIGNED INT NOT NULL PK AI,
    area_id UNSIGNED INT NOT NULL,
    name VARCHAR NOT NULL
)

и

areas (
    id UNSIGNED INT NOT NULL PK AI,
    parent_area_id UNSIGNED INT NOT NULL DEFAULT 0,
    name VARCHAR NOT NULL,
    type ENUM('city','district') NOT NULL DEFAULT 'city' 
)

Области.поле type является необязательным, но если вы хотите определить их как таковые, то это может быть способом сделать это в базе данных (иначе просто предположите, что если parent_area_id = 0, то это город, иначе это район)

Таким образом, при выборе поля все, что вы делаете, это:

SELECT *
FROM institutions
INNER JOIN areas
ON areas.id = institutions.area_id

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

SELECT
    i.*,
    COALESCE(a_parent.id,a_child.id) AS city_id,
    COALESCE(a_parent.name,a_child.name) AS city_name
FROM institutions AS i
INNER JOIN areas AS a_child
ON a_child.id = i.area_id
LEFT JOIN areas AS a_parent
ON a_parent.id = a_child.parent_area_id 

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

2 голосов
/ 17 февраля 2012

Этот шаблон называется полиморфными ассоциациями, и его нелегко решить с помощью SQL.

uid // common id table with globally unique ids
  id int AUTO_INCREMENT

city
  id UNIQUE FK:uid.id

district
  id UNIQUE FK:uid.id
  city_id FK:city.id

institution
  location_id FK:uid.id 

fruits
  id UNIQUE FK:uid.id

FK означает внешний ключ.Вы должны вручную проверить, что institution.location_id указывает на район или город, а не на фрукт или что-то еще.

2 голосов
/ 17 февраля 2012

Существует грязный , повторите грязный способ сделать это: у учреждения есть поле идентификатора типа SIGNED INT, с отрицательными числами, указывающими на идентификатор города и положительные числа, указывающие на район. Это делает для простых объединений по запросу.

Опять же: это грязно , я рекомендую вам полностью избегать ситуации (например, создав таблицу деревьев и районов с родительским полем), но если вы не можете изменить свою модель, это работает.

...