как установить уникальное ограничение на 2 столбца, когда один столбец может быть нулевым - PullRequest
3 голосов
/ 07 августа 2011

У меня очень простая таблица

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является нулевым, это не навязывает уникальность заголовка, что нам и нужно.Можно ли удостовериться, что заголовки уникальны и для корневых категорий?

Ответы [ 2 ]

3 голосов
/ 08 августа 2011

Вы можете создать уникальный индекс для этого:

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

Вы бы спали намного лучше ночью, чем полагаясь на триггеры или проверки на уровне приложения: P

2 голосов
/ 07 августа 2011

Вы не можете сделать это с ограничением UNIQUE в PostgreSQL:

Однако в этом сравнении два нулевых значения не считаются равными.Это означает, что даже при наличии уникального ограничения можно хранить повторяющиеся строки, которые содержат нулевое значение, по крайней мере, в одном из ограниченных столбцов.Это поведение соответствует стандарту SQL, но мы слышали, что другие базы данных SQL могут не следовать этому правилу.

Основная проблема заключается в том, что x = NULL является ложным для всех x в стандартном SQL.

Вы можете применить его для значений NULL parent_id с помощью триггера BEFORE INSERT и BEFORE UPDATE, но ActiveRecord не знает, что такое триггеры, поэтому вам придется поддерживать триггер вручную.В качестве альтернативы вы можете сделать все это с помощью пользовательских проверок и надеяться, что ничто не коснется вашей базы данных, не пройдя сначала вашу модель.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...