数据库标准化 - 字段取决于另一个非关键字段

时间:2016-10-21 19:04:16

标签: sql-server database-normalization

以下是SQL Server中表定义的一部分:

CREATE TABLE User     
[UserId] INT NOT NULL IDENTITY(1,1),
[EatsFruit] BIT NOT NULL DEFAULT '0',
[FavoriteFruit] NVARCHAR(50) DEFAULT NULL,

可以想象,UserId是主键。我在这里使用了一个更简单的例子来解释我与“水果”字段相关的问题。

EatsFruit字段将为1或0,具体取决于用户是否吃水果。如果EatsFruit包含1,那么FavoriteFruit字段将包含用户最喜欢的水果。如果EatsFruit是0,那么FavoriteFruit是不相关的,它必须包含N / A或一些类似的值。

我想知道对此进行建模的最佳方法是什么,以及是否需要进行规范化。

由于FavoriteFruit字段取决于EatsFruit的内容,是否应该在包含UserId和FavoriteFruit的不同表中分隔?这将更清晰,因为除非用户实际吃水果(并且FavoriteFruit的内容始终是相关的),否则不会出现某个用户的条目。但是,由于新表的主键也是UserId,这是不是意味着FavoriteFruit真的依赖于UserId而不应该首先从主表中分离出来?

这里最好的做法是什么?非常感谢你!

2 个答案:

答案 0 :(得分:2)

从纯粹的规范化角度来看,您不希望有一个可能占用空间的字段与无用信息一样,就像您在示例中用户不吃水果时那样。此外,你真的不希望收藏水果成为NVarchar,因为“甜瓜”和“西瓜”是不同的东西(或者是它们),或者“事故”中的“Aple”条目怎么样。

如果是我,我会有一个Fruit Table和一个FavoriteFruit Association表,FavoriteFruit表会有水果ID和用户ID。如果用户没有喜欢的水果,则不使用空间。另外,我会问我是否可以摆脱“EatsFruit”,只需检查FavoriteFruits表中的条目。

那就是说,你所拥有的方式虽然可能有点松散,但并不是一个不可原谅的罪。

干杯。

答案 1 :(得分:0)

当您开始在表格中保存条件anual_bonus时,您就知道数据需要规范化。

想象一下,您的员工表中有一个字段 user_id ,但只有经理才能获得奖励。你将在该领域拥有大量的空白,这将是一种浪费。

对于这种情况,我会

用户:

  user_id
  favorite_fruit_id (can be null if user eat fruit but doesnt have favorite?)

EatFruit:

  fruit_id
  fruit_name

水果

SELECT user.*
FROM user
LEFT JOIN EatFruit
      on user.user_id = EatFruit.user_id
WHERE EatFruit.user_id IS NOT NULL

以便让喜欢水果的用户

float