mysql - 2 auto_increment 字段,其中 1 重置

标签 mysql database-design innodb auto-increment

我将编写几个 MySQL 表来处理发票。

我的计划是将其分成 3 个主要表格:

create table invoice
(
  id auto_increment,
  client (foreign key),
  created (date),
  *etc*...
)

create table products
(
  id auto_increment
  *product info*...
)

create table invoice_products
(
  invoice_id (references invoice.id)
  row (resetting auto_increment)  <--THIS!!!
  product_id(references products.id)
  product_quantity INT
  primary key (invoice_id,row)
)

问题是,当创建新发票时,invoice.id 是 auto_incremented,这是应该的。我不希望每张新发票的 invoice_products.row 从 1 开始。 因此,对于每个新发票,行 auto_increment 将从 1 开始,但如果将新行添加到现有发票 ID,行 ID 将从它停止的地方继续。

关于如何实现这一点有什么建议吗?

(我希望简短版本的代码足以让您理解困境)

提前感谢您的任何建议!

编辑:澄清:数据库中的所有表都是 InnoDB(因为大量使用外键约束)

最佳答案

您所要做的就是将表更改为使用 MyISAM 引擎。但请注意,MyISAM 不支持事务和外键。

无论如何,这是一个如何工作的例子(引用 manual ):

For MyISAM and BDB tables you can specify AUTO_INCREMENT on a secondary column in a multiple-column index. In this case, the generated value for the AUTO_INCREMENT column is calculated as MAX(auto_increment_column) + 1 WHERE prefix=given-prefix. This is useful when you want to put data into ordered groups.

CREATE TABLE animals (
    grp ENUM('fish','mammal','bird') NOT NULL,
    id MEDIUMINT NOT NULL AUTO_INCREMENT,
    name CHAR(30) NOT NULL,
    PRIMARY KEY (grp,id)
) ENGINE=MyISAM;

INSERT INTO animals (grp,name) VALUES
    ('mammal','dog'),('mammal','cat'),
    ('bird','penguin'),('fish','lax'),('mammal','whale'),
    ('bird','ostrich');

SELECT * FROM animals ORDER BY grp,id;

Which returns:

+--------+----+---------+
| grp    | id | name    |
+--------+----+---------+
| fish   |  1 | lax     |
| mammal |  1 | dog     |
| mammal |  2 | cat     |
| mammal |  3 | whale   |
| bird   |  1 | penguin |
| bird   |  2 | ostrich |
+--------+----+---------+

In this case (when the AUTO_INCREMENT column is part of a multiple-column index), AUTO_INCREMENT values are reused if you delete the row with the biggest AUTO_INCREMENT value in any group. This happens even for MyISAM tables, for which AUTO_INCREMENT values normally are not reused.

If the AUTO_INCREMENT column is part of multiple indexes, MySQL will generate sequence values using the index that begins with the AUTO_INCREMENT column, if there is one. For example, if the animals table contained indexes PRIMARY KEY (grp, id) and INDEX (id), MySQL would ignore the PRIMARY KEY for generating sequence values. As a result, the table would contain a single sequence, not a sequence per grp value.

如您所见,您的主键和 auto_increment 设置已经正确。只需更改为 MyISAM。


如果不想用MyISAM,也可以边选择边计算。

SELECT
ip.*,
@row := IF(@prev_inv != invoice_id, 1, @row + 1) AS `row`,
@prev_inv := invoice_id
FROM invoice_products ip
, (SELECT @row:=1, @prev_inv:=NULL) vars
ORDER BY invoice_id

而第三种可能当然是在数据库外计算。我会留给你:)

关于mysql - 2 auto_increment 字段,其中 1 重置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19366493/

相关文章:

MySQL通过乘法自增字段

mysql - Typeahead.js 未填充搜索框

sql-server - 数据库设计 Microsoft SQL Server

sql - 在具有现有一对多关系的表之间创建一对一关系

mysql - STR_TO_DATE 返回 null

Mysql打印帮助而不是连接到服务器

mysql - 树状分类系统的数据库设计

mysql 插入并选择带有插入id的行

mysql - 如何发现MariaDB崩溃的原因?

mysql - 使用 Laravel 队列时如何避免作业数据库表锁问题?