我正在尝试决定是否应该将特定列推送到其自己的表中,或者是否应该使用另一种方法或某种约束。
假设我有一张像这样的桌子:
tbl_Location
LocationID PK int
Address varchar(100)
City varchar(50)
State varchar(50)
另一张桌子,例如:
tbl_Store
StoreID PK int
StoreName varchar(50)
LocationID int FK
问题1:所以一家商店必须只有一个地点,不能超过一个。将它们推送到另一个表中,并创建一个约束来禁止相同的 storeID 出现在多个行中,是不是太过分了,例如:
tbl_StoreLocation
StoreID int
LocationID int
问题 2:如果我将其放入自己的表中,仍然使用 PK 标识/自动增量列是否有好处?
在极少数情况下,位置可能会从 tbl_Location 表中删除。如果它被删除,在方法一(全部在一个表中)中,我必须将 LocationID 设置为 NULL。方法二,我必须使用级联。
让事情变得更加复杂的是,商店可以拥有产品,而 LocationID 只是他们的默认位置。创建产品时,它默认为 tbl_Store 中的 LocationID,或者如果我将其分解为另一个表,即 tbl_StoreLocation 表。这进一步推动了这一点,例如:
tbl_Product
ProductID PK int
StoreID FK int
ProductName varchar(50)
LocationID fk int <-----
或者我应该再次拥有(每个产品只能有一个位置):
tbl_ProductLocation
ProductID int
LocationID int
我读到了规范化的更深层次的内容,但我需要帮助理解的是对于如此简单的事情的时间/收益/结构分析。
你觉得怎么样?
对于问题1: 如果要求一个商店只有一个位置,不少于一个且不超过一个,那么将商店和位置的关系推到另一个表中就有点大材小用了。但如果商店可以没有任何位置,因为它的位置可能会被删除,您应该使用
tbl_StoreLocation
表。在这种情况下,您应该从 LocationID
表中删除 tbl_Store
列。
对于问题 2:是的,如果您要将 PK 标识/自动增量列放在自己的表中,那么仍然使用它是有好处的。为什么不?你仍然用它来建立关系。
关于产品的几句话。您说 - “商店可以拥有产品” - 因此产品与商店相关,但与位置相关,因此产品位置就是其商店位置。仅当您更改此业务规则时,您才需要相应地重新设计数据库。
当产品和商店都将有一个位置时,拥有一个单独的桌子似乎有点过分了。在我看来,在这里介绍一点
SCD
也不错。为什么不添加 bit
列 IsEffective
或者拥有 EffectiveTill
列,该列将具有与日期相对应的时间戳(默认值 31-12-2999
和直到表中记录 tbl_Location
、tbl_Product
或tbl_Store
有效。
如果删除了位置,只需将列
EffectiveTill
更新为 getdate()
如果产品的位置需要突然更改,只需将该行的 EffectiveTill
更新为 getdate()
,然后插入新行并使用新的 locationID
。
这个过程有两个好处。一。未来不会出现令人讨厌的指数重新排列。二。历史数据的簿记。您永远不知道什么时候可能需要掌握历史数据。