如何最好地规范化和参考(FK)位置(邻里/城市/地区/国家/大陆)

时间:2012-11-06 18:46:59

标签: sql database-design foreign-keys relational-database normalization

所以我一直在搜索,但没有找到满意的答案。

我有不同类型的位置,如标题中所述。给定一种类型的位置(即城市),可以推断出粒度较小的位置。即如果你知道你在俄勒冈州,这意味着你在美国,这意味着你在北美。

我们有引用位置的对象,但粒度并不完全相同。有些项目可能指向社区,有些项目只能在城市层面知道,而有些项目仅在某个地区已知,等等。

我有两种方法可以组织数据,这是我倾向于的方式:

  • 拥有一个通用的“位置”表,其中包含位置“类型”和“父位置”。因此,有一个类型国家的美国入口,以及一个引用美国的俄勒冈州州的入口。 即。

enter image description here

然后,您可以让对象引用其主键的位置,然后可以推断出其他位置。这有意义还是有更好的方法来组织数据?

  • 我考虑的另一种方法是为每个位置“类型”使用不同的表,但问题是让我们的对象引用它,因为对象的最细粒度的位置并不总是相同。

如果我稍后要将其他类型的地方类型划掉,例如城市和地区之间的县,这可能会出现问题吗?我认为这不会是一个问题,而不是单独的表,但也许有一种更好的方式我可以以合理的方式跟踪事物。

3 个答案:

答案 0 :(得分:1)

这是子类的一种情况,通常称为子类型。由于某些子类型包含在其他子类型中,这一点很复杂。容器问题由经典的基本关系数据库设计很好地处理。

子类问题需要一些解释。 OOP称为“子类”的是ER建模圈中的名称“ER Specialization”。这告诉您如何绘制子类图,但它没有告诉您如何实现它们。

值得一提的是在SQL表中实现子类的两种技术。第一个名称为“单表继承”。第二个名称为“Class Table Inheritance”。在类表继承中,您将拥有一个“位置”通用表,其中包含所有位置共有的所有属性,无论其类型如何。在“城市”表中,您将拥有属于城市的属性,但不属于国家/地区等。您将拥有其他类型位置的其他子类表。

如果你走这条路,你应该寻找另一种技术,称为“共享Priomary Key”。在此技术中,子类表的id字段都包含来自超类表的id字段的副本。这需要一点努力,但这非常值得。

共享主键提供了几个优点。它强制实现子类关系的一对一性质。它使得通用数据的专用数据简单,容易,快速。它跟踪哪些项属于哪个子类,而没有额外的字段。

在您的情况下,还有另一个优势。通过使用外键引用位置的其他表不必决定是引用超类表还是子类表。引用超类表的单个外键也将隐式引用其中一个子类表,尽管不明显哪一个。

这不是完美的,但它非常非常好。去过那里,做到了。

有关详细信息,您可以使用Google搜索技术,或在SO中找到相关标记。

答案 1 :(得分:0)

怎么样:

<强>国家:

  • Id
  • Name

<强>地区:

  • Id
  • CityId
  • Name

<强>城市:

  • Id
  • RegionId
  • Name

<强>求教:

  • Id
  • CityId
  • Name

这适用于位置类型。但是你的主要问题是

  

但粒度并不完全相同。

为此:

<强>对象

  • Id
  • Name
  • LocationId
  • Type

答案 2 :(得分:0)

好问题。

你绝对应该选择第一个选项。如果您查看任何数据建模模式书,他们都会选择这种方式。

这只是北美还是全球?

的问题:

城市/城镇/村庄/村庄是师的子女(州/省的通用术语),但不在英国,他们是国家(或县)的孩子

邮政区域(邮政编码,邮政编码)也是各部门的子女,而不是县或城市。有些城市完全位于拉链中,有些拉链完全位于城市

县也是师的孩子。曼哈顿包含县,而大多数县包含城市。

如果您希望获得全球解决方案,我会阅读Hay的企业模型模式。这是便宜的野生动物园。