【问题标题】:Symfony2, Doctrine and MySQL: how to generate invoice numberSymfony2、Doctrine 和 MySQL:如何生成发票编号
【发布时间】:2012-11-02 20:12:07
【问题描述】:

使用 Symfony2.0、Doctrine 和 MySQL,我需要根据下一个格式自动生成相关发票编号:

年/自动增量

例如,2012 年的发票:

2012/00000001
2012/00000002
2012/00000003

等等……

该发票编号将使用我的 MySQL 数据库的 Purchase 表中的 invoice_number 字段进行存储。

问题是,我如何查询数据库以返回特定年份的最后一个自增数?

换句话说(伪代码):

function new_invoice(){
    $year = today.year;
    select last invoice_number where year = $year;
    $new_invoice_number = increment invoice_number;
    store $year . "/" . $new_invoice_number;
}

我该怎么做?

【问题讨论】:

    标签: mysql symfony doctrine


    【解决方案1】:

    首先,symfony2 和 dictionary2 都不是您的问题和解决方案的一部分。其次,您可能需要考虑在您的 invoice_number 中存储一个 /,主要是因为您需要为此字段设置一个 varchar,这在索引和查询项目等方面的性能比整数差。

    也就是说,您可以通过多种方式实现您想要的,具体取决于您的需求:

    选择最后一个条目,加一,保存

    此解决方案仅在您没有太多写入购买表或这些写入由一个进程(例如一批)完成时才有效,您可以在其中等待一个项目被写入并且如果成功写下一个。

    只需从数据库中选择最后一个条目,获取invoice_number,加一,保存。如果年份不同,请从一个开始。

    当然,如果您每秒有很多写入,您就会遇到麻烦,因为在您写入一行的那一刻,另外两个可能已经读取了旧的最后一个 invoice_number,将其加一并尝试存储它(导致错误因为它们必须是唯一的)。

    读取时动态计算

    如果您不需要经常使用invoice_number,此解决方案效果很好。你可以对一个想法有一个正常的 auto_increment 。对于每一年,您将去年的最后一个 id 存储在一些帮助表中。当你读取一行时,你可以通过获取年份、上一年的最后一个 id 并从 auto_increment 中减去它来计算 id。

    开销当然是您每次都需要计算发票。根据您实际实现它的方式以及数据库负载是什么,这可能从不明显到非常慢。

    让 invoice_number 为空,而不是计算它

    这可以通过多种不同的方式完成,如果您不想摆弄事务等,捕捉失败的写入等,这是一个非常简洁的解决方案。想法是先用空的 invoice_number 存储数据,然后在保存数据时计算 invoice_number 并更新数据集。

    您可以将它与之前的想法结合起来,像上面描述的那样计算 invoice_number,然后用这个数字更新数据集,而不是每次都重新计算它。您还可以有一个 cronjob 或寻找具有空 invoice_number 的行的东西,以及仅由该 cronjob 使用的助手表中的计数器之类的东西。他拿起计数器,将其递增,使用这是数据集的新发票并保存计数器和数据集。

    尝试,出错时重复

    这是一个丑陋的解决方案,但它可以工作并且在某些情况下可能没问题。您选择最后一个 invoice_number,将其加一,保存当前数据集。如果失败,则重复该过程。你这样做直到你成功储蓄。您需要确保在实际数据库上进行选择(doctrine2 可能会缓存结果,这意味着您始终获取旧数据集,增加相同的数字并因此一遍又一遍地遇到相同的错误)并且如果您有一些 master/从站设置不适用于从站,因为它可能不是最新的。

    我不喜欢这个解决方案,但正如我所说,这是值得考虑的。

    每年一张桌子

    每年可以将数据保存在一个表中。这样你就可以使用 auto_increment。当然,外键会变得混乱,并且在许多表中进行选择并不比只有一张表那么容易。您当然可以引入一个组合所有这些表的视图。

    使用存储过程

    我从来都不是存储过程的粉丝,主要是因为它将逻辑从应用程序带到数据库,这使得了解正在发生的事情变得更加困难(“这个值来自哪里?”)。但是您可以有一些存储过程来计算 invoice_number 并将其与 INSERT INTO 上的其他值一起存储

    只需使用 auto_increment

    如果你只使用 auto_increment,你会为自己省去很多麻烦。您始终可以将年份保存在另一列中并将两者一起显示。当然,如果您的要求来自产品所有者,这可能是不可能的。但是,如果您有任何方法可以做到这一点,请尝试一下!

    ...

    可能还有更多。这些只是我的想法。

    【讨论】:

    • 哇!只是一个很好的答案。真的很有帮助,不仅对我来说,因为它看起来像是任何找到它的幸运者的大师班;)。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多