sql >> Database >  >> RDS >> Mysql

PHP + MYSQL op Duplicate KEY verhogen nog steeds de INDEX KEY

ok ja, nu herinner ik me dit probleem. Er was eens een man die invoegingen wilde doen, maar elke invoeging moest in stappen van 100 zijn als je je kunt voorstellen, beginnend met @1000. En we moesten het hele ding in een opgeslagen proces verpakken om één kwetsbaar punt te hebben. Uw probleem kwam aan het licht en zijn nummering werd met 1 of zo verschoven.

Door het in te pakken, zouden we het maar één punt kunnen hebben om het te doen, met een slot, en de auto_inc-waarde te behouden met ALTER TABLE

De andere benadering die ik tegen hem zei was om een ​​incrementele tabel te gebruiken, de 1 rij te vergrendelen, de waarde in die rij te krijgen, deze te gebruiken, die incTable bij te werken met 100. ontgrendel.

De hele tijd lachten we om OCS-problemen. Ik denk dat hij alleen veelvouden van 10 leuk vond, idk

Bewerken:

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;

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

Uit het Mysql INNODB-gedeelte van Handleiding :

Zie je me dit gebruiken, waarschijnlijk niet. Gewoon laten zien. Ik ben prima met gaten en slapen 's nachts. Daarom noemde ik de eerste tafel wat ik deed :>



  1. Apache NiFi

  2. Waarom wordt het als een slechte gewoonte beschouwd om cursors in SQL Server te gebruiken?

  3. Server wordt automatisch gesloten en geconfronteerd met de fout 'ERR_STREAM_WRITE_AFTER_END', samen met gegevens die elke keer naar de client worden verzonden

  4. django db-migratie mislukt met postgres