2014-04-02 51 views
4

我有一個實體在3個fiels上有一個唯一的約束。ORM UniqueConstraint,空值重複

2個字段不可爲空,第三個字段可以爲空。

我的問題,當第三字段爲空,唯一性約束是不行的,所以我可以在我的數據庫中的一些重複值一樣(5,1,null)(5,1,null)

對我來說,(5,1,null)是一個獨特的價值,與。空太

你有什麼想法

這是我的ORM線:

* @ORM\Table(name="table", uniqueConstraints={@ORM\UniqueConstraint(name="table_idx", columns={"field1", "field2", "field3"})}) 

編輯:可爲空的值是另一個實體的外鍵,所以我不能放置自定義值。它是一個實體或null。

+0

不確定你的意思,但是引用文檔'一個UNIQUE索引允許可以包含NULL的列的多個NULL值:http://dev.mysql.com/doc/refman/5.0/en/create-index .html –

+0

我不希望允許多個空值。對我來說,null是一個真正的價值。 –

+0

這是因爲NULL是一個未知值,並且比較兩個未知值的結果也是未知的。也許你可以使用一個特殊的值而不是NULL? – Eelke

回答

3

我也面臨同樣的問題,沒有找到任何解決方法。

最後在我的表格中添加了一個更多的varchar列,它的值是3個字段的組合。例如:5_1_0(手動檢查並添加0作爲空約束,否則約束Id),並在新列上添加唯一約束並刪除現有約束。

0

這可以使用two partial indexes來實現。但是學說註解是不夠的。我們應該添加一些SQL來解決問題。

注意!我在我的項目中使用PostgreSQL和migrations

首先創建2個唯一索引(我用YAML):

uniqueConstraints: 
    table_idx_2_fields: 
     columns: [ field1, field2 ] 
    table_idx_3_fields: 
     columns: [ field1, field2, field3 ] 

然後使用控制檯產生遷移類:

php app/console doctrine:migrations:diff 

SQL將會產生,但必須進行修改一點點( WHERE子句加入

class Version20170622165834 extends AbstractMigration 
{ 
    /** 
    * @param Schema $schema 
    */ 
    public function up(Schema $schema) 
    { 
     // ... 

     $this->addSql(' 
      CREATE UNIQUE INDEX table_idx_2_fields ON tbl (field1, field2) 
      WHERE field3 IS NULL; 
     '); 
     $this->addSql(' 
      CREATE UNIQUE INDEX table_idx_3_fields ON tbl (field1, field2, field3) 
      WHERE field3 IS NOT NULL; 
     '); 
    } 

    /** 
    * @param Schema $schema 
    */ 
    public function down(Schema $schema) 
    { 
     // ... 
    } 
} 

執行生成的SQL(遷移):

php app/console doctrine:migrations:migrate -n 

完成!