Имеют 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
Это, например, всегда будет возвращать название города, даже если учреждение было привязано к определенному району в городе