Я занимаюсь разработкой с использованием symfony 1.4 (и Doctrine) и имею таблицу базы данных MySQL с уникальным индексом на нескольких столбцах. Во-первых, определение таблицы YAML до сих пор:
Campaign:
actAs:
Sluggable:
fields: [name]
canUpdate: true
uniqueBy: [merchant_id, deleted_at]
Timestampable: ~
SoftDelete: ~
columns:
merchant_id: { type: integer, notnull: true }
name: { type: string(255), notnull: true, notblank: true }
start_date: { type: date, notnull: true, notblank: true }
end_date: { type: date, notnull: true, notblank: true }
indexes:
unique_name: { fields: [name, merchant_id, deleted_at], type: unique }
relations:
Merchant: { local: merchant_id, foreign: id }
Как видите, мне приходится иметь дело с кампаниями, принадлежащими торговцам. Кампания знает своего продавца и имеет имя (а также дату начала и дату окончания). Название кампании должно быть уникальным - не глобально, а для конкретного продавца. Для этого мне понадобится уникальный индекс названия кампании и соответствующего продавца. Но, поскольку таблица «действует как SoftDelete» и пользователь должен иметь возможность создавать новую кампанию с именем, которое уже существует для кампании «мягкого удаления», столбец deleted_at
также должен быть частью уникального индекса , Видите ли, уникальность названия кампании касается только не удаленных кампаний соответствующего продавца.
Теперь перейдем к актуальной проблеме : поскольку столбец deleted_at
равен NULL для всех не удаленных кампаний, а значения NULL в уникальном индексе всегда рассматриваются как уникальные, все кампании могут иметь не уникальные имена - в истинном смысле. Я знаю, что это относится к таблицам MyISAM и InnoDB, но не к таблицам BDB. Однако, переход на BDB не мой любимый вариант, если вы понимаете, о чем я.
Теперь перейдем к актуальному вопросу : Какие есть другие возможные варианты, кроме изменения движка MySQL на BDB? Обходной путь может состоять в том, чтобы переименовать кампанию с мягким удалением, например, name = 'DELETED AT ' + deleted_at + ': ' + name
. Это, с одной стороны, будет иметь то преимущество, что все кампании с мягким удалением будут иметь уникальные имена даже в том случае, если они будут восстановлены (сброс deleted_at
обратно на NULL). Столбец deleted_at
больше не должен был бы быть частью уникального индекса, и, таким образом, все кампании (не удаленные, не удаленные, а восстановленные один раз) будут иметь уникальное имя - относительно соответствующего продавца. Но, с другой стороны, я не думаю, что это будет самое элегантное решение. Каковы ваши мнения и опыт по этому поводу?
Я очень благодарен вам и рад вашему вкладу.
Flinsch.