duanhuang7591 2012-07-24 21:00
浏览 74
已采纳

增量计数器mysql

My question is pretty simple but answer might be tricky.

I'm in PHP and I want to manage manually a unique ID for my objects. What is tricky is to manage atomicity. I dont want that 2 elements get the same ID.

"Elements" are grouped in "Groups". In each group I want elements ID starting from 1 and grow incrementally for each insert in that group.

My first solution is to have a "lastID" column in the table "Groups" :

CREATE TABLE groups ( id INT AUTO_INCREMENT, lastId INT )
CREATE TABLE elements ( myId INT, multiple values ...)

In order to avoid many elements with the same ID, I have to update lastId and select it in an atomic SQL Query.

After that, one retrieved, I have a unique ID that can't be picked again and I can insert my element.

My question is how to solve the bold part ? My database is MySQL with MyISAM engine so there is no transaction support.

UPDATE groups 
SET lastId = lastId + 1 
WHERE id = 42

SELECT lastId 
FROM groups
WHERE id = 42

Is there something more atomic than these 2 requests ?

Thanks

  • 写回答

3条回答 默认 最新

  • dongqian6484 2012-07-24 21:03
    关注
    UPDATE groups SET lastId = last_insert_id(lastId + 1)
    

    and then you can get your new id with

    SELECT last_insert_id()
    

    Using last_insert_id with a parameter will store the value and return it when you call it later.
    This method of generating autonumbers works best with MyISAM tables having only a few rows (MyISAM always locks the entire table). It also has the benefit of not locking the table for the duration of the transaction (which will happen if it is an InnoDB table).

    This is from the MySQL manual:

    If expr is given as an argument to LAST_INSERT_ID(), the value of the argument is returned by the function and is remembered as the next value to be returned by LAST_INSERT_ID(). This can be used to simulate sequences:

    Create a table to hold the sequence counter and initialize it:

    CREATE TABLE sequence (id INT NOT NULL); 
    INSERT INTO sequence VALUES (0); 
    

    Use the table to generate sequence numbers like this:

    UPDATE sequence SET id=LAST_INSERT_ID(id+1);
    SELECT LAST_INSERT_ID(); 
    

    The UPDATE statement increments the sequence counter and causes the next call to LAST_INSERT_ID() to return the updated value. The SELECT statement retrieves that value. The mysql_insert_id() C API function can also be used to get the value. See Section 21.8.3.37, “mysql_insert_id()”.

    You can generate sequences without calling LAST_INSERT_ID(), but the utility of using the function this way is that the ID value is maintained in the server as the last automatically generated value. It is multi-user safe because multiple clients can issue the UPDATE statement and get their own sequence value with the SELECT statement (or mysql_insert_id()), without affecting or being affected by other clients that generate their own sequence values.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料