我正在创建一个数据库,但我对其中的一个表不确定。这个表存储的是每个游戏中的用户,所以每个用户在每个游戏中都有一个条目。用户是通过他们的 user_id
是一个36个字符的UUID4,而游戏的标识是由一个 session_id
是一个8个字符的字母数字字符串,如 "ABK2RXN4"。目前,我已经创建了一个额外的字段,叫做 id
这是一个自动递增的整数,我已经将其设置为主键。只有这3个字段。
由于这些字段的组合是 session_id
和 user_id
的结果总是唯一的,我是否应该把这两个作为复合私钥,并去除了 id
领域?
谢谢。
EDIT.请问,如果我们有一个更复杂的表,需要更多的字段,情况会改变吗?
如果我们有一个更复杂的表,需要更多的字段,事情会发生变化吗?以这个表为例。
| id | voter | voting_for | round | category_id | acceptable |
|-----|----------|------------|----------|-------------|------------|
| int | char(36) | char(36) | smallint | int | boolean |
这是关于游戏中的投票。本质上,每一轮游戏结束后,游戏中的用户会对游戏中其他用户的答案进行投票。所以每一个条目都有用户的用户ID。voter
的用户ID,他们是谁?voting_for
,当前 round
జజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజ category_id
的类别,以及他们是否同意这个答案。acceptable.
所以,你可以用以下方法制作一个复合主键 voter
, voting_for
, round
和 category_id
. 这是否会因为字段较多而变得更糟,或者我仍然应该使用复合键,而不是现有的自动递增。id
?
这要看情况。
如果桥表要包含任何其他列,这些列是用户和游戏之间的关系的属性(比如说。JoinedGameDate
或什么的),那么行可能应该有自己的ID,因为听起来这就是你的设计模式,表结构的一致性有一定的价值。虽然抛出一个 UNIQUE
索引在这两个值上并不是一个坏主意。
另一方面,如果它真的只是一个定义N:N关系的桥,你可以定义一个复合键,这将照顾到你的索引,然后收工。
另一方面,多出的那一个自动增量的开销是非常小的,所以无论你采用哪种方式,这个决定对性能的影响可能都会忽略不计。
"每个用户每场比赛一个条目 "说的是 PRIMARY KEY(session_id, user_id)
对得起桌子 entry
. (选择把哪个id放在第一位,取决于你运行最多的是什么查询)。
然而,由于这加起来有44个字节,我们再想想。
中的每个二级索引 entry
表有一个PK的副本,静静地粘在上面。 如果你有一个以上的二级索引,这可能会变得很笨重。
此外,如果你有其他表链接到了 entry
,他们(通常)需要整个PK的副本,使他们潜在的更胖。
当我们看到所有这些东西的实际表现时,有 若干 因素,有人说 (id)
会更快,有人说会导致 (session_id, user_id)
是更快。
所以,速度和空间将取决于很多细节,你还没有介绍。
同时,你可以通过将UUID缩小到BINARY(16),也就是小20个字节的方式来帮助速度和空间。 (去掉破折号,然后用 UNHEX()
;反之则做反方向。 更多详情请咨询)。)
但是UUID还有一个速度问题。 它们是非常随机的。 所以,每次插入和请求的每一行都是随机查找。 如果你有足够的RAM,让所有使用UUIDs的表完全在ram中,那么这不是什么大问题。 否则,性能会很差,而且随着表的变大,性能会越来越差。
是不是应该有一个 session_id
表中 voting_for
? 会不会有 JOINs
到其他表格? 也许你需要的只是 PRIMARY KEY(session_id, voter, voting_for)
. 这样至少可以把游戏的信息集中在一起。
技巧和更多的讨论。* UUIDs: http:/mysql.rjweb.orgdoc.phpuuid * 多对多映射。 http:/mysql.rjweb.orgdoc.phpindex_cookbook_mysql#many_to_many_mapping_table。
您的桥表是基于两列的。这两列都是不可空的,你希望对它们有一个唯一的约束,这样就不会有重复。
这使得这两列已经是表的一个键。"主键 "只是这样一个键的名称。你可以不这样做(即把列声明为 NOT NULL
并对它们有一个唯一的约束)。) 你也可以将其声明为 "主键"。这实际上不会改变任何东西。
你也可以决定添加一个技术性的单列键(如你所建议的一个整数ID)。那么你的表将有两个唯一的键。后者可以用来从另一个表中更容易地引用一行,如果有这样的表的话。有些人在使用基于技术ID的数据库时,更喜欢每个表都有这样的ID,但只要你不需要引用,就没有必要。你又把哪个键(ID或复合键)以及是否有任何键称为 "主键 "没有实际影响。通常情况下,你会把ID称为主键。