我需要一个表来存储一些评分,在此表中,我有一个 综合索引(user_id,post_id) 和其他列来标识不同的评分系统。
user_id - bigint post_id - bigint type - varchar ... Composite Index (user_id, post_id)
在此表中,我没有 主键, 因为 主键 必须是唯一的,而INDEX不必是唯一的,就我而言,唯一性是一个问题。
例如我可以有
INSERT INTO tbl_rate (user_id,post_id,type) VALUES (24,1234,'like'), (24,1234,'love'), (24,1234,'other');
缺少PRIMARY KEY可能会导致性能问题?我的表结构好还是需要更改?
谢谢
几点:
听起来您只是在使用表的当前唯一特性,并将其用作主键。那个有效。由于本地性,自然键在查询方面具有一些优势。(每个用户的数据存储在同一区域中)。而且由于该表是由该键聚集的,因此,如果您按主键中的列进行搜索,则可以消除对数据的查找。
但是,使用您选择的自然主键对性能也有不利影响。
使用非常大的主键会使innodb中的所有其他索引变得非常大,因为主索引包含在每个索引值中。
使用自然主键的速度不如INSERT的替代键快,因为除了更大以外,它还不能每次都插入表的末尾。它必须在该用户的部分中插入并发布等。
另外,如果您按时间进行搜索,除非时间是第一列,否则您将使用自然键在整个表中进行搜索。代理键在时间上往往是本地的,对于某些查询通常可能恰好是正确的。
使用像您这样的自然键作为主键也很烦人。如果您想提及特定的选票怎么办?您需要一些字段。而且,与许多ORM一起使用时有点困难。
这是答案
我将创建自己的代理键并将其用作主键,而不是依赖innodb的内部主键,因为您将能够使用它进行更新和查找。
ALTER TABLE tbl_rate ADD id INT UNSIGNED NOT NULL AUTO_INCREMENT, ADD PRIMARY KEY(id);
但是,如果您确实创建了代理主键,那么我还将使您的键成为唯一键。相同的成本,但可以确保正确性。
ALTER TABLE tbl_rate ADD UNIQUE ( user_id, post_id, type );