Ограничение уникальности направляющих и соответствие уникальному индексу дб для пустого столбца

У меня есть следующее в моем файле миграции

  def self.up
    create_table :payment_agreements do |t|
      t.boolean    :automatic, :default => true, :null => false
      t.string     :payment_trigger_on_order
      t.references :supplier
      t.references :seller
      t.references :product
      t.timestamps
    end
  end

Я хочу удостовериться, что, если product_id указан, это уникально, но я также хочу позволить пустой указатель, таким образом, у меня есть следующее в моей модели:

  validates :product_id,
            :uniqueness => true,
            :allow_nil => true

Работает отлично, но я должен затем добавить индекс к файлу миграции

add_index :payment_agreements, :product_id, :unique => true

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

Мой вопрос - то, что является лучшим / наиболее распространенный способ иметь дело с этой проблемой

16
задан Dave 28 May 2010 в 05:15
поделиться

2 ответа

Некоторые основные системы баз данных не позволяют уникальному индексу содержать несколько NULL: уникальность применяется как к NULL, так и к не-NULL. Существуют способы обойти это на уровне базы данных (например, триггеры или вычисляемый столбец; см. текст ссылки).

Можно решить эту проблему на уровне приложения и ввести валидацию, которая проверяет уникальность, если product_id не является null.

validate :enforce_unique_product_id
def enforce_unique_product_id
  if (!self.product_id.nil? &&
      PaymentAgreement.exists?(:conditions=>['product_id = ?', self.product_id]))
    errors.add_to_base('There is already an agreement with product id " + 
                       self.product_id)
  end
end

(Обновление: Как указал zed_0xff, MySql допускает несколько NULL в индексе UNIQUE в наиболее часто используемых хранилищах).

0
ответ дан 30 November 2019 в 23:09
поделиться

это зависит от вашего сервера db. что касается mysql:

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

11
ответ дан 30 November 2019 в 23:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: