はい、今私はこの問題を覚えています。かつて挿入をしたいと思っていた人がいましたが、各挿入は100
の増分である必要がありました 想像できれば、@1000から始めてください。そして、1つの脆弱性を持つために、すべてをストアドプロシージャでラップする必要がありました。あなたの問題が表面化し、それは彼の番号付けを1かそこら捨てました。
それをラップすることで、ロックを使用して1つのポイントを実行し、ALTER TABLE
を使用してauto_inc値を維持することができます。
私が彼に言ったもう1つのアプローチは、インクリメントテーブルを用意し、1行をロックし、その行の値を取得して使用し、そのincTableを100で更新することでした。ロックを解除します。
私たちはずっとOCDの問題について笑っていました。彼は10の倍数だけが好きだったと思います、idk
編集:
スキーマ:
-- drop table ocd_nextnums;
create table ocd_nextnums
( -- id table for nextnum, for the OCD impaired
tableName varchar(100) not null,
nextnum int not null
-- won't bother with indexes, go for it if you want
)engine=INNODB; -- note engine type
insert ocd_nextnums(tableName,nextnum) values('thing',1);
insert ocd_nextnums(tableName,nextnum) values('some_other_table',1);
-- drop table thing;
create table thing
( id int primary key, -- NOT an auto_increment, but is a PK
email varchar(100) not null,
version varchar(20) not null,
lastupdate datetime not null,
UNIQUE KEY (email)
)engine=MyIsam;
ストアドプロシージャ:
-- drop procedure putInThing;
delimiter $$
create procedure putInThing
(
email_In varchar(100), version_In varchar(20)
)
BEGIN
declare toUse int;
declare theCount int;
select count(*) into theCount from thing where email=email_In;
select id into toUse from thing where email=email_In; -- useful for result set @end
IF theCount=1 THEN
-- was there, do UPDATE
update thing set version=version_In,lastupdate=now() where email=email_In;
ELSE
-- new row, do INSERT (please note the FOR UPDATE clause)
select nextnum into toUse from ocd_nextnums where tableName='thing' FOR UPDATE;
update ocd_nextnums set nextnum=nextnum+1 where tableName='thing';
insert thing(id,email,version,lastupdate) values (toUse,email_In,version_In,now());
end if;
select toUse; -- <------- that was your id
END
$$
テスト:
call putInThing('[email protected]','111');
call putInThing('[email protected]','121');
call putInThing('[email protected]','107');
select * from thing;
+----+----------+---------+---------------------+
| id | email | version | lastupdate |
+----+----------+---------+---------------------+
| 1 | [email protected] | 111 | 2015-08-14 17:08:10 |
| 2 | [email protected] | 121 | 2015-08-14 17:08:54 |
| 3 | [email protected] | 107 | 2015-08-14 17:08:56 |
+----+----------+---------+---------------------+
call putInThing('[email protected]','101111007'); -- is an update
call putInThing('[email protected]','42'); -- is an update
call putInThing('[email protected]','10007'); -- is an update
call putInThing('[email protected]','1'); -- is an insert
select * from thing;
+----+----------------------+---------+---------------------+
| id | email | version | lastupdate |
+----+----------------------+---------+---------------------+
| 1 | [email protected] | 111 | 2015-08-14 17:08:10 |
| 2 | [email protected] | 121 | 2015-08-14 17:08:54 |
| 3 | [email protected] | 10007 | 2015-08-14 17:22:09 |
| 4 | [email protected] | 1 | 2015-08-14 17:22:47 |
+----+----------------------+---------+---------------------+
マニュアル のMysqlINNODB部分から :
私がこれを使っているのを見ますか、おそらくそうではありません。見せているだけです。私はギャップと夜寝て元気です。そのため、最初のテーブルに自分が行ったことに名前を付けました:>