2011-08-07 39 views
3

我有一個非常簡單的表格如何設置唯一約束超過200列時,一列可以爲空

categories(parent_id, title) 

我想設置一個唯一的約束,使兩類不能有相同的標題和父母。

class CreateCategories < ActiveRecord::Migration 
    def change 
    create_table :categories do |t| 
     t.integer :parent_id 
     t.string :title, :null => false 
    end 
    add_index :categories, [:title, :parent_id], :unique => true 
    end 
end 

當PARENT_ID爲null,不會強制標題這是我們所需要的獨特性。是否有可能確保標題對於根類別是唯一的?

回答

3

您可以創建唯一索引:

CREATE UNIQUE INDEX ix_categories_root_title 
    ON categories (title) 
    WHERE parent_id IS NULL 

你會在晚上睡得更好不是依靠觸發器或應用程序級驗證:P

2

你不能做到這一點與PostgreSQL中UNIQUE constraint

然而,兩個空值並不認爲這種比較平等的。這意味着即使存在唯一約束,也可以在至少一個受約束的列中存儲包含空值的重複行。此行爲符合SQL標準,但我們聽說其他SQL數據庫可能不遵循此規則。

底層的問題是x = NULL對於標準SQL中的所有x都是錯誤的。

您可以使用BEFORE INSERT和BEFORE UPDATE觸發器強制NULL parent_id值,但ActiveRecord不知道觸發器是什麼,所以您必須手動維護觸發器。或者,您可以在自定義驗證中完成所有操作,並希望在沒有首先通過模型的情況下,什麼都不會觸及數據庫。