我正在開發使用symfony 1.4(和Doctrine),並有一個MySQL數據庫表在多列上的唯一索引。首先,到目前爲止表中的YAML定義如下:唯一的多列和NULL值
Campaign:
actAs:
Sluggable:
fields: [name]
canUpdate: true
uniqueBy: [merchant_id, deleted_at]
Timestampable: ~
SoftDelete: ~
columns:
merchant_id: { type: integer, notnull: true }
name: { type: string(255), notnull: true, notblank: true }
start_date: { type: date, notnull: true, notblank: true }
end_date: { type: date, notnull: true, notblank: true }
indexes:
unique_name: { fields: [name, merchant_id, deleted_at], type: unique }
relations:
Merchant: { local: merchant_id, foreign: id }
正如您所看到的,我必須處理屬於商家的廣告系列。一個活動知道它的商人,並有一個名字(以及開始日期和結束日期)。廣告系列的名稱應該是唯一的 - 不是全局的,而是針對特定的商家。到此爲止,我需要一個關於廣告系列名稱和相應商家的唯一索引。但是,由於表格「充當SoftDelete」,用戶應該能夠創建一個名稱已經存在用於「軟刪除」活動的新活動,deleted_at
列也必須是唯一索引的一部分。您看到,廣告系列名稱的唯一性僅涉及相應商家的已刪除廣告系列。
現在來到實際問題:由於列deleted_at
NULL的唯一索引中的所有未刪除的廣告活動,並始終作爲唯一處理空值,所有的活動都不允許有非唯一名稱 - 真正的意義。我知道,這適用於MyISAM和InnoDB表,但不適用於BDB表。但是,如果你知道我的意思,切換到BDB不是我最喜歡的選擇。
現在來到實際問題:除了將MySQL引擎更改爲BDB以外,還有其他可能的選擇嗎?解決方法可以是重命名軟刪除的廣告系列,例如name = 'DELETED AT ' + deleted_at + ': ' + name
。這一方面有一個好處,即所有軟刪除的廣告系列即使在它們被恢復的情況下也會具有唯一的名稱(將deleted_at
重置爲NULL)。 deleted_at
列不再是唯一索引的一部分,因此,所有的廣告系列(未刪除,軟刪除以及恢復一次)都將具有唯一的名稱 - 涉及相應的商家。但另一方面,我認爲這不是最優雅的解決方案。你對此有何看法和專業知識?
我非常感謝你,並對你的貢獻感到高興。
Flinsch。
艾克,感謝您的答覆。我也有一個非常相似的想法。我認爲附加標誌'is_deleted'並不是真的需要,因爲我可以檢查'deleted_at'是否爲0。不過,我之前避開它,因爲我不確定是否手動將'deleted_at'設置爲NOT NULL值會導致無法預料的後果,例如生成對象列表等 - 因爲'deleted_at'就像是一個「magic column 「symfony /主義」。但我想我會試試看... :) – Flinsch 2010-11-05 22:30:06
MySQL 5.7可以幫助虛擬列!:http://stackoverflow.com/questions/42064759/how-to-do-unique-constraint-works-與無效值在MySQL的/ 42291845#42291845 – Nothus 2017-02-17 07:38:37