我想給一個實體(發票,訂單,預訂等)一個唯一的序列號,但只在該年內唯一。因此,每年(或另一個字段,如客戶)的第一張發票開始有id 1。這意味着可以有一個複合主鍵(年,id)或一個主鍵(即invoice_id)和另外兩個列獨一無二。使用複合主鍵生成自動增量ID
我的問題:使用Doctrine2和Symfony2爲對象提供自動生成的ID和另一個值的唯一組合的最佳方式是什麼?
複合鍵學說限制
學說不能分配一個自動生成的ID的實體與一個複合主鍵(http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/composite-primary-keys.html):
具有複合關鍵字的每個實體不能使用比「已分配」的其他 ID生成器。這意味着在您致電
EntityManager#persist($entity)
之前,ID字段必須設置其值 。
設置序列號手動
所以我必須手動分配一個ID。爲了做到這一點,我試圖在某一年尋找最高的ID,並給予ID + 1的新實體。我懷疑這是最好的方式,即使它是,我還沒有找到最好的幹)的方式來做到這一點。由於我認爲這是一個通用的問題,我想阻止XY-problem,我已經開始了這個問題。
常規期權:只有MyISAM數據
我發現基於this answer的 '香草' 的MySQL/MyISAM的解決方案:
CREATE TABLE IF NOT EXISTS `invoice` (
`year` int(1) NOT NULL,
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`year`,`id`)
) ENGINE=MyISAM;
因爲Doctrine2限制是行不通的,所以我我正在尋找這種香草MySQL解決方案的Doctrine ORM等價物。
其他解決方案
沒有爲InnoDB的一個解決方案,以及:Defining Composite Key with Auto Increment in MySQL
##畏縮的(可能)問題的常規期權是,你必須鎖定**整個表**在您的交易期間,這相當於殺死了併發的INSERT。你爲什麼要每年重複IDS?一個實際的id值是沒有意義的;如果要輸出序列,請執行自連接和「COUNT()」。 –
由於財務原因,發票必須有序列號(每年以id = 1開頭)。它不一定是主鍵的一部分,我會編輯我的問題。 –
不,好吧,是的,你可能確實需要騎自行車,然後持續的順序......你可能無法擺脫這種做法,但至少可以解決表鎖問題。將計數器存儲在另一個表中(按年份鍵入),然後使用存儲過程或觸發器(在他們自己的事務中)將其打開。如果有人不提交他們的行,最終會出現差距,但至少長時間運行的交易不會鎖定其他人。那麼你只需要在這些列上使用'UNIQUE KEY'。 –