避免生成重复标签值的一种方法是使用MyISAM表来生成唯一的序列号。 MyISAM支持您需要的AUTO_INCREMENT行为。
参见“MyISAM的注意事项”一节中的MySQL参考3.6.9. Using AUTO_INCREMENT
对于这种方法,你可以创建一个单独的MyISAM表;该表的目的是生成唯一的序列号:例如,
CREATE TABLE foo
(prefix VARHCAR(1) NOT NULL
, num INT UNSIGNED AUTO_INCREMENT
, PRIMARY KEY (prefix, num)
) Engine=MyISAM
假设标签前缀是一个字符,其余是数字:
INSERT INTO foo (prefix, num)
SELECT SUBSTR(t.label,1,1) AS prefix
, MAX(SUBSTR(t.label,2,8) AS num
FROM mytable
GROUP BY SUBSTR(t.label,1,1)
去获得新的序列号,插入一行到新表,为前缀的值,并为NUM列NULL,并检索插入的Num列的值:
INSERT INTO foo (prefix,num) VALUES ('W',NULL);
SELECT LAST_INSERT_ID();
你可以用它来构建的价值在你用于label
列r原始表格。
请注意,它只是具有所需行为的MyISAM引擎(为每个前缀分别增加AUTO_INCREMENT序列)。您的原始表可以是任何引擎。
这种方法避免了竞争条件,但是由于在MyISAM表上插入了独占锁,所以引入了并发瓶颈。
的另一种方式,以避免竞态条件是获得对表的排他锁,然后做一个SELECT MAX(),然后执行插入,然后松开该锁。但是这种方法引入了更多的并发瓶颈,即对单个资源的访问序列化。
如果你的问题是关于识别重复的现有label
值,那么这个查询获取你有“重复”标签的行。 (这是挑选出只有一行,每个重复的标签。)
SELECT t.label
, MAX(t.id)
FROM mytable t
GROUP BY t.label
HAVING COUNT(1) > 1
要更新标签是唯一的,你需要生成这些行的新标签。
在单个SQL语句中完成该操作有点棘手。我试图提出一个声明,但它被破坏了,我没有时间去修复它。
将字段设置为'UNIQUE'? – hjpotter92 2013-03-25 02:00:54