2011-08-07 40 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不知道触发器是什么,所以您必须手动维护触发器。或者,您可以在自定义验证中完成所有操作,并希望在没有首先通过模型的情况下,什么都不会触及数据库。