【问题标题】:MySQL counter for specific situations针对特定情况的 MySQL 计数器
【发布时间】:2017-07-12 23:51:09
【问题描述】:

我需要生成唯一的“ids”,关键是,它只能在 1 - 99999 之间。

“好”的是,它必须是唯一的,只有在与另一列的组中。

我们有组,每个组都有自己的“group_id”,每个组都需要unique('group_id', 'increment_id')之类的东西

99999 条记录现在对于每个组来说足够几年,但对于所有组来说还不够,因此我不能只使用 AUTO_INCREMENT 创建表并在其中插入记录并自动递增。

例如,如果第一组需要 5 条记录,第二组需要 3 条记录,我想得到这样的结果:

group_id, increment_id
1, 1,
1, 2,
1, 3,
1, 4,
1, 5,
2, 1
2, 2,
2, 3

此外,冲突不是一个选项,因此如果以编程方式完成,使用“长度”之类的东西可能会很棘手(即一次可以有 10 个请求,每个请求首先为给定的 group_id 选择长度,然后尝试创建10行具有相同的increment_id)

但是我在想 - 如果我将它设置为 count 的 subselect 的值,那么它总是“ok”?

【问题讨论】:

    标签: mysql increment auto-increment


    【解决方案1】:

    您可以创建一个名为 counters 的辅助表来管理它:

    表:计数器 列:group_id、current_counter

    每次插入一行时 increment_id = select max(increment_id)+1 from table_xxx where group_id = group_xxxx

    【讨论】:

    • 第一个选项本身不起作用 - 每次我把记录放在那里它都会上升,因此更快达到 99999
    • 但是第二个选项 - 碰撞呢?如果大量并发请求进入数据库以创建此类记录,它是否总是“ok”,或者它可能会崩溃,因为在尝试放入新记录时在给定时间选择“max”不再是 max?
    • 您只需要为特定的 group_id 更新 current_counter,每个组将根据需要有单独的计数器。
    • myisam 引擎将按顺序执行插入,关于 innodb 我不太确定。但我认为数据库将并行保护新插入,因为您也在此插入上执行选择,而不是 100%。您使用的是哪个引擎?
    • 好吧,如果可能的话,我会尽可能地独立于当前的引擎,但我认为这是无法在“抽象级别”解决的问题。我们目前使用的是 MariaDB,可能是默认设置,也就是 XtraDB
    【解决方案2】:

    您可以使用用户变量来获取每个 group_id 内的递增数字:

    select 
        t.*, 
        @rn := if(@group_id = group_id,
                    @rn + 1,
                    if(@group_id := group_id, 1, 1)
                ) increment_id
    from (
        select group_id
        from your_table t
        /* some where clauses */
        order by group_id
        ) t
    cross join (
        select @rn := 0,
            @group_id := - 1
        ) t2
    

    【讨论】:

      猜你喜欢
      • 2020-05-31
      • 2011-07-04
      • 1970-01-01
      • 2018-05-19
      • 1970-01-01
      • 2011-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多