1

我想知道这是一个好的设计,假设表格如下

ADDRESS(id, address, city_fk, stateFK, countryFK),
CITY(id, name, stateFK, countryFK),
STATE(id, name, countryFK),
COUNTRY(id, name)

请注意国家 fk 如何在 3 个表格中重复?并在 2 个表中重复状态 fk?谁能告诉我这是不是一个好的设计?如果是这样,为什么?因为我不认为有必要经常重复它。

干杯

4

8 回答 8

4

你想要更像这样的东西:

  • 地址(id,地址,city_fk)
  • 城市(id,名称,state_fk)
  • 状态(id,名称,country_fk)
  • 国家(身份证,姓名)

如果是我,我会稍微重命名这些字段:

  • 地址(id,地址,city_id)
  • 城市(id,城市,state_id)
  • STATE(id, state, country_id)
  • 国家(身份证,国家)
于 2009-04-09T00:51:13.523 回答
1

我不确定我会沿着这条路走下去。我可以理解有一个国家表,当然还有一个州表,但是一个城市表可以确保该城市属于所讨论的特定国家/州。我只是想像您的 City FK 表中所需的数据量将是巨大的,我不确定我是否看到了好处。也许如果你能详细说明你希望从拥有一张城市表中获得什么好处,我可能会更好地回答这个问题。我见过的大多数系统都有 Country 和 State 的 FK 表,但这些表不一定相互关联。

于 2009-04-09T00:43:07.240 回答
1

我想我的问题是“好的设计是为了什么?” 如果地址的精确完整性对您的设计绝对至关重要,那么这可能是富有成果的讨论的开始。另一方面,如果目的是收集地址并能够以您可能希望从真实用户那里获得的所有种类存储它们,您可能会考虑一些更灵活的东西:即更少的表和更多的可选字段和UI 中有一套很好的友好验证规则。

于 2009-04-09T01:02:28.580 回答
0

我会这样做:

  • 国家(国家 ID,国家名称)
  • 州(stateID,stateName,countryID(FK))
  • City(cityID, cityName, stateID(FK)) <- 你把这个国家和那个 FK
  • 地址(addressID, adressDescription, cityID) <- 这里的概念相同。

现在告诉我,在不同的城市、州和国家拥有相同地址的几率是多少?最小。所以这应该有效。请记住,将数据库标准化到极端并不总是有效或有帮助。

希望这可以帮助

此致!

于 2009-04-09T00:51:57.310 回答
0

取决于您如何在所有表上定义 PrimaryKey。如果您将id列作为所有表的键,则可以减少所有表中的列,以便它们将 FK 保留到下一个区域。

  • address(给定)
  • city 通过地址.city_fk
  • state通过 city.state_fk
  • country通过 state.country_fk 国家

设计就像克里斯的。如果您需要一个查询中的所有数据,则可以进行联接。

但是,如果id不是键而是所有表中的部分键(不能单独定义数据集),那么我会认为这是一个很好的设计。然后将像这样识别地址:

  • 国家 8(法国)
  • 状态 3(巴黎地区)
  • 城市 23(巴黎)
  • 地址 1(为该城市存储的第一个地址)

仅仅知道“City 23”是不够的,因为接下来会出现问题:第 23 个城市在哪个州,哪个州在哪个国家 - 这将导致您将数据存储在所有表中。

但这实际上取决于您如何定义密钥。

于 2009-04-09T00:53:12.567 回答
0

考虑一下:如果我知道国家,而国家 FK 是国家,我就可以传递地知道国家,再次包含它是一种多余的非规范化。

如果我知道城市,而城市 FK 是状态,那么我就可以传递地知道状态,并且再次包含它是一种多余的非规范化。

所以,如果我了解这座城市,我就了解这个州,我就了解这个国家。

ADDRESS(id, address, city_fk), CITY(id, name, stateFK), STATE(id, name, countryFK), COUNTRY(id, name)

在实践中,将城市作为实体或属性存在合理的论据。对于诸如邮寄地址之类的东西,将其作为属性可能更简单。

对于像“选民档案”(用于竞选和政治活动的数据库)之类的东西,将城市变成一个实体可能是有意义的。这在美国弗吉尼亚州尤为重要,这在美国是独一无二的,因为注册城市是独立的政治管辖区,与美国其他地区不同,在管辖权上,大多数城市都是县的一部分。

即使在弗吉尼亚州以外的州,由于属于县的城市有单独的选举(市长和议会),在政治数据库中,使城市(变得更小,选区和辖区以及乡镇和村庄,并变得更大)是有用的、县和 HD 以及 SD 和 CD)合并为实体。

现在以美国俄亥俄州的莱克伍德为例。在管辖范围内,莱克伍德是凯霍加县。在政治电视广告方面,它是克利夫兰-阿克伦-坎顿电视指定市场区的一部分。它位于克利夫兰市外,该市也是凯霍加县管辖的一部分。莱克伍德分为四个议会选区,每个选区又分为十五个或更多选区。它是州议会第 13 区的一部分,其中包括莱克伍德和克利夫兰市西侧的一部分。它是州参议院第 23 区的一部分,其中包括布鲁克林、布鲁克帕克、克利夫兰(7-21 区和 14 区的一部分)、莱克伍德、林代尔、米德尔堡高地、帕尔马和帕尔马高地。莱克伍德位于俄亥俄州第 10 届美国国会选区(由 Dennis Kucinich 代表)。

现在,对于任何给定的俄亥俄州选民,我们如何在数据库中表示当他投票时谁将在他的选票上?

于 2009-04-09T00:59:31.270 回答
0

我一直对表格设计做的是查看它并找出我会遇到什么样的麻烦(即会产生什么不一致)。

在您的特定情况下,显而易见的是您可以创建一个位于怀俄明州和达拉斯市的地址,该市处于衰败状态,哎呀,我的意思是德克萨斯州:-)

同样,您的地址可能位于澳大利亚国家德克萨斯州(美国)以及南美洲秘鲁的 Xolotllotl a市。当邮递员追踪您时,我不想向他解释您的架构。

你如何解决这个问题?您可能应该只从地址引用城市,然后从城市引用州,然后从州引用国家。

但是地址是一种棘手的野兽,它们采取的形式在很大程度上取决于它们所在的位置。有些有县,有些城市跨越州界等等。

除非您迫切需要在特定城市寻找人,否则我会将其合并到一个自由格式的地址中(大多数地方都有某种邮政编码,这是一个更好的选择)。您可能希望按州或国家/地区进行选择,在这种情况下,将它们保留为单独的字段。

我的第一次尝试是:

ADDRESS(id, address_including_city, stateFK),
STATE(id, name, countryFK),
COUNTRY(id, name)

您必须区分不同国家/地区的“相同”州(例如,华盛顿和西澳大利亚都是西澳),但您可以轻松地在数据输入屏幕中显示该国家/地区,以便操作员知道他们正在进入哪个州(或更可能,他们将首先选择国家,而国家的选择将被削减)。


据我所知,Xolotllotl 并不是一座真正的城市,它只是我编造的一个听起来像那些古老的印加人美丽名字的城市

于 2009-04-09T01:16:07.083 回答
0

您是否规范化得太远了?

当您降低重复数据的成本时,您可能会通过需要 3 或 4 个连接来获得整个地址来否定它......

我个人会坚持:

地址:

  • ID
  • 街道地址(例如 123 Joe Street)
  • 城市
  • 状态
  • 邮政编码 (ZIP)
  • 国家(例如美国或澳大利亚)

当然,您必须对诸如城市/州/邮政编码/国家之类的事物进行索引,但这可能比加入多个表要快得多。

(注意:我不是 DBA,所以我不能支持我的声明,但这是我使用的,它工作正常)

于 2009-04-09T01:31:55.327 回答