Имеется три таблицы:
City
+----+--------+-----------+------------+
| id | name | region_id | country_id |
+----+--------+-----------+------------+
| 1 | Город1 | 2 | 1 |
+----+--------+-----------+------------+
| 2 | Город2 | 1 | 1 |
+----+--------+-----------+------------+
| 3 | Город3 | 3 | 2 |
+----+--------+-----------+------------+
Region
+----+----------+------------+
| id | name | country_id |
+----+----------+------------+
| 1 | Регион1 | 1 |
+----+----------+------------+
| 2 | Регион2 | 1 |
+----+----------+------------+
| 3 | Регион3 | 3 |
+----+----------+------------+
Country
+----+---------+
| id | name |
+----+---------+
| 1 | Страна1 |
+----+---------+
| 2 | Страна2 |
+----+---------+
В описанной архитектуре поле country_id избыточно — как в самом городе, так и в регионе города, порождает потенциальные коллизии, когда город1 принадлежит стране1 и находится в регионе1, принадлежащем стране2. Можно было бы удалить country_id в таблице city и брать его из привязанной таблицы Region, но не каждый город имеет регион. Что будет лучшим решением описанной проблемы, как уйти от потенциальных коллизий и избыточности информации?
Если мы работаем с древовидной структурой переменной длины, то единственный способ - хранить все данные в одной таблице с полем, указывающим тип и ссылкой на родителя.
В вашем ограниченном примере, конечно, можно сделать добавить ограничение, чтобы в таблице city из двух полей (region_id, country_id) всегда было заполнено строго одно.
Но в России бывают ситуации когда город иерархически находится внутри другого города.
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости