ORM UniqueConstraint, дубликат нулевого значения
У меня есть сущность с уникальным ограничением на 3 поля.
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"})})
Редактировать: значение обнуляемого является внешним ключом для другой сущности, поэтому я не могу поставить пользовательское значение. Это сущность или ноль.
3 ответа
Это может быть достигнуто с помощью двух частичных индексов. Но аннотации к доктрине недостаточно. Мы должны добавить немного SQL, чтобы решить эту проблему.
НОТА! Я использую PostgreSQL и миграции в моем проекте.
Сначала создайте 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
Готово!
Я тоже столкнулся с той же проблемой, не нашел способа ее решить.
Наконец добавил еще один столбец varchar в мою таблицу, его значение - комбинация из 3 полей. например:5_1_0(проверка вручную и добавление 0 для нулевого ограничения, в противном случае идентификатор ограничения) и добавление уникального ограничения для нового столбца и удаление существующего ограничения.
У меня был аналогичный случай, когда A всегда был установлен, B и C были нулевыми, но один из них всегда был установлен.
Итак, у меня были следующие возможности:
A. B. C.
123-null-789
123-456-null
Я попытался создать UniqueConstraint как комбинацию
A-B-C
, но это не сработало.
Что сработало, так это два UniqueConstraints с параметром where:
@ORM\UniqueConstraint(
name="unique-key-1",
columns={"a", "b"},
options={"where": "b IS NOT NULL"}
),
@ORM\UniqueConstraint(
name="unique-key-2",
columns={"a", "c"},
options={"where": "c IS NOT NULL"}
)
Таким образом, уникальные ключи работали для правильных случаев.