正确使用KEY,INDEX或UNIQUE

时间:2013-01-30 19:11:32

标签: mysql indexing constraints unique

我指的是this SO-question。在第一个答案中,据说

  

UNIQUE是指索引的所有行必须唯一的索引。也就是说,对于此索引中的所有列,同一行可能不具有与另一行相同的非NULL值。除了用于加速查询之外,UNIQUE索引还可用于强制限制数据,因为数据库系统在插入或更新数据时不允许破坏此不同值规则。

由于我的英语不是最好的,我想知道这意味着什么,

  

对于此索引中的所有列,同一行可能没有相同的非NULL值作为另一行

为了快速将此与我的实际问题联系起来,这是我的方案。我有三张桌子

game(gameID, ...), PK(gameID)
player(gameID, playerName, ...), PK(gameID, playerName), FK(gameID)
prop(gameID, playerName, c1, c2, c3, ...) PK(gameID, playerName), FK(gameID, playerName)

现在,连接到游戏的玩家可以选择1-n道具。在这样的道具中,c1 - c3代表扑克牌值,更准确地说是{1,2,3,...,T,J,Q,K,A}。

这三张牌的组合可以包含相同的值,但组合只能在游戏中选择一次。例如。玩家可以选择{2,2,3}{A,2,3},但是在那个游戏中,没有其他玩家可以再次选择相同的组合。

现在返回我的序言,c1, c2, c3语句中的三个元素UNIQUE未被声明为CREATE TABLE(否则示例中的第一个组合将无法实现)。这是否意味着我不能使用UNIQUE(gameID, c1, c2, c3)作为约束来确保游戏中组合的唯一性?这是使用INDEX(gameID, c1, c2, c3)的好例子吗?在我的特定情况下使用这两种变体有什么区别?

最后,第三个表的CREATE TABLE语句将是

create table prop(
    gameID  INTEGER NOT NULL,
    playerName  VARCHAR(25) NOT NULL,
    isBB    BOOLEAN NOT NULL DEFAULT FALSE,
    card1   VARCHAR(1) NOT NULL,
    card2   VARCHAR(1) NOT NULL,
    card3   VARCHAR(1) NOT NULL,
    PRIMARY KEY (gameID, playerName),
    FOREIGN KEY (gameID, playerName) REFERENCES player(gameID, playerName) ON DELETE CASCADE,
    UNIQUE(gameID, c1, c2, c3) /* OR INDEX(gameID, c1, c2, c3)?

)ENGINE=INNODB;

1 个答案:

答案 0 :(得分:2)

索引用于加速数据库中的搜索。另一方面,唯一约束强制执行数据库中的行规则(在您的示例中,没有两行将完全相同的'gameID,c1,c2,c3'列值。

您可以拥有gameID索引,以加快WHERE gameID = ?之类的查询速度。但是这并不能保证你只有1行,比如说gameID = 1.如果你需要这样的约束,那么你需要UNIQUE约束(对于id字段,主键是一个更好的选择,因为它将唯一性和索引结合在一起)。

回答您的具体问题:

  

这是否意味着我不能使用UNIQUE(gameID,c1,c2,c3)作为约束来确保游戏中组合的唯一性?

如果你这样做,那么这些组合将是每场比赛的唯一。

  

这是使用INDEX(gameID,c1,c2,c3)的好例子吗?

如果您经常在游戏中搜索组合,这也是一个很好的例子。