一个表中如何有两个自动增量列?


8

我有一个MySQL表,其中包含有关公司发票的信息。但是,该公司有两个分支机构,每个分支机构都有唯一的发票顺序;可以说是“意甲”和“乙”。但是,这是一家公司,我不想创建两个发票表。相反,我不知何故要为一个表具有两个不同的自动增量。我知道从技术上讲这是不可能的,但是我想这是其他人以前解决过的问题,所以我想知道是否有众所周知的“解决方案”吗?

我现在正在执行的操作不是使用主键作为发票编号(这是理想的选择),而是使用带有发票ID的辅助列,该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'

Answers:


11

您打算做的事情只能在三(3)个条件下使用MySQL干净地完成

  • 条件#1:使用MyISAM存储引擎
  • 条件#2:使auto_increment列成为复合主键的一部分
  • 条件#3:给定类型的每个auto_increment必须存在于自己的行中
  • 请参阅MyISAM的auto_increment文档

这是您的原始表格布局

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

根据我刚才提到的三个条件,这是新的建议表布局:

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>

试试看 !!!

CAVEAT:目前,只有MyISAM存储引擎支持与其他列分组的多个auto_increment值。对于基于auto_increment列的InnoDB,直接将其绑定到gen_clust_index(又称为聚集索引),这是不可能的!


这太棒了!我不知道这是可能的...感谢开导我!
2012年

您可以在InnoDB中做一件(类似的)事情,但是不幸的是,它并没有像人们希望的那样起作用。该invicenumbers会(1,3,5,7)(2,4,6)两个分支分别为:(
ypercubeᵀᴹ

真的太糟糕了,它对于InnoDB不起作用!
User402841

@user,如果需要InnoDB(在我的情况下,我需要外键),则可以使用触发器来模拟多字段自动增量。看到这篇文章
Murta

0

一旦成功插入行,请在发票表上使用插入后触发器来设置发票号的值。

这意味着您不必在PHP脚本中进行计算,而在数据库中进行计算。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.