sql >> Database teknologi >  >> RDS >> Mysql

PHP + MYSQL på Duplicate KEY øger stadig INDEX KEY

ok ja, nu husker jeg dette problem. Der var engang en fyr, der ville lave inserts, men hver insert skulle være i intervaller på 100 hvis du kunne forestille dig, at starte @1000. Og vi var nødt til at pakke det hele ind i en lagret proc for at have ét sårbart sted. Dit problem dukkede op, og det afskaffede hans nummerering med 1 eller deromkring.

Ved at pakke det ind, kunne vi fornuftigt have et punkt med at gøre det, med en lås, og bevare auto_inc-værdien med ALTER TABLE

Den anden fremgangsmåde, jeg sagde til ham, var at have en inkrementeringstabel, lås 1 rækken, få værdien i den række, brug den, opdater den incTable med 100. lås op.

Hele tiden grinede vi af OCD-problemer. Jeg tror, ​​at han kun kunne lide multipla af 10, idk

Rediger:

Skema:

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

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

Fra Mysql INNODB-delen af ​​Manual :

Vil du se mig bruge dette, sandsynligvis ikke. Bare viser det. Jeg har det fint med huller og sover om natten. Derfor navngav jeg den første tabel, hvad jeg gjorde :>



  1. Hvordan genererer man automatisk et unikt id i SQL som UID12345678?

  2. Kan ikke indsætte Varchar2-data ved hjælp af lagret procedure med tabeltype som IN-parameter

  3. Sikkerhed på rækkeniveau virker ikke for tabelejer

  4. Opret forespørgsel for at få optælling af uafsluttede opkald