Bagaimana Anda bisa memiliki dua kolom penambahan otomatis dalam satu tabel?

8

Saya memiliki tabel MySQL yang berisi informasi tentang faktur perusahaan. Namun, perusahaan ini memiliki dua cabang, dan masing-masing memiliki urutan faktur yang unik; "Serie A" dan "Serie B", bisa dikatakan. Namun, ini adalah satu perusahaan tunggal dan saya tidak ingin membuat dua tabel faktur. Sebaliknya, saya entah bagaimana ingin memiliki dua peningkatan otomatis yang berbeda untuk satu tabel. Saya tahu ini secara teknis tidak mungkin, tapi saya kira ini adalah masalah yang sudah ditangani orang lain sebelumnya, jadi saya ingin tahu apakah ada 'solusi' terkenal untuk masalah ini?

Apa yang saya lakukan saat ini adalah tidak menggunakan kunci utama sebagai nomor faktur (yang akan ideal), melainkan menggunakan kolom sekunder dengan id faktur, yang ditambahkan secara manual (baik, menggunakan skrip PHP, tetapi masih tidak otomatis ), dengan memeriksa faktur terbaru untuk seri tersebut.

Ini adalah pengaturan saya saat ini:

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

Untuk memeriksa faktur lateset, saya menjalankan:

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

Pengguna402841
sumber

Jawaban:

11

Apa yang Anda usulkan hanya dapat dilakukan dengan MySQL secara bersih dalam tiga (3) kondisi

  • KONDISI # 1 : Gunakan mesin penyimpanan MyISAM
  • KONDISI # 2 : Jadikan kolom auto_increment bagian dari kunci utama gabungan
  • KONDISI # 3 : Setiap auto_increment untuk jenis yang diberikan harus ada di barisnya sendiri
  • Lihat dokumentasi auto_increment untuk MyISAM

Ini adalah tata letak tabel asli Anda

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

Berdasarkan tiga kondisi yang baru saja saya sebutkan, berikut adalah tata letak tabel yang baru diusulkan:

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

Berikut ini adalah contoh melalui data sampel dan 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;

Ini dia dijalankan:

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>

Cobalah !!!

CAVEAT: Saat ini, hanya Mesin Penyimpanan MyISAM yang mendukung beberapa nilai auto_increment yang dikelompokkan dengan kolom lainnya. Ini tidak mungkin dengan InnoDB berdasarkan kolom auto_increment yang diikat langsung ke gen_clust_index (alias Clustered Index) !!!

RolandoMySQLDBA
sumber
Ini BENAR-BENAR MENGAGUMKAN! Saya tidak tahu ini mungkin ... terima kasih telah mencerahkan saya !!
User402841
Anda dapat melakukan hal (mirip) di InnoDB tetapi sayangnya itu tidak berfungsi seperti yang diharapkan. Para invicenumber akan menjadi (1,3,5,7)dan (2,4,6)untuk dua cabang masing-masing :(
ypercubeᵀᴹ
Sayang sekali itu tidak bekerja untuk InnoDB!
User402841
@ Pengguna, jika InnoDB diperlukan (dalam kasus saya, saya diperlukan untuk kunci asing), Anda dapat menggunakan pemicu untuk mensimulasikan peningkatan multi bidang otomatis. Lihat posting ini
Murta
0

Gunakan pemicu setelah insert pada tabel faktur untuk menetapkan nilai nomor faktur setelah baris berhasil dimasukkan.

Ini berarti bahwa Anda tidak harus melakukan perhitungan dalam skrip PHP Anda, tetapi dalam database.

Stephen Senkomago Musoke
sumber