SQL服务器,规范这么多还是不行?

SQL Server, to normalize this much or not?

我正在尝试决定是否应该将特定列推送到它自己的列 table,或者我是否应该使用其他方法或某种约束。

假设我有一个 table 像:

tbl_Location

LocationID PK int
Address varchar(100)
City varchar(50)
State varchar(50)

另一个table喜欢:

tbl_Store

StoreID PK int
StoreName varchar(50)
LocationID int FK

问题1:所以一家店需要有一个位置,不能超过一个。将这些推入另一个 table 并创建一个约束来禁止同一 storeID 出现在多行中是否有点过分,例如:

tbl_StoreLocation

StoreID int
LocationID int

问题 2:如果我要将 PK identity/auto 增量列放在它自己的 table 中,仍然使用 PK identity/auto 增量列是否有好处?

在极少数情况下,某个位置可能会从 tbl_Location table 中删除。如果它被删除,在方法一(一体机 table )中,我将不得不将 LocationID 设置为 NULL。方法二,我得用级联了。

更复杂的是,商店可以有产品,而 LocationID 只是它们的默认位置。创建产品时,它默认使用 tbl_Store 中的 LocationID,或者如果我将其分解为另一个 table,则 tbl_StoreLocation table。所以这进一步推动了这一点,例如:

tbl_Product

ProductID PK int
StoreID FK int
ProductName varchar(50)
LocationID fk int <-----

或者我应该再次拥有(并且每个产品只能有一个位置):

tbl_ProductLocation

ProductID int
LocationID int

我了解了规范化的更深层阶段,但我需要帮助理解的是对如此简单的事物的 time/benefit/structure 分析。

你怎么看?

对于问题1: 如果一家商店需要有一个位置,不少于一个且不超过一个,那么将商店和位置之间的关系推到另一个 table 就太过分了。但是如果一个商店可以没有任何位置,因为它的位置可能被删除,你应该使用 tbl_StoreLocation table。在这种情况下,您应该从 tbl_Store table.

中删除 LocationID

对于问题 2:是的,如果您要将其放在自己的 table 中,仍然使用 PK identity/auto 增量列是有好处的。为什么不?你还在用它来搞关系。

关于产品的几句话。你说 - 'stores can have products' - 所以产品与商店有关但与位置有关,所以产品位置就是它的商店位置。只有当您更改此业务规则时,您才需要相应地重新设计您的数据库。

当产品和商店都将有一个位置时,单独 table 似乎有点矫枉过正。在我看来,在这里介绍一点 SCD 并不是一个坏主意。为什么不添加 bitIsEffectiveEffectiveTill 列,该列的时间戳对应于日期(默认值 31-12-2999 和时间,直到记录在 tables tbl_Locationtbl_Producttbl_Store 有效

如果位置被删除,只需将列 EffectiveTill 更新为 getdate() 如果产品的位置需要突然改变,只需将该行的 EffectiveTill 更新为 getdate() 并使用新的 locationID.

插入新行

这个过程有两个好处。一。将来没有令人讨厌的索引重新排列。二。历史数据的簿记。您永远不知道什么时候可能需要获取历史数据。