3

我有一个意见问题,但同时可能有一个正确的答案。我正在尝试开发一套产品,并希望确保因为我自己在做,所以我第一次就做对了。我多次重写了架构,每次都认为它更好。然后我可能会遇到一些新想法,它要么需要在架构上进行大量工作,要么会破坏我的架构。

在大学里,我学会了“合理化”(我认为这是他们使用的词,可能会离题)一个数据库,有 5 个级别。据我记得,3 级是最常见的。我知道这种做法是为了确保数据不会重复,为此,您必须将表分解为较小的表。并且取决于你打破它的程度,级别越高。好吧,我不知道我是否想要最高级别,但我知道我希望它尽可能高效。我已经使用了 4 年的 SQL Server 2000/2005/2008 和 2 年的 Oracle,使用 Informix 大约 6 个月(5 多年前),在这里或那里使用 mySQL 和大约 6 个月的 Access。我的首选是 SQL Server,但我希望架构在任一平台上都一样高效。

这是一些表的伪模式布局,然后我将解释我想要做什么。

Manufacturers
  ManufacturerID (Identity)
  ManufacturerName
  ManufacturerStreetAddress
  ManufacturerZipCodeID
  ...

ZipCodes
  ZipCodeID (Identity)
  ZipCode
  ZipCodeStateID
  ...

States
  StateID (Identity)
  StateName
  StateAbbreviation
  ...

Cities
  CityID (Identity)
  CityName
  CityStateID
  ...

我很抱歉它只是一个伪模式,但这就是我现在所拥有的,因为我正在休息时在纸上进行设计,但在我走得太远之前有一个问题。我想做的是确保一切都正确地相互联系。我的信念是邮政编码属于一个州和一个城市,但没有一个城市属于任何一个邮政编码,它可能有很多。如果我将邮政编码放在制造商表中,我希望能够获得州和城市。但我不想在其他表中多次使用任何 ID。我的意思是在 ZipCodes 和 Cities 中拥有 StateID 的次数可能太多了。一个州可以有多个同名城市,多个州可以有同名城市。但我不确定我是否想要一个 CityNames 表,然后是一个 CityStates 表(CityNameID 和 StateID)。我很清楚有一些位置数据库可供购买,也许有些是免费的,我可以使用并且不必担心这一点。但是,我想努力理解这一点,因为我相信它会在未来帮助我明智地进行架构设计,而且还因为如果需要更改任何内容,我希望拥有布局的可定制性。

问题:

  1. 这种伪模式看起来是正确的还是会更好(意见)?
  2. 它是否被称为“合理化”数据库,或者其他什么(将投票支持正确答案)?还有多远(观点)
  3. 还会有一个用户表,以及其他包含地址(团队、国会大厦等)的表,如果理论上是正确的,那么伪模式对于这样的数据库是否是一个好的计划(意见)?

谢谢大家的时间,我会投票赞成任何彻底和连贯的答案。数据库专家或具有多年数据库经验的人优先,但我会听取所有答案。另外,我不确定这是否应该是一个社区 wiki,但我现在没有将它标记为一个。谢谢。

更新:另外,我忘了提到我知道“合理化”数据库需要连接,有时需要子查询。我通常滥用 LEFT OUTER JOIN,但是将这些表绑定在一起以显示地址而不是执行 4 个不同的查询的最有效方法是什么?谢谢。

更新:好的,现在这可能过于规范化或不够规范化或根本没有,但是你们能告诉我你是否更喜欢这个伪模式吗?

Manufacturers
  ManufacturerID (Identity)
  ManufacturerName
  ManufacturerStreetAddress
  ManufacturerCCSZID --CCSZ (Country, City, State, Zip), needs a better name
  ...

ZipCodes
  ZipCodeID (Identity)
  ZipCode
  ...

States
  StateID (Identity)
  StateName
  StateAbbreviation
  ...

Cities
  CityID (Identity)
  CityName
  ...

Countries
  CountryID (Identity)
  CountryName
  CountryAbbreviation
  ...

CountryCityStateZipCodes
  CountryCityStateZipCodeID (Identity)
  CCSZCountryID
  CCSZStateID
  CCSZCityID
  CCSZZipCodeID

要获得地址,它看起来像:

SELECT  M.ManufacturerStreetAddress,
        CN.CountryName,
        CN.CountryAbbreviation,
        S.StateName,
        S.StateAbbreviation,
        C.CityName,
        Z.ZipCode
FROM Manufacturers M
LEFT OUTER JOIN CountryCityStateZipCodes CCSZ ON CCSZ.CountryCityStateZipCodeID = M.ManufacturerCCSZID
LEFT OUTER JOIN Countries CN ON CN.CountryID = CCSZ.CCSZCountryID
LEFT OUTER JOIN States S ON S.StateID = CCSZ.CCSZStateID
LEFT OUTER JOIN Cities C ON C.CityID = CCSZ.CCSZCityID
LEFT OUTER JOIN ZipCodes Z ON Z.ZipCodeID = CCSZ.CCSZZipCodeID

或者,也许你们知道编写该查询的更好方法。但无论如何,这看起来比第一个模式更好吗?

4

3 回答 3

3

我一直听说它被称为“标准化”,但我们谈论的是同一件事。

最简单的方法可能是将城市、州和邮编组合到一张表中。您甚至可以考虑使用邮政编码本身作为密钥,尽管我可以想到您想要避免这种情况的两个原因:

  1. 东北部各州的邮政编码以 0 开头,如果您将邮政编码设为数字字段,则会被截断。
  2. 如果您使用邮政编码作为密钥,则您不能在多个城镇中多次使用该邮政编码。就像你说的,邮局更关心邮编而不是城镇名称。但是这种设置会限制您以后搜索这些单独的城镇。

以后要按城市、州或邮编搜索,只需将此表加入制造商表即可。您可以使用 INNER JOIN - 除非 Manufacturers 表中的字段 ManufacturerZipCodeID 为空,在这种情况下,您还需要 LEFT JOIN 来显示这些字段。

于 2010-08-31T14:20:46.220 回答
1

我不是数据库专家,但在我看来,给定的伪模式似乎是不正确的。这是解释。从问题中得知的事实是:

  1. 一个州可以有多个城市。
  2. 一个状态是独一无二的
  3. 一个城市可以有多个邮政编码
  4. 城市名称可能等于另一个城市名称。
  5. 邮政编码是唯一的

首先,写下唯一性。所以我们构建了这两个原始表:

STATE
---
State ID (PK)
State Name

ZIP
---
Zip ID (PK)
Zip Code (NK)

然后,出现了一个逻辑问题。知道 Zip ID,我们将如何检索城市 ID?要回答这个问题,我们需要提供 Zip 和 City 之间的链接。这个链接应该放在哪里?它不在 City 表中,因为从 Fact#3 我们知道一个城市可以有许多不同的邮政编码。所以它必须在 ZIP 表中。这是我们下一个版本的 ZIP 表:

ZIP
---
Zip ID (PK)
Zip Code (NK)
City ID (FK)

现在,由于我们可以从 Zip“移动”到 City,我们将讨论 City 表。城市名称可以与其他名称相同。所以我们不需要强制它(城市名称字段)是唯一的。所以这是我们第一个版本的 City 表:

CITY
----
City ID (PK)
City Name

同样,出现了同样的逻辑问题。我们如何搬到州知道一个城市?必须在这两个表之间的某处创建链接。同样,知道事实#4 并不能保证城市名称的唯一性。链接必须放在 City 表上。所以这是我们下一个版本的 City 表:

CITY
---
City ID (PK)
City Name
State ID (FK)

通过这个链接,我们可以正确地检索状态。总的来说,我们可以通过 City ID(在 Zip 表中提供)从 Zip 移动到 City,并且我们可以通过 State ID(在 City 表中提供)继续从 City 移动到 State。

从数据库的角度来看,合理化数据库是好的,但从编程的角度来看可以被认为是“邪恶的”。因为它促使程序员编写越来越多的类。毕竟,“太远”可以定义为“表变得不合理”。City Name 表似乎不合理,因为它是一个属性,而不是一个实体。如果我的数据库分析师创建了这样一个不合理的表,我会很乐意将其标记为“太远” :) 另一方面,过度合理化数据库会极大地影响数据库性能。根据我的经验,它会使查询运行速度变慢。

关于用户、团队、国会大厦等其他问题。我现在不能说什么,因为我还没有看到这个问题。

于 2010-08-31T14:41:31.383 回答
1

我对你的设置方式没有太大的问题。邮政编码中的州 ID 可能很危险 - 得知有跨越州界的邮政编码并不会让我感到惊讶,但我不确定。

您将通过将州、城市和邮政编码存储在单独的表中来进行大量连接,但是在处理存储地址而没有一致性措施的数据库时,这比几次连接更像是一场噩梦。例如,您最终会得到“NY”和“ny”以及“Ny”和“New York”和“NewYork”。所以我认为从长远来看,为州、城市和邮编设置单独的表格会有所回报。

于 2010-08-31T14:30:58.390 回答