复合主键和自动递增?什么是好的做法?

Composite Primary Keys and auto increment? What is a good practices?

我正在开发具有多租户功能的 SaaS 应用程序,并且我决定使用单个数据库(目前为 MySQL Innodb)来存储客户的数据。我选择使用复合主键,例如 PK(client_id, id)。我这里有两种方法,

1:我自己增加 "id"(通过触发器或代码)

2:使"id"自动递增mysql。

在第一种情况下,我将为每个客户提供唯一的 id's,因此每个客户的 ID 为 1、2、3 等。 在第二种情况下,所有客户的 ID 都会增长。 这里的最佳做法是什么?我的优先事项是:性能、安全性和扩展性。谢谢!

您肯定想使用自动递增的 id 值作为主键。这恰好有很多原因。这里有一些。

  1. 如果您自己生成竞争条件(意外 id 重复),则需要格外小心。将精力(开发、QA、运营)用于使您的 SaaS 变得出色,而不是在主键上重新发明漏气轮胎。
  2. 您仍然可以在 (client_id, id) 上放置索引,即使它不是 PK。
  3. 您的 JOIN 操作将更易于编写、测试和维护。
  4. 此查询模式非常适合从 table 获取每个客户端的最新行。它表现非常好。如果你自己生成pks,就更难做这种事情了。

        SELECT t.*
          FROM table t
          JOIN (SELECT MAX(id) id 
                  FROM table 
                 GROUP BY client_id
              ) m ON t.id = m.id
    

"PK(client_id, id)"--

id INT UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY(client_id, id),
INDEX(id)

是的,这个组合会起作用。而且它会有效地工作。它不会为每个客户端分配 1、2、3,但这应该无关紧要。相反,连续的 id 将分散在客户端中。

可能您的所有查询都会包含 WHERE client_id = (constant),对吗?这意味着 PRIMARY KEY(client_id, id) 将始终被使用,而 INDEX(id) 将不会被使用,除非满足 AUTO_INCREMENT.

而且,那个PK会比INDEX(client_id, id)更有效率。 (这是因为 InnoDB "clusters" 与数据的 PK。)