【问题标题】:schema and table design with auto_increment field that is not a key具有不是键的 auto_increment 字段的架构和表设计
【发布时间】:2011-09-27 13:28:53
【问题描述】:

我有一个发票号码,这个号码与一个特殊文件相关联。这个文档有一个id,由一个累进数字和当前年份组成,像这样

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

每年的累进数字从 1 开始

1-2012
2-2012
3-2012

首先,我想用 invoice_n、prog_n、year 制作一个表格。 prog_n 是 AUTO_INCREMENT 并且每年我都会重置它。但是您不能使用不是键的 AUTO_INCREMENT 字段。反正我要重置计数器,这不太推荐……

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

环境是经典的 LAMP

非常感谢!

【问题讨论】:

    标签: mysql database database-design database-schema


    【解决方案1】:

    扩展@Marius 的答案,我会使用触发器让 MySQL 自动设置 invoicenumber,如下所示:

    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,以便可以使用该字段上的索引。

    见:
    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

    【讨论】:

    • 非常好,我不知道触发器。现在我正在阅读一些关于它们的文档,据我所知,我可以在不指定特殊字段的情况下进行插入。触发器和 DBMS 现在关心它。对吗?
    • 除了NEW 虚拟表之外,您无法影响触发器链接到的表。但是,您可以更改其他表格。
    【解决方案2】:

    您可以在您的发票表中有一个单独的id 列和auto_increment,以及一个使用以下公式填充prog_n 的触发器:

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

    这样,您的prog_n 每年都会自动重置,您无需手动进行。但是,如果您在表中插入大量发票,则可能会出现性能问题,但我认为这在实践中不会发生。

    【讨论】:

      猜你喜欢
      • 2013-01-03
      • 2011-12-09
      • 1970-01-01
      • 2020-10-18
      • 1970-01-01
      • 2011-05-05
      • 2014-01-13
      • 2011-01-28
      • 1970-01-01
      相关资源
      最近更新 更多