我有一个意见问题,但同时也有一个可能有正确答案的问题。我正在尝试开发一套产品,并希望确保自己自己这样做,我第一次就做好了。我多次重新编写模式,每次都认为它更好。然后我会遇到一些新的想法,它要么需要在架构上做很多工作,要么会破坏我的架构。
在大学期间,我学会了“合理化”(我认为这是他们使用的词,可能是关闭的)数据库,有5个级别。根据我的记忆,3级是最常见的。我知道这样做的目的是确保数据不会重复,为此,您必须将表分成较小的表。根据你分手的程度,水平越高。好吧,我不知道我是否想要最高级别,但我知道我希望它能像我能得到的那样高效。我有4年的SQL Server 2000/2005/2008和2年的Oracle,大约6个月的Informix(5年多以前),在这里或那里使用mySQL和大约6个月的Access。我的偏好是SQL Server,但我希望架构在任一平台上都一样高效。
这是一些表格的psuedo架构布局,然后我会解释我想要做什么。
Manufacturers
ManufacturerID (Identity)
ManufacturerName
ManufacturerStreetAddress
ManufacturerZipCodeID
...
ZipCodes
ZipCodeID (Identity)
ZipCode
ZipCodeStateID
...
States
StateID (Identity)
StateName
StateAbbreviation
...
Cities
CityID (Identity)
CityName
CityStateID
...
我为它只是一个假的架构而道歉,但这就是我现在所拥有的,因为我在休息时在纸上做设计,但在我走得太远之前有一个问题。我想要做的是确保一切都正确地相互联系。我的信念是,Zip-Code属于一个州和一个城市,但没有一个城市属于任何一个邮政编码,它可能有很多。如果我将Zip-Code放在制造商表中,我希望能够获得州和城市。但我不想在其他表中使用任何ID太多次。我的意思是在ZipCodes和City中使用StateID可能是一次太多次。州可以有多个具有相同名称的城市,多个州可以拥有相同名称的城市。但我不确定我是否需要CityNames表,然后是CityStates表(CityNameID和StateID)。我很清楚,有一些位置数据库可供购买,也许一些免费,我可以使用,不必担心这个。但是,我想对此有所了解,因为我相信它将有助于我将来的架构设计,但也因为我希望在需要更改任何内容的情况下具有布局的可约定性。
问题:
谢谢大家的时间,我会投票通过任何彻底和连贯的答案。数据库专家或具有多年数据库经验的人员是首选,但我会听取所有答案。另外,我不确定这是否应该是社区维基,但我现在并没有将其标记为一个。感谢。
更新:另外,我忘了提到我知道“合理化”数据库需要加入,有时需要子查询。我通常滥用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
或许你们知道一个更好的方法来编写该查询。但无论如何,这看起来比第一个模式更好吗?
答案 0 :(得分:3)
我一直听到它叫做“规范化”,但我们谈的是同样的事情。
最简单的方法是将city,state和zip合并到一个表中。你甚至可以考虑使用邮政编码本身作为关键,虽然我可以想到你为什么要避免这样做的两个原因:
要稍后按城市,州或邮政编码进行搜索,只需将此表格加入制造商表格即可。你可以使用内部连接 - 除非在制造商表中有制造商工厂区的空白,在这种情况下,你需要一个LEFT JOIN来显示它们。
答案 1 :(得分:1)
我对设置方式的方式没有太大问题。邮政编码中的州ID可能很危险 - 我知道有些邮政编码跨越国界,我不会感到惊讶,但我不确定。
您将通过在单独的表中存储州,城市和邮政编码来进行大量连接,但是在处理存储地址而没有一致性措施的数据库时,这更像是一场噩梦而不是几次连接。例如,你最终得到“纽约”,“纽约”和“纽约”,“纽约”和“纽约”。所以我认为从长远来看,州,城市和拉链的单独表格会得到回报。
答案 2 :(得分:1)
我不是数据库专家,但在我看来,给定的伪模式似乎不正确。这是解释。从问题中得知的事实是:
首先,记下独特的内容。所以我们构建了这两个原始表:
STATE
---
State ID (PK)
State Name
ZIP
---
Zip ID (PK)
Zip Code (NK)
然后,出现了一个逻辑问题。知道Zip ID后,我们如何检索城市ID?要回答这个问题,我们需要在Zip和City之间提供一个链接。这个链接应该放在哪里?它不在City表中,因为从事实#3我们知道一个城市可以有许多不同的邮政编码。所以它必须在ZIP表中。这是我们下一版的ZIP表:
ZIP
---
Zip ID (PK)
Zip Code (NK)
City ID (FK)
现在,既然我们可以从Zip“移动”到City,我们将讨论City table。城市名称可以与其他名称相同。所以我们不需要强制它(城市名称字段)是唯一的。所以这是我们的City表的第一个版本:
CITY
----
City ID (PK)
City Name
同样,出现了同样的逻辑问题。我们如何移居国家了解城市?必须在这两个表之间的某处创建链接。再次,知道事实#4不能保证城市名称的唯一性。该链接必须放在City表上。所以这是我们下一个城市表的版本:
CITY
---
City ID (PK)
City Name
State ID (FK)
通过此链接,我们可以正确检索状态。总的来说,我们可以通过城市ID(在Zip表格中提供)从Zip移动到城市,我们可以通过州ID(城市表格中提供)继续从城市移动到州。
从数据库角度合理化数据库是好的,但在编程透视图中可以被认为是“邪恶的”。因为它促使程序员编写越来越多的类。毕竟,“太远”可以定义为“桌子变得不合理”。城市名称表似乎是不合理的,因为它是属性,而不是实体。如果我的数据库分析师创建这样一个不合理的表格,我会高兴地标记“太远了”:) 另一方面,过度合理化数据库会极大地影响数据库性能。根据我的经验,它会使查询运行得更慢。
关于用户,团队,Capitols等其他问题,我现在还不能说什么,因为我还没有看到问题。