ElP*_*ter 3 mysql doctrine symfony
使用Symfony2.0,Doctrine和MySQL,我需要根据下一格式自动生成相关的发票号码:
年/ autoincrementable
例如,2012年的发票:
2012/00000001
2012/00000002
2012/00000003
Run Code Online (Sandbox Code Playgroud)
等等...
该发票号码将使用invoice_number我的MySQL数据库中的Purchase表中的字段进行存储.
问题是,如何查询数据库以返回特定年份的最后一个自动增量数?
换句话说(伪代码):
function new_invoice(){
$year = today.year;
select last invoice_number where year = $year;
$new_invoice_number = increment invoice_number;
store $year . "/" . $new_invoice_number;
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点?
First of all, neither symfony2 nor doctrine2 are part of your problem and your solution. Second, you may want to think about storing a / in your invoice_number, mainly because you need to make the field a varchar for this which performs worse than an integer on stuff like indexing and quering for items.
That said, what you want can be achieved in many ways, depending on your needs:
Select last entry, increment by one, save
This is a solution which will only work if either you have not that much writes to your purchase table or these writes are done by one process (e.g. a batch) where you can wait for one item to be written and if this succeeds write the next one.
Simply select the last entry from the database, get the invoice_number, increment by one, save. If the year is different, start with one.
Of course, if you have many writes per second, you get into trouble because the moment you write a row, two others may have read the old last invoice_number, increment it by one and are trying to store it (resulting in errors because they need to be unique).
Calculate dynamically on read
This solution works well if you don't need the invoice_number that often. You could have a normal auto_increment on an idea. For each year, you store the last id of the last year in some helper table. When you read a row, you can calculate the id by getting the year, the last id of the last year and subtract that from the auto_increment.
当然,您需要每次都计算发票.根据您实际实现它的方式以及数据库负载的大小,这可能是从不明显到非常慢的任何地方.
让invoice_number为空,而不是计算它
这可以通过许多不同的方式完成,如果您不想处理事务等,捕获失败的写入等,这是一个非常简洁的解决方案.我们的想法是首先使用空的invoice_number存储数据,然后在保存数据时计算invoice_number并更新数据集.
您可以将此与前一个想法相结合,计算如上所述的invoice_number,然后使用此数字更新数据集,而不是每次重新计算它.您还可以使用cronjob或其他东西查找具有空invoice_number的行,以及类似于帮助程序表中的计数器的内容,该表仅由此cronjob使用.他取得计数器,递增计数器,使用这是数据集的新发票并保存计数器和数据集.
尝试,重复错误
这是一个丑陋的解决方案,但它可以工作,在某些情况下可能没问题.选择最后一个invoice_number,将其递增1,保存当前数据集.如果失败,则重复此过程.你这样做直到你成功储蓄.您需要确保在实际数据库上执行select(doctrine2可能会缓存结果,这意味着您始终获取旧数据集,增加相同的数字,从而反复出现相同的错误)并且如果您有一些主数据/从站设置不适用于从站,因为它可能不是最新的.
我不喜欢这个解决方案,但正如所说,这是值得考虑的事情.
每年一张桌子
每年可以将数据保存在一个表中.这样你就可以使用auto_increment.当然,外键变得混乱,选择多个表并不比拥有一个表容易.您当然可以引入一个结合了所有这些表的视图.
使用存储过程
我从来不是存储过程的粉丝,主要是因为它从应用程序到数据库需要逻辑,因此更难理解正在发生的事情("这个值来自哪里?").但是你可以有一些存储过程来计算invoice_number并将其与其他值一起存储在a上INSERT INTO
只需使用auto_increment
如果你只使用auto_increment,你可以省去很多麻烦.您始终可以将年份保存在另一列中,并将两者一起显示.当然,如果您的要求来自产品所有者,则可能无法实现.但如果你有任何办法,试试吧!
...
可能还有更多.这些只是我的头脑.