web-dev-qa-db-ja.com

MySQL phpmyadminで2つの自動インクリメント列を使用する方法

2つの自動インクリメント値を使用することは可能ですか?

  • 0から始まる1つ
  • 4000400から始まる別のもの

私を助けてください

6
user2106221

いいえ、できません。箱から出していない。可能な回避策:

  1. トリガーAFTER INSERTトリガー)。

    短所:

    • 明白な恐怖。メンテナンスやデバッグの悪夢など、トリガーの他のすべての欠点が付属しています。

    利点:

    • この列を参照するFOREIGN KEY制約を設定できます。
    • 最初と2番目のid列を個別に更新できます。
  2. ビュー。最初の自動インクリメント値の常に+4000400である値のみの場合は、ビューを使用できるため、基本的にこの値をまったく格納せず、必要なときに計算するだけです。

        CREATE VIEW 
            tablex_with_2nd_AI AS
        SELECT 
            tablex_id,
            colA,                                 -- other columns
            --                                    -- you need
            tablex_ix + 4000400  AS second_id
        FROM 
            tablex ;
    

    短所:

    • この(仮想)列を参照するFOREIGN KEY制約は使用できません。

    利点:

    • スペースを節約します。やや速い挿入。
  3. それをしないでください 2番目の自動インクリメント列はありません。 2番目の自動インクリメント値が本当に必要ですか?何のために?あなたが解決しようとしている実際の問題の説明は、他の人があなたをよりよく助けるのに役立ちます。ここでは、実際に問題を解決するのではなく、問題を解決する方法を説明しただけだと思います。

6
ypercubeᵀᴹ

良いニュースと悪いニュースがあります

良いニュース

複数のauto_increment値を使用できます

悪いニュース

2つのこと:

  1. MyISAMストレージエンジンでのみ使用できます
  2. 使用できるauto_increment値は1つだけです。同じテーブル内の他のauto_increment値からの一意性を定義するには、各auto_incrementに関連付けられた列が必要です。

私はこれについて前に話しました

これがサンプルの表です

USE test
DROP TABLE IF EXISTS stores;
CREATE TABLE stores
(
    store_type int not null,
    id int not null auto_increment,
    store_name varchar(128) not null,
    PRIMARY KEY (store_type,id)
) ENGINE=MyISAM;

ここにサンプルデータがあります

INSERT INTO stores (store_type,store_name) VALUES
(1,'Red Lobster'),(1,'Olive Garden'),
(2,'ShopRite'),(2,'PathMark'),(2,'Wegman''s'),
(3,'McDonald''s'),(3,'Wendy''s'),(3,'Burger King'),
(1,'Ruby Tuesdays'),(1,'TGI Fridays'),
(4,'BJs'),(4,'Costco'),(1,'Bennigan''s');

読み込みましょう

mysql> USE test
Database changed
mysql> DROP TABLE IF EXISTS stores;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE stores
    -> (
    ->     store_type int not null,
    ->     id int not null auto_increment,
    ->     store_name varchar(128) not null,
    ->     PRIMARY KEY (store_type,id)
    -> ) ENGINE=MyISAM;
Query OK, 0 rows affected (0.08 sec)

mysql> INSERT INTO stores (store_type,store_name) VALUES
    -> (1,'Red Lobster'),(1,'Olive Garden'),
    -> (2,'ShopRite'),(2,'PathMark'),(2,'Wegman''s'),
    -> (3,'McDonald''s'),(3,'Wendy''s'),(3,'Burger King'),
    -> (1,'Ruby Tuesdays'),(1,'TGI Fridays'),
    -> (4,'BJs'),(4,'Costco'),(1,'Bennigan''s');
Query OK, 13 rows affected (0.00 sec)
Records: 13  Duplicates: 0  Warnings: 0

mysql>

次に、データを確認します。

mysql> SELECT * FROM stores;
+------------+----+---------------+
| store_type | id | store_name    |
+------------+----+---------------+
|          1 |  1 | Red Lobster   |
|          1 |  2 | Olive Garden  |
|          2 |  1 | ShopRite      |
|          2 |  2 | PathMark      |
|          2 |  3 | Wegman's      |
|          3 |  1 | McDonald's    |
|          3 |  2 | Wendy's       |
|          3 |  3 | Burger King   |
|          1 |  3 | Ruby Tuesdays |
|          1 |  4 | TGI Fridays   |
|          4 |  1 | BJs           |
|          4 |  2 | Costco        |
|          1 |  5 | Bennigan's    |
+------------+----+---------------+
13 rows in set (0.00 sec)

mysql>

次に、PRIMARY KEY列で並べ替えられたデータを確認します。

mysql> SELECT * FROM stores ORDER BY store_type,id;
+------------+----+---------------+
| store_type | id | store_name    |
+------------+----+---------------+
|          1 |  1 | Red Lobster   |
|          1 |  2 | Olive Garden  |
|          1 |  3 | Ruby Tuesdays |
|          1 |  4 | TGI Fridays   |
|          1 |  5 | Bennigan's    |
|          2 |  1 | ShopRite      |
|          2 |  2 | PathMark      |
|          2 |  3 | Wegman's      |
|          3 |  1 | McDonald's    |
|          3 |  2 | Wendy's       |
|          3 |  3 | Burger King   |
|          4 |  1 | BJs           |
|          4 |  2 | Costco        |
+------------+----+---------------+
13 rows in set (0.00 sec)

mysql>

試してみる !!!

更新2013-02-26 12:00 EST

id値に4000400を追加して、SuperMarkets(store_type 2)を拡張してみましょう

mysql> UPDATE stores SET id = id + 4000400 WHERE store_type = 2;
Query OK, 3 rows affected (0.02 sec)
Rows matched: 3  Changed: 3  Warnings: 0

mysql> SELECT * FROM stores ORDER BY store_type,id;
+------------+---------+---------------+
| store_type | id      | store_name    |
+------------+---------+---------------+
|          1 |       1 | Red Lobster   |
|          1 |       2 | Olive Garden  |
|          1 |       3 | Ruby Tuesdays |
|          1 |       4 | TGI Fridays   |
|          1 |       5 | Bennigan's    |
|          2 | 4000401 | ShopRite      |
|          2 | 4000402 | PathMark      |
|          2 | 4000403 | Wegman's      |
|          3 |       1 | McDonald's    |
|          3 |       2 | Wendy's       |
|          3 |       3 | Burger King   |
|          4 |       1 | BJs           |
|          4 |       2 | Costco        |
+------------+---------+---------------+
13 rows in set (0.00 sec)

mysql>

A & Pを別のスーパーマーケットとして追加しましょう

mysql> INSERT INTO stores (store_type,store_name) VALUES (2,'A & P');
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM stores ORDER BY store_type,id;
+------------+---------+---------------+
| store_type | id      | store_name    |
+------------+---------+---------------+
|          1 |       1 | Red Lobster   |
|          1 |       2 | Olive Garden  |
|          1 |       3 | Ruby Tuesdays |
|          1 |       4 | TGI Fridays   |
|          1 |       5 | Bennigan's    |
|          2 | 4000401 | ShopRite      |
|          2 | 4000402 | PathMark      |
|          2 | 4000403 | Wegman's      |
|          2 | 4000404 | A & P         |
|          3 |       1 | McDonald's    |
|          3 |       2 | Wendy's       |
|          3 |       3 | Burger King   |
|          4 |       1 | BJs           |
|          4 |       2 | Costco        |
+------------+---------+---------------+
14 rows in set (0.00 sec)

mysql>

それはあなたのために働くことができるように見えます!!!

3
RolandoMySQLDBA

私はこの問題に遭遇しただけで、答えに貢献したいと思います。 Ypercubeの答えを使って解決しましたが、少し異なります。最初に、

IDの他に2番目の自動インクリメント列が必要なのはなぜですか?

いくつかのオブジェクトがあり、その量はかなり機密性の高い企業情報になる可能性があります。たとえば、user_id 37で、自分のWebサイトに37人のユーザーしかいないと提案したくない場合があります。クレームの数、購入の数、ユーザー、競合他社、または規制当局に知られたくない、良い点と悪い点の数。

しかし、少なくとも私の場合は、これらのオブジェクトに公開されている一意の番号を割り当てて、ユーザー入力でオブジェクトを簡単に管理できるようにすると便利です。たとえば、SEに関するこの質問の番号は35449です。ブラウザに次の番号を入力して取得できます:https://dba.stackexchange.com/questions/35449

そして最後に、IDを不明瞭にしようとする複雑なオーバーヘッドを作りたくありません。 IDより大きい数値の自動インクリメント。

それが問題です。 Ypercubeの答えはかなりクールな解決策を持っています、IDに定数を追加するだけです。私だけがPHP追加のクエリを使用する場合はPHP $ ===で実行し、別の関数に入れましたので、簡単に追跡でき、SQLの他の部分と密接に結合しません。 。それは遅いですが、私と同じように管理するのは簡単です。

complaint_idrefund_idのような負の値の出現量を減らそうとする場合は、負にならないように減算しないでください。数十億以上の巨大な乱数を追加してください。例:id + 159035466234)これにより、オブジェクトの量とは関係がないことが明らかになります。

0
Arthur Tarasov

[トリガー]タブをご覧ください。トリガーに基づいて、挿入に基づいて2番目の自動インクリメント列を更新できます。

    CREATE TABLE IF NOT EXISTS test2 (
    id          int(11) NOT NULL AUTO_INCREMENT,
    another_id      int(11) ,
    blah        varchar(250),
    PRIMARY KEY (`id`)  
)   ENGINE=MyISAM  DEFAULT CHARSET=latin1 ; 

テーブルに行が挿入されると、トリガーは列 'another_id'(40004000に設定)を増分する必要があります

0
acutesoftware