繁体   English   中英

auto_increment字段不是关键的架构和表设计

[英]schema and table design with auto_increment field that is not a key

我有发票号码,该号码与特殊文件相关。 该文档具有一个由序号和当前年份组成的ID,例如

222-2011
223-2011
224-2011
...

每年递增数从1重新开始

1-2012
2-2012
3-2012

首先,我想制作一张带有invoice_n,prog_n,年份的表格。 prog_n是AUTO_INCREMENT,每年我都会重置它。 但是您不能使用不是关键的AUTO_INCREMENT字段。 无论如何,我要重置计数器,因此不建议这样做...

我无法更改ID格式,必须使用该规则。 我可以以某种方式进行有效的设计吗?

环境是经典的LAMP

非常感谢!

您可以在发票表中使用auto_increment单独创建一个id列,并使用以下公式填充一个prog_n触发器:

prog_n = id - select max(id) from invoices where year = current_year - 1

这样,您的prog_n都会自动重置,而无需手动进行。 但是,如果您在表中插入很多发票,则可能是性能问题,但我认为实际上不会发生这种情况。

扩展@Marius答案,我将使用触发器让MySQL自动设置发票编号,如下所示:

DELIMITER $$

CREATE TRIGGER bi_invoices_each BEFORE INSERT ON invoices FOR EACH ROW
BEGIN
  DECLARE lastest_invoice_number VARCHAR(20);
  DECLARE numberpart INTEGER;

  -- find lastest invoicenumber in the current year.
  SELECT COALESCE(max(invoicenumber),0) INTO lastest_invoice_number 
  FROM invoice 
  WHERE invoice_date >= MAKEDATE(YEAR(NEW.invoice_date)  ,1) 
    AND invoice_date <  MAKEDATE(YEAR(NEW.invoice_date)+1,1);

  -- extract the part before the '-'
  SET numberpart = SUBSTRING_INDEX(lastest_invoice_number,'-',1)

  SET NEW.invoicenumber = CONCAT(numberpart+1,'-',YEAR(NEW.invoice_date));
END $$

DELIMITER ;

请注意,您无法在before触发器中访问自动递增的ID;
只有在after触发器中才能执行此操作,但是不能在其中更改任何值,因此需要一些技巧。
使用更多技巧来确保我们在选择查询中invoice_date原样使用invoice_date ,以便可以使用该字段上的索引。

看到:
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_substring-index
http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_makedate

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM