当前位置: 首页 > 面试题库 >

具有复合索引但不具有主键的MySQL表

游安康
2023-03-14
问题内容

我需要一个表来存储一些评分,在此表中,我有一个 综合索引(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可能会导致性能问题?我的表结构好还是需要更改?

谢谢


问题答案:

几点:

听起来您只是在使用表的当前唯一特性,并将其用作主键。那个有效。由于本地性,自然键在查询方面具有一些优势。(每个用户的数据存储在同一区域中)。而且由于该表是由该键聚集的,因此,如果您按主键中的列进行搜索,则可以消除对数据的查找。

  1. 但是,使用您选择的自然主键对性能也有不利影响。

  2. 使用非常大的主键会使innodb中的所有其他索引变得非常大,因为主索引包含在每个索引值中。

  3. 使用自然主键的速度不如INSERT的替代键快,因为除了更大以外,它还不能每次都插入表的末尾。它必须在该用户的部分中插入并发布等。

  4. 另外,如果您按时间进行搜索,除非时间是第一列,否则您将使用自然键在整个表中进行搜索。代理键在时间上往往是本地的,对于某些查询通常可能恰好是正确的。

  5. 使用像您这样的自然键作为主键也很烦人。如果您想提及特定的选票怎么办?您需要一些字段。而且,与许多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 );


 类似资料:
  • 我在oracle数据库中有一个包含客户数据的表。以下是一个简化的定义: 此表的主键是。 该表有许多行,其中为空。在数据库级别,没有问题,但是当我试图通过JPA实体访问这些行时,会导致一些问题: 1:使用

  • 我们想用雄辩的ORM和Laravel 5实现复合主键http://www.mbarendezvous.com/ 据我所知,它目前还没有得到雄辩者的支持。请建议最好的替代方案。

  • 我使用spring数据rest作为CRUD。但是当实体具有复合主键时,我不知道如何通过给出主键来获得一个实体。 河流等级: RiverPK类: Riverdoo级: 然后我可以通过调用get http://localhost:8080/river/获取河流数据,还可以通过调用post http://localhost:8080/river/{river json}为db创建新的实体 river j

  • 问题内容: 我有一个这样的表格: 需要以以下形式返回,重复项: 我尝试这样做,但这会返回类似 而且我需要重复的内容,但是当然不起作用。 有任何想法吗?谢谢。 问题答案: 您需要汇总ID。如果仅需要其中之一的ID(例如,删除),则可以执行以下操作: 如果您想同时使用两个ID,并且知道不会超过2个,则可以执行以下操作: 如果您想要所有重复项及其ID,则必须使用派生表,如Nitin Midha的回答。

  • 模板实体: 工作流实体: 指挥实体:

  • 我有一个实体,它的复合主键由两个字段组成,其中一个也是复合外键的一部分。 背景:我有实体<代码>人员 、<代码>区域 和<代码>会话 。 与具有多对多关系,使用称为“和实体。 所以,我有,主键为(,)。本身是的外键。 也有一个字段。我希望(,)是的复合外键。 我的PersonSession代码: } 这看起来不错,它在数据库中创建了所有正确的关系。当我尝试插入个性化会话对象时,问题就出现了——ar