Ниже я изложил схему базы данных, которую я использовал бы на основе информации, которую вы указали.
Каждый город относится к одному государству.
cities
id unsigned int(P)
state_id unsigned int(F states.id)
name varchar(50)
+----+----------+---------------+
| id | state_id | name |
+----+----------+---------------+
| 1 | 33 | New York City |
| .. | ........ | ............. |
+----+----------+---------------+
См. ISO 3166 для получения дополнительной информации. Вы не просили страны, но их тривиально добавить ...
countries
id char(2)(P)
iso3 char(3)(U)
iso_num char(3)(U)
name varchar(45)(U)
+----+------+---------+---------------+
| id | iso3 | iso_num | name |
+----+------+---------+---------------+
| ca | can | 124 | Canada |
| mx | mex | 484 | Mexico |
| us | usa | 840 | United States |
| .. | .... | ....... | ............. |
+----+------+---------+---------------+
Каждый район относится к одному городу.
districts
id unsigned int(P)
city_id unsigned int(F cities.id)
name varchar(50)
+----+---------+-----------+
| id | city_id | name |
+----+---------+-----------+
| 1 | 1 | The Bronx |
| 2 | 1 | Brooklyn |
| 3 | 1 | Manhattan |
| .. | ....... | ......... |
+----+---------+-----------+
Для получения дополнительной информации см. ISO 3166-2:US.Каждое государство принадлежит к одной стране.
states
id unsigned int(P)
country_id char(2)(F countries.id)
code char(2)
name varchar(50)
+----+------------+------+----------+
| id | country_id | code | name |
+----+------------+------+----------+
| 1 | us | AL | Alabama |
| .. | .......... | .... | ........ |
| 33 | us | NY | New York |
| .. | .......... | .... | ........ |
+----+------------+------+----------+
На основании вашей информации пользователь принадлежит к одному городу. В примере данные Боб ассоциируется с Нью-Йорком. Присоединившись к столам, вы можете легко найти, что Боб находится в штате Нью-Йорк и в стране Соединенных Штатов.
users
id unsigned int(P)
username varchar(255)
city_id unsigned int(F cities.id)
...
+----+----------+---------+-----+
| id | username | city_id | ... |
+----+----------+---------+-----+
| 1 | bob | 1 | ... |
| .. | ........ | ....... | ... |
+----+----------+---------+-----+
Пользователи могут принадлежать любому числу районов. В примере данные Боб принадлежит Бронксу и Бруклину. user_id
и district_id
образуют первичный ключ, который гарантирует, что пользователь не может быть связан с одним и тем же округом более одного раза.
users_districts
user_id unsigned int(F users.id) \_(P)
district_id unsigned int(F districts.id)/
+---------+-------------+
| user_id | district_id |
+---------+-------------+
| 1 | 1 |
| 1 | 2 |
| ....... | ........... |
+---------+-------------+
Моя модель базы данных не устанавливает правило, согласно которому районы пользователя принадлежит должен быть в городе, который принадлежит пользователю - на моем взгляде, что логика должна быть сделана на уровне приложений. Если Боб переезжает из Нью-Йорка в Балтимор, я думаю, что все его записи должны быть удалены из таблицы users_districts
, а затем добавить новые для своего нового города.
Что касается пользовательского интерфейса, я бы пользователя:
- Выберите страну - это будет автоматически заполнить выпадающий список связанных состояний.
- Выберите состояние - это автоматически заполнит выпадающий список связанных городов.
- Выберите город - это автоматически заполнит список связанных районов.
- Позвольте пользователю выбрать любое количество районов.