• mysql利用LAST_INSERT_ID实现id生成器


    首先了解 LAST_INSERT_ID

    • LAST_INSERT_ID 有自己的存储空间,能存一个数字
    • 不带参数时返回最近insert的那行记录的自增字段值。带参数时会将自己存储的数字刷成参数给定的值

    结合使用样例来看:

    -- 这种情况是正常情况,LAST_INSERT_ID 输出值会增加
    INSERT INTO `advertise_ipad` (`path`, `status`) VALUES ('testValue', 1);
    SELECT LAST_INSERT_ID();  -- 输出1
     
    -- 如果主动赋值了 AUTO_INCREMENT 字段,则输出值不会增加
    INSERT INTO `advertise_ipad` (`id`, `path`, `status`) VALUES ('100', 'testValue', 1);
    SELECT LAST_INSERT_ID();  -- 输出1
    INSERT INTO `advertise_ipad` (`path`, `status`) VALUES ('testValue', 1); -- 这时 AUTO_INCREMENT 被刷成100,如果再执行不带id的插入,下一个id会为101,LAST_INSERT_ID 也变成101
    SELECT LAST_INSERT_ID();  -- 输出101
     
    -- 如果主动赋值了 AUTO_INCREMENT 字段,且值比当前自增值小,不会改变 LAST_INSERT_ID 的结果
    INSERT INTO `advertise_ipad` (`id`, `path`, `status`) VALUES ('60', 'testValue', 1);
    SELECT LAST_INSERT_ID();  -- 输出101
    INSERT INTO `advertise_ipad` (`path`, `status`) VALUES ('testValue', 1); -- 这时 AUTO_INCREMENT 还是101,不会被60影响,再执行不带id的插入,下一个id和 LAST_INSERT_ID 会为102
    SELECT LAST_INSERT_ID();  -- 输出102
     
    -- 执行批量插入,虽然插入了103、104、105,三条记录,但 LAST_INSERT_ID 会返回第一个,即103
    INSERT INTO `advertise_ipad` (`path`, `status`) VALUES ('testValue', 1), ('testValue', 1), ('testValue', 1);
    SELECT LAST_INSERT_ID();  -- 输出103
    INSERT INTO `advertise_ipad` (`path`, `status`) VALUES ('testValue', 1); -- 再插入一条记录,由于自增已经到了105,下一行会变成106,LAST_INSERT_ID 也变成106
    SELECT LAST_INSERT_ID();  -- 输出106
     
    -- 如果执行带参数的 LAST_INSERT_ID 方法,则会保存下来
    SELECT LAST_INSERT_ID(600);
    SELECT LAST_INSERT_ID();  -- 输出600
    INSERT INTO `advertise_ipad` (`path`, `status`) VALUES ('testValue', 1); -- 再插入一条记录,由于自增还是106,下一行会变成107,LAST_INSERT_ID 也变成107
    SELECT LAST_INSERT_ID();  -- 输出107

    函数很简单

    为了实现便于不同业务访问的id生成器,我们需要一个管理不同维度id的table,比如

    CREATE TABLE `tbl_id_factory` (
      `id_type` tinyint(3) unsigned NOT NULL,
      `id_value` bigint(20) unsigned NOT NULL,
      PRIMARY KEY (`id_type`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    创建mysql函数来实现

    CREATEFUNCTION `next_id`(id_type_index TINYINT) RETURNS bigint(20) DETERMINISTIC
    BEGIN
        UPDATE tbl_id_factory SET id_value = LAST_INSERT_ID(id_value+1) WHERE id_type = id_type_index;
        RETURN LAST_INSERT_ID();
    END

    在上层调用时只需 SELECT next_id(业务类型) 即可

    第三行的 LAST_INSERT_ID(id_value+1) 实际上将其值刷成 当前业务自增值+1,然后第四行返回。这里 LAST_INSERT_ID 函数起到中间变量的作用,当下一个业务访问时,LAST_INSERT_ID 又被刷成另一个业务的自增值+1,这需要 LAST_INSERT_ID 方法线程安全,文档中是这么说的

    The value of mysql_insert_id() is affected only by statements issued within the current client connection. It is not affected by statements issued by other clients.

    参考文档:https://dev.mysql.com/doc/refman/8.0/en/mysql-insert-id.html

    micheal.li > 阿智
    micheal.li > mikeve@163.com
  • 相关阅读:
    C++ 重载操作符- 01 简单的入门
    C++ 析构函数
    Auto Control 001 自动控制的一般概念
    C++ 友元
    安装 SQL Server 2014 Express
    关闭是否只查看安全传送的网页内容提示框 和 是否允许运行软件,如ActiveX控件和插件提示框
    Python 网络爬虫 010 (高级功能) 解析 robots.txt 文件
    2019-06-12 Java学习日记之JDBC
    2019-06-11 Java学习日记之Bootstrap
    2019-06-10 Java学习日记之JQuery
  • 原文地址:https://www.cnblogs.com/loveCheery/p/8945100.html
Copyright © 2020-2023  润新知