sql >> データベース >  >> RDS >> Mysql

重複キーでのPHP+MYSQLは、引き続きINDEXキーを増やします

    はい、今私はこの問題を覚えています。かつて挿入をしたいと思っていた人がいましたが、各挿入は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部分から :

    私がこれを使っているのを見ますか、おそらくそうではありません。見せているだけです。私はギャップと夜寝て元気です。そのため、最初のテーブルに自分が行ったことに名前を付けました:>



    1. Entity Framework:データベース内の多数の関連テーブルを1回のトリップでクエリする方法

    2. フロントエンドでのラジオボタンの作成(PHP)

    3. UNIXでoracleを使用してフラットファイルで出力を取得する

    4. PL/pgSQL関数のオプションの引数