如何组织大型地址数据库更好?

时间:2010-04-20 14:07:25

标签: mysql database database-design

如何组织大型地址数据库?

需要创建地址的mysql数据库。如何更好地组织? 我有两个变种: 1) cuontries

id|name
1 |Russia

cities
id|name
1 |Moscow
2 |Saratov

villages
id|name

streets
id|name
1 |Lenin st.

places
id|name            |country_id|city_id|village_id|street_id|building_number|office|flat_number|room_number
1 |somebuilding    |1         |1      |NULL      |1        |31             |12a   |NULL       |NULL

为简化起见,我并非都使用地址。如果任何部分没有参与地址,则它等于NULL

2)

addressElements
id|name
1 |country
2 |city
3 |village
4 |street
5 |office
6 |flat_number
7 |room_number

addressValues
id|addressElement_id|value
1 |1                |Russia
2 |2                |Saratov
3 |2                |Moscow
4 |3                |Prostokvashino
5 |4                |Lenin st.

places
id| name
1 | somebuilding

places_has_addressValues
place_id|addressValue_id
1       |1
1       |3 
1       |5

UPD。 我决定如下制作 alt text http://notme.ru/bebe/addresses.jpg

我使用属性“type”(ENUM)来声明对象的类型。例如,公寓类型可以是“平面”或“房间”或“办公室”

4 个答案:

答案 0 :(得分:2)

我选择第一个选项的原因:

  • 简单。第一种选择是清晰明显的十几倍。想想其他人以后维护你的代码。
  • 联接。正如Vanessa所提到的那样,第二种方案写入连接会更加困难。

第一个选项的缺点可能是结构更加严格,所以你必须花一些时间来确保你有适合你的数据模型的所有可能选项(例如P.O.盒子怎么样?)。您可能想访问当地的邮局并聊天。也许http://www.russianpost.ru/会有一些有用的信息吗?

答案 1 :(得分:1)

我会说第一个去。一个地方在一个国家,一个城市(或者可能没有城市),一个村庄(或者没有村庄)等。第二个数据库可以让您灵活地在多个国家,多个街道等地方占有一席之地。因为这对地址没有任何意义,它只会增加一个不必要的复杂层,每次你想查找一个地址时都会有更多的连接。

答案 2 :(得分:1)

第二个选项将是一个性能杀手,不要这样做(EAV表在我的列表中很高,请勿用光标做到这一点)。由于您不知道特定地址有多少元素,因此查询获取地址也很困难。

你打算如何使用它?你是否真的要让人们查找每个可能的街道地址来选择合适的街道地址?为什么不简单地让他们输入地址?如果您要从GUI进行数据输入而不是批量导入,我不会使用街道表。我对城市表的感觉有点相同,它会有多少条目?尝试保留那个国家必须存在的城市很好,但输入数据时是否实用?当有人需要进入不在城市表中的城市时,你会怎么做?引用偶尔会更改名称,数据条目可能具有尚未进入城市表的较新值。

答案 3 :(得分:0)

1)乡村和城市是等价的 - 即城市或乡村,但不是两者。

2)正确规范化的数据库将具有:

table countries
  ( country_id int primary key, country_name varchar(100) );

table cities  # also villages
  ( city_id int primary key, city_country_id int, city_name varchar(200),
    city_is_village bool );

table streets
  ( street_id int primary key, street_city_id int, street_name varchar(200) );

table addresses # we'll stop normalizing here
  ( addr_id int primary key, addr_street_id int, addr_building_number int, 
    addr_office int, addr_flat_number int, addr_room_number int );

# then to get the entire address, you would join the tables

 SELECT addr_room_number, addr_flat_number, addr_office, addr_building_number, 
        street_name, city_name, city_is_village, country_name
    FROM addresses
    LEFT join streets ON street_id = addr_street_id
    LEFT join cities ON city_id = street_city_id
    LEFT join countries ON country_id = city_country_id
    ;