1つのテーブルに2つの自動インクリメンタル列を設定するにはどうすればよいですか?


8

会社の請求書に関する情報を含むMySQLテーブルがあります。ただし、この会社には2つの支店があり、それぞれに固有の請求シーケンスがあります。いわば「セリエA」と「セリエB」。ただし、これは1つの会社であり、2つの請求書テーブルを作成したくありません。むしろ、1つのテーブルに2つの異なる自動インクリメントを設定したいのです。これは技術的に不可能であることはわかっていますが、これは他の人が以前に取り組んだ問題だと思うので、この問題の既知の「解決策」があるかどうか知りたいですか?

私が今行っているのは、請求書番号としてプライマリキーを使用すること(これは理想的です)ではなく、手動でインクリメントされる請求書IDを持つセカンダリ列を使用することです(まあ、PHPスクリプトを使用しますが、それでも自動ではありません) )、その特定のシリーズの最新の請求書を確認する。

これは私の現在の設定です:

CREATE TABLE `invoices` (
  `id` mediumint unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `invoicenumber` mediumint unsigned NOT NULL,
  `branch` enum('A','B') NOT NULL,
  `date` date NOT NULL,
  `client` varchar(100) NOT NULL
) COMMENT='' ENGINE='InnoDB';

最新の請求書を確認するには、次のコマンドを実行します。

SELECT MAX(invoicenumber+1) AS new_invoice_number FROM invoices WHERE branch = 'A'

回答:


11

あなたがすることを提案していることは、3つの(3)条件の下でMySQLできれいに行うことができるだけです

これが元のテーブルレイアウトです

CREATE TABLE `invoices` ( 
  `id` mediumint unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, 
  `invoicenumber` mediumint unsigned NOT NULL, 
  `branch` enum('A','B') NOT NULL, 
  `date` date NOT NULL, 
  `client` varchar(100) NOT NULL 
) COMMENT='' ENGINE='InnoDB'; 

今述べた3つの条件に基づいて、新しく提案されたテーブルレイアウトは次のとおりです。

CREATE TABLE `invoices` ( 
  `invoicenumber` mediumint unsigned NOT NULL auto_increment, 
  `branch` enum('A','B') NOT NULL, 
  `date` date NOT NULL, 
  `client` varchar(100) NOT NULL,
  PRIMARY KEY (branch,invoicenumber)
) COMMENT='' ENGINE='MyISAM'; 

サンプルデータとSQLによる例を次に示します。

drop database if exists user1162541;
create database user1162541;
use user1162541
CREATE TABLE `invoices` ( 
  `invoicenumber` mediumint unsigned NOT NULL auto_increment, 
  `branch` enum('A','B') NOT NULL, 
  `date` date NOT NULL, 
  `client` varchar(100) NOT NULL,
  PRIMARY KEY (branch,invoicenumber)
) COMMENT='' ENGINE='MyISAM'; 
INSERT INTO invoices (branch,date,client) VALUES
('A',DATE(NOW()),'John'),
('B',DATE(NOW()),'Jack'),
('A',DATE(NOW()),'Jeff'),
('B',DATE(NOW()),'Joel'),
('A',DATE(NOW()),'Jane'),
('B',DATE(NOW()),'Joan'),
('A',DATE(NOW()),'June');
SELECT * FROM invoices ORDER BY branch,invoicenumber;

ここで実行されます:

mysql> drop database if exists user1162541;
Query OK, 1 row affected (0.01 sec)

mysql> create database user1162541;
Query OK, 1 row affected (0.02 sec)

mysql> use user1162541
Database changed
mysql> CREATE TABLE `invoices` (
    ->   `invoicenumber` mediumint unsigned NOT NULL auto_increment,
    ->   `branch` enum('A','B') NOT NULL,
    ->   `date` date NOT NULL,
    ->   `client` varchar(100) NOT NULL,
    ->   PRIMARY KEY (branch,invoicenumber)
    -> ) COMMENT='' ENGINE='MyISAM';
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO invoices (branch,date,client) VALUES
    -> ('A',DATE(NOW()),'John'),
    -> ('B',DATE(NOW()),'Jack'),
    -> ('A',DATE(NOW()),'Jeff'),
    -> ('B',DATE(NOW()),'Joel'),
    -> ('A',DATE(NOW()),'Jane'),
    -> ('B',DATE(NOW()),'Joan'),
    -> ('A',DATE(NOW()),'June');
Query OK, 7 rows affected (0.02 sec)
Records: 7  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM invoices ORDER BY branch,invoicenumber;
+---------------+--------+------------+--------+
| invoicenumber | branch | date       | client |
+---------------+--------+------------+--------+
|             1 | A      | 2012-04-21 | John   |
|             2 | A      | 2012-04-21 | Jeff   |
|             3 | A      | 2012-04-21 | Jane   |
|             4 | A      | 2012-04-21 | June   |
|             1 | B      | 2012-04-21 | Jack   |
|             2 | B      | 2012-04-21 | Joel   |
|             3 | B      | 2012-04-21 | Joan   |
+---------------+--------+------------+--------+
7 rows in set (0.00 sec)

mysql>

試してみる !!!

警告:現在、MyISAMストレージエンジンのみが、他の列とグループ化された複数のauto_increment値をサポートしています。これは、gen_clust_index(別名クラスター化インデックス)に直接結び付けられているauto_incrementカラムに基づくInnoDBでは不可能です。


これは完全に素晴らしいです!これが可能だとは思いもしませんでした...
User402841

InnoDBで(同様の)ことを実行できますが、残念ながら、期待どおりに機能しません。invicenumbersは次のようになります(1,3,5,7)し、(2,4,6)それぞれ二つの枝のため:(
ypercubeᵀᴹ

本当にひどいのでInnoDBでは機能しません!
User402841

@ user、InnoDBが必要な場合(私の場合は外部キーが必要です)、トリガーを使用して複数フィールドの自動インクリメントをシミュレートできます。この投稿を
Murta、2015

0

行が正常に挿入されたら、請求書テーブルで挿入後トリガーを使用して、請求書番号の値を設定します。

つまり、PHPスクリプトではなくデータベースで計算を行う必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.