Làm thế nào bạn có thể có hai cột tăng tự động trong một bảng?


8

Tôi có một bảng MySQL chứa thông tin về hóa đơn của một công ty. Tuy nhiên, công ty này có hai chi nhánh và mỗi chi nhánh có một trình tự lập hóa đơn duy nhất; một "Serie A" và "Serie B", có thể nói như vậy. Tuy nhiên, đây là một công ty duy nhất và tôi không muốn tạo hai bảng hóa đơn. Thay vào đó, bằng cách nào đó tôi muốn có hai mức tăng tự động khác nhau cho một bảng. Tôi biết điều này là không thể về mặt kỹ thuật, nhưng tôi đoán đây là vấn đề mà những người khác đã giải quyết trước đây, vì vậy tôi muốn biết liệu có một "giải pháp" nổi tiếng nào cho vấn đề này không?

Những gì tôi đang làm bây giờ không phải là sử dụng khóa chính làm số hóa đơn (sẽ là lý tưởng), mà là sử dụng cột phụ với id hóa đơn, được tăng theo cách thủ công (tốt, sử dụng tập lệnh PHP, nhưng nó vẫn không tự động ), bằng cách kiểm tra hóa đơn mới nhất cho loạt cụ thể đó.

Đây là thiết lập hiện tại của tôi:

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

Để kiểm tra hóa đơn lateset, tôi chạy:

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

Câu trả lời:


11

Những gì bạn đang đề xuất chỉ có thể được thực hiện với MySQL trong ba điều kiện (3)

  • ĐIỀU KIỆN # 1 : Sử dụng công cụ lưu trữ MyISAM
  • ĐIỀU KIỆN # 2 : Biến phần cột auto_increment của khóa chính ghép
  • ĐIỀU KIỆN # 3 : Mỗi auto_increment cho một loại nhất định phải tồn tại trong hàng riêng của nó
  • Xem tài liệu auto_increment cho MyISAM

Đây là cách bố trí bảng gốc của bạn

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

Dựa trên ba điều kiện tôi vừa đề cập, đây là cách bố trí bảng đề xuất mới:

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

Dưới đây là một ví dụ thông qua dữ liệu mẫu và 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;

Ở đây nó được thực thi:

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>

Hãy thử một lần !!!

CAVEAT: Hiện tại, chỉ có MyISAM Storage Engine hỗ trợ nhiều giá trị auto_increment được nhóm với các cột khác. Điều này là không thể với InnoDB dựa trên các cột auto_increment được gắn trực tiếp vào gen_clust_index (còn gọi là Chỉ mục cụm) !!!


Đây là TUYỆT VỜI TUYỆT VỜI! Tôi không biết điều này là có thể ... cảm ơn vì đã khai sáng cho tôi !!
Người dùng402841

Bạn có thể làm một điều (tương tự) trong InnoDB nhưng thật không may, nó không hoạt động như một hy vọng. Invicenumbers sẽ là (1,3,5,7)(2,4,6)cho hai nhánh tương ứng :(
ypercubeᵀᴹ

Thực sự quá tệ, nó không hoạt động với InnoDB!
Người dùng402841

@user, nếu InnoDB là cần thiết (trong trường hợp của tôi, tôi cần cho khóa ngoại), bạn có thể sử dụng trình kích hoạt để mô phỏng gia tăng tự động đa trường. Xem bài đăng này
Murta

0

Sử dụng trình kích hoạt chèn sau trên bảng hóa đơn để đặt giá trị của số hóa đơn sau khi hàng được chèn thành công.

Điều này có nghĩa là bạn không phải thực hiện tính toán trong tập lệnh PHP của mình mà trong cơ sở dữ liệu.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.