在 MySQL 中生成连续的参考编号

Posted

技术标签:

【中文标题】在 MySQL 中生成连续的参考编号【英文标题】:Generating continous reference numbers in MySQL 【发布时间】:2018-08-11 12:44:42 【问题描述】:

我正在设计一个多租户 mysql 数据库。我的做法是为所有租户使用一个数据库,并在每个表中都有一个租户ID 列来分隔每个租户的数据。

对于某些表,我需要在特定租户中生成一系列连续的参考编号。

例如,我有一个名为 book 的表,其中包含以下列:租户 IDbook REFBook REF 用于唯一标识租户内的book。假设有 2 个租户:租户 1 和租户 2。每个租户都有一些书籍。现在我希望每个租户中的 book REF 像 1,2 一样运行,...

显然,在这种情况下,book.REF 并不是真正的 ID,因为租户 1 中的一些与租户 2 中的一些相同。但是由于它们被租户 ID 分开,所以它就可以了。

我不能对book REF 使用“自动增量主键”,因为它会在book REF 的租户中留下“漏洞”。

所以简而言之,bookREF有2个要求:

    它们在租户内是连续的; 每个在租户中都是唯一的;

您认为实现这样一个目标的好方法是什么?

【问题讨论】:

imo,可靠地生成序列号的方法是 1) 拥有一个命名序列表。 2)使用交易。 3)显式锁定序列(SELECT seq1 FOR UPDATE)。 4)更新它。 5)使用序列或将其丢弃。 6) 以 COMMIT 或 ROLLBACK 结束事务。这是安全的,因为所有访问都是序列化的。我有一些“redbeanphp”的测试代码。 瑞恩,感谢您的建议。听起来很有希望......如果有的话,你能分享一下redbeanphp链接吗?谢谢。 【参考方案1】:

最好的方法可能是触发器,即使它在重负载时并不完全安全。

如果同一个租户从 10 台 PC 插入 1M 本书,您可能会点击重复键,因此请务必使用 CREATE UNIQUE INDEX idxu_book ON book(id,ref) 避免这种情况

无论如何,这里有一个触发器来为每个 ID 租户制作序列:

DELIMITER $$

CREATE TRIGGER `tgi_book_ref_seq` BEFORE INSERT ON `book` 
FOR EACH ROW
BEGIN

    SET NEW.ref = (
            SELECT COALESCE(MAX(ref), 0)+1
            FROM book 
            WHERE id = NEW.id
        );

END $$
DELIMITER ;

【讨论】:

以上是关于在 MySQL 中生成连续的参考编号的主要内容,如果未能解决你的问题,请参考以下文章

mysql唯一编号生成

Prisma 在 mysql 中生成大写的数据库表。有没有办法只生成小写的表格?

python 从迭代中生成连续n个大小的块的生成器。

在 iPhone 应用程序中生成暂停/不连续的哔声

MySQL 如何生成日期表

系统中生成编号/单号问题的实现方案讨论