重複するラベル値の生成を回避するための1つのアプローチは、MyISAMテーブルを使用して一意のシーケンス番号を生成することです。MyISAMは、必要なAUTO_INCREMENTの動作をサポートします。
MySQLリファレンス3.6.9の「MyISAMノート」セクションを参照してください。AUTO_INCREMENTの使用
このアプローチでは、別のMyISAMテーブルを作成します。この表の目的は、一意のシーケンス番号を生成することです。
CREATE TABLE foo
( prefix VARHCAR(1) NOT NULL
, num INT UNSIGNED AUTO_INCREMENT
, PRIMARY KEY (prefix, num)
) Engine=MyISAM
ラベルプレフィックスが1文字で、残りが数値であると仮定します。
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
これを使用して、元のテーブルの列に使用される値を作成できます。
必要な動作を行うのはMyISAMエンジンのみであることに注意してください(プレフィックスごとにAUTO_INCREMENTシーケンスを個別にインクリメントします)。元のテーブルはどのエンジンでもかまいません。
このアプローチは競合状態を回避しますが、挿入のためにMyISAMテーブルで排他的ロックが取られるため、同時実行のボトルネックが発生します。
競合状態を回避するもう1つの方法は、テーブルの排他ロックを取得してからSELECT MAX()を実行し、次に挿入を実行してからロックを解除することです。しかし、そのアプローチでは、同時実行のボトルネックがさらに発生し、単一のリソースへのアクセスがシリアル化されます。
質問が既存の重複label
値の識別に関するものである場合、このクエリは「重複」ラベルを持つ行を取得します。(これは、複製されたラベルごとに1行だけを選択します。)
SELECT t.label
, MAX(t.id)
FROM mytable t
GROUP BY t.label
HAVING COUNT(1) > 1
ラベルを一意に更新するには、それらの行の新しいラベルを生成する必要があります。
単一のSQLステートメントでそれを実行するのは少し注意が必要です。私は声明を考え出そうとしましたが、それは壊れていて、それを修正する時間がありません。