如何为县、市和州构建 MySQL 数据库

How to structure a MySQL database for counties, cities, and states

我正在为持有当地酒精法律的律师重新设计一个数据库。这个想法是,某人可以查看他们所在的县或市,并找出他们最后一次或第一次可以在酒吧喝酒或在商店买酒的时间。我 运行 遇到的问题是法律管辖权非常复杂。问题包括:

  1. 独立的城市(没有与之关联的县, 例如马里兰州巴尔的摩)
  2. 一个城市名称可以跨越多个辖区(例如弗吉尼亚州福尔斯彻奇是一个独立的城市,还有一个弗吉尼亚州福尔斯彻奇是费尔法克斯县的一部分)
  3. 包含县的城市(New York City, NY, for 例如,包含五个不同的县)

我想使用这个简单的模式,但情况并非如此简单:

state {
  id (INT, PRIMARY KEY)
  name_short (CHAR(2))
  name_long (CHAR(14))
…}

county {
  id (INT, PRIMARY KEY)
  name (CHAR(30))
  state_id (INT, FOREIGN KEY, REQUIRED)
…}

locality {
  id (INT, PRIMARY KEY)
  name (CHAR(30))
  county_id (INT, FOREIGN KEY, CAN BE NULL)
  state_id (INT, FOREIGN KEY, REQUIRED)
...}    

hours {
  id (INT, PRIMARY KEY)
  locality_id (INT, FOREIGN KEY, CAN BE NULL)
  county_id (INT, FOREIGN KEY, CAN BE NULL)
  state_id (INT, FOREIGN KEY, REQUIRED)
  beer_and_wine_or_liquor (INT => 1=beer and wine only, 2=liquor only, 3=both)
  on_or_off_premises (INT => 1=on-premises only, 2=off-premises only, 3=both)
  start_time (INT => seconds after Sunday 12am)
  end_time (INT => seconds after Sunday 12am)
}

这个想法是查询一个城市和 return 他们当地的酒精法律。如果一个城市将他们的法律推迟到一个县,那么 hours 中将根本没有该城市的条目,然后将在县一级进行另一个查询。这可能会一直级联到州一级。这样就消除了数据冗余。如果 locality 的每个城市都将其法律推迟到县,甚至可能没有必要为每个城市都有条目。

(请注意,我将此与 Google 地图 API 一起使用,以根据地址、交叉路口或 latitude/longitude 确定一个人的城市和县(如果存在)。注意另外,邮编搜索不是一种选择,因为它们跨越司法管辖区。)

从区域 table 中取出 county_id 并创建一个查找 table,如下所示:

locality_counties {
    locality_id (INT)
    county_id (INT)
}

然后你可以用它来表示地方和县之间的1:1或1:m关系。您的查询可能如下所示:

SELECT
    h.*,
    s.name_short AS state_abbr,
    s.name_long as state_name,
    l.name AS locality_name,
    c.name AS county_name,
    c2.name AS alternate_county_name
FROM
    hours h
JOIN
    states s
    ON h.state_id = s.id
LEFT OUTER JOIN
    counties c
    ON h.county_id = c.id
LEFT OUTER JOIN
    localities l
    ON h.locality_id = l.id
LEFT OUTER JOIN
    locality_counties lc
    ON l.id = lc.locality_id
LEFT OUTER JOIN
    counties c2
    ON lc.county_id = c2.id

您会为每个县返回一条记录。而且这些记录中的每一个都将包含初始县和地区的重复信息,因此您需要善于用代码去除重复信息。