没有钥匙的桌子不好吗?

时间:2014-03-06 16:05:45

标签: database database-design relational-database database-schema

我有下表,表示在足球比赛期间给予球员的牌:

CREATE TABLE cards (
    player_id INT,
    match_id INT,
    color VARCHAR(4),
    minute INT,

    FOREIGN KEY (player_id) REFERENCES players(id),
    FOREIGN KEY (match_id) REFERENCES matches(id)
);

如您所见,其中没有主键。玩家可以在相同的比赛中在同一分钟接收两张相同颜色的牌。我认为这没关系,因为没有必要更准确地知道第二张牌是什么。

这是一个糟糕的设计吗?这有名字吗?这有什么样的正常形式吗?

3 个答案:

答案 0 :(得分:3)

是的,一般来说,拥有没有主键的表是个坏主意。

这样做的一个原因是没有主键,如果您想要删除或更新其中一条记录(如果您有多个与您解释的数据相同的数据),则无法知道您所指的是哪条记录

示例:

 player_id    match_id      color      minute
 1            100           RED        34
 1            100           RED        34
 2            100           YELLOW     41
 3            200           RED        22

现在,想象一下你想要更新玩家1获得的第二张牌,并将其更改为黄色(或删除它)。你会怎么写这个查询?

因此,如果您希望在同一场比赛中为同一个玩家提供多条记录,则可以为每条记录创建surrogate key。否则,自然主键将是player_id和match_id的组合。

CREATE TABLE cards (
    card_id INT PRIMARY KEY,
    player_id INT,
    match_id INT,
    color VARCHAR(4),
    minute INT,

    FOREIGN KEY (player_id) REFERENCES players(id),
    FOREIGN KEY (match_id) REFERENCES matches(id)
);

答案 1 :(得分:3)

只需添加一个新属性“NumberOfCards”,即可将{player,match,color,minute}作为密钥。

  

这是不好的设计吗?

  

这是否是任何形式的正常形式?

没有。每列都是可空的,并且允许重复的行,因此它不是一个正确的关系,并且不满足任何正常形式。

答案 2 :(得分:2)

让我稍微谈谈sqlvogel said ....

在关系数据库中,“table”是“关系”的数学概念的物理表示,它是元组的。由于它是一个集合(而不是多集),它可以包含每个元组最多一次

没有键的表允许多个相同的行/元组,因此不是关系(并且您的数据库不能再被视为“关系”)。


在您的特定情况下,您只需从现有字段中创建一个密钥,然后添加一个“数量”字段,您可以根据需要增加和减少该字段。或者,考虑一个更“细粒度”的自然键,甚至是一个“伪代理”键as proposed by Miky Dinescu,它可以让你真正区分单个卡片。

在极少数情况下,无密钥表可能有用(当数据不是很“重要”但写入性能时,例如存储调试跟踪时),但在绝大多数情况下,缺少钥匙应该是一个大红旗。