sql >> Databasteknik >  >> RDS >> Mysql

PHP + MYSQL på Duplicate KEY ökar fortfarande INDEX KEY

ok ja, nu kommer jag ihåg det här problemet. Det var en kille en gång som ville göra inserts, men varje insert måste vara i steg om 100 om du kunde föreställa dig att börja @1000. Och vi var tvungna att slå in det hela i en lagrad proc för att ha en plats för sårbarhet. Ditt problem dök upp och det kastade bort hans numrering med 1 eller så.

Genom att linda in det skulle vi kunna ha en enda poäng att göra det, med ett lås, och behålla auto_inc-värdet med ALTER TABLE

Det andra tillvägagångssättet jag sa till honom var att ha en inkrementeringstabell, lås 1-raden, hämta värdet i den raden, använd den, uppdatera incTablen med 100. lås upp.

Hela tiden skrattade vi åt OCD-problem. Jag tror att han bara gillade multipler av 10, idk

Redigera:

Schema:

-- 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;

Lagrad proc:

-- 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
$$

Test:

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 |
+----+----------------------+---------+---------------------+

Från Mysql INNODB-delen av manual :

Kommer du att se mig använda detta, förmodligen inte. Bara att visa det. Jag mår bra med luckor och sover på nätterna. Det är därför jag döpte den första tabellen till vad jag gjorde :>



  1. Runtime.getRuntime().exec för att skicka parametern när du uppmanas

  2. välj ett slumpmässigt värde baserat på sannolikhetschans

  3. Hur man aktiverar bulkbehörighet i SQL Server

  4. Steg för att ändra administratörslösenord som har förlorats eller glömts av en EBS WebLogic Domain R12.2