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

Database Normalization - Field depending on another non-key field

以下是 SQL 服务器中 table 定义的一部分:

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

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

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

我想知道对此建模的最佳方法是什么,是否需要对其进行标准化。

既然 FavoriteFruit 字段依赖于 EatsFruit 的内容,是否应该将其分隔在包含 UserId 和 FavoriteFruit 的不同 table 中?这会更简洁,因为除非用户实际吃水果(并且 FavoriteFruit 的内容总是相关的),否则不会出现某个用户的条目。但是,由于新 table 的主键也将是 UserId,这是否意味着 FavoriteFruit 确实依赖于 UserId,并且一开始就不应该与主 table 分开?

此处的最佳做法是什么?非常感谢!

当您开始在 table 中保存条件 NULL 时,您就知道数据需要标准化。

假设您的员工 table 中有一个字段 anual_bonus,但只有经理才能获得奖金。您将在该字段中有很多空值,这将是一种浪费。

对于这种情况,我会

用户:

  user_id

吃水果:

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

水果

  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

从纯粹的规范化角度来看,您不希望有一个字段可能会占用 space 无用的信息,就像在您的示例中用户不吃水果时那样。此外,您真的不希望 Favorite Fruit 成为 NVarchar,因为 "Melon" 和 "Watermelon" 是不同的东西(或者它们是不同的东西),或者 "Aple" 的意外条目呢?

如果是我,我会有一个水果 Table 和一个 FavoriteFruit 协会 table,FavoriteFruit table 会有水果 ID 和用户 ID。如果用户没有最喜欢的水果,则不使用 space。另外,我会问我是否可以去掉 "EatsFruit" 并简单地检查 FavoriteFruits table 中的条目。

话虽如此,你的这种套路,虽然可能玩得有点松散,但并不是不可饶恕的罪过。

干杯。