Symfony2、条令和MySQL:如何生成发票号

Symfony2、条令和MySQL:如何生成发票号,mysql,symfony,doctrine,Mysql,Symfony,Doctrine,使用Symfony2.0、Doctrine和MySQL,我需要根据下一种格式自动生成相关发票号: 年份/可自动递增 例如,2012年的发票: 2012/00000001 2012/00000002 2012/00000003 等等 该发票号将使用MySQL数据库中我的采购表中的发票号字段存储 问题是,如何查询数据库以返回某一年的最后一个可自动递增的数字 换句话说(伪代码): 我该怎么做呢?首先,symfony2和doctrine2都不是您的问题和解决方案的一部分。其次,您可能需要考虑在发票号中

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

年份/可自动递增

例如,2012年的发票:

2012/00000001
2012/00000002
2012/00000003
等等

该发票号将使用MySQL数据库中我的采购表中的
发票号
字段存储

问题是,如何查询数据库以返回某一年的最后一个可自动递增的数字

换句话说(伪代码):


我该怎么做呢?

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

也就是说,根据您的需要,您可以通过多种方式实现您的目标:

选择最后一个条目,递增一,保存

这是一个解决方案,只有当您没有太多的写入到采购表中,或者这些写入是由一个进程(例如批处理)完成的,您可以等待写入一个项目,并且如果写入成功,则写入下一个项目时,该解决方案才会起作用

只需从数据库中选择最后一个条目,获取
发票编号
,递增一,保存即可。如果年份不同,从一年开始

当然,如果您每秒写入的次数很多,您就会遇到麻烦,因为在您写入一行的那一刻,其他两个可能已经读取了旧的最后一个发票号,将其递增1,并试图存储它(由于它们需要唯一,因此会导致错误)

读取时动态计算

如果您不经常需要
发票号
,此解决方案效果良好。你可以在一个想法上有一个正常的自动增量。对于每一年,您都将上一年的最后一个id存储在某个助手表中。当您读取一行时,您可以通过获取年份、上一年的最后一个id并从自动增量中减去该id来计算id

当然,开销是您每次都需要计算发票。这取决于您实际实现它的方式以及数据库负载的大小,从不明显到非常缓慢

让发票号为空,然后计算它

这可以通过许多不同的方式完成,如果您不想处理事务之类的事情,比如捕获失败的写入等等,这是一个非常好的解决方案。其思想是首先使用空发票号存储数据,然后在保存数据时计算发票号并更新数据集

您可以将这一点与前面的想法结合起来,像上面描述的那样计算发票号,然后用这个数字更新数据集,而不是每次都重新计算它。您还可以有一个cronjob或其他东西来查找发票号为空的行,以及类似于helper表中的计数器之类的东西,它只被这个cronjob使用。他获取计数器,将其递增,使用数据集的新发票,并保存计数器和数据集

尝试,出错时重复

这是一个丑陋的解决方案,但在某些情况下它是可行的。选择最后一个发票编号,将其递增一,保存当前数据集。如果失败,则重复该过程。你这样做直到你成功地储蓄。您需要确保在实际数据库上进行选择(doctrine2可能会缓存结果,这意味着您一直获得旧数据集,增加相同的数字,从而反复出现相同的错误),并且如果您有一些主/从设置,则无法在从机上工作,因为它可能不是最新的

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

每年一张表

每年可以将数据保存在一个表中。这样您就可以使用自动增量。当然,外键被弄乱了,选择多个表并不像选择一个表那么容易。当然,您可以引入一个组合所有这些表的视图

使用存储过程

我从来都不喜欢存储过程,主要是因为它将逻辑从应用程序带到数据库,从而更难掌握发生了什么(“这个值来自哪里?”)。但是您可以使用一些存储过程来计算
发票号
,并将其与
插入到
中的其他值一起存储

只需使用自动增量

如果你只使用自动增量,你会节省很多麻烦。您始终可以将年份保存在另一列中,并将两者一起显示。当然,如果您的需求来自产品所有者,这可能是不可能的。但是如果你有任何办法,试试看


可能还有更多。这些都是我脑子里想出来的。

哇!这是一个很好的回答。真的很有帮助,不仅对我,因为它看起来像是一个大师级的任何幸运的家伙找到它;)。谢谢。
function new_invoice(){
    $year = today.year;
    select last invoice_number where year = $year;
    $new_invoice_number = increment invoice_number;
    store $year . "/" . $new_invoice_number;
}