Уникальный индекс MySQL по нескольким полям

У нас в БД есть специальная таблица, которая хранит в себе историю своих изменений. Так называемая «самоархивируемая» таблица:

CREAT TABLE coverages (
   id INT, # primary key, auto-increment
   subscriber_id INT,
   current CHAR,  # - could be "C" or "H".
   record_version INT,
   # etc.
);

В нем хранятся «покрытия» наших подписчиков. Поле «текущая» указывает, является ли это текущей/исходной записью («C») или записью истории («H»).

У нас может быть только одно текущее покрытие «C» для данного подписчика, но мы не можем создать уникальный индекс с двумя полями (*subscriber_id и current*), потому что для любой данной записи «C» может быть любое количество «H». » записи - история изменений.

Таким образом, индекс должен быть уникальным только для current == 'C' и любого subscriber_id.

Это можно сделать в Oracle DB с помощью чего-то вроде «материализованных представлений»: мы можем создать материализованное представление, которое будет включать только записи с current = 'C', и создать уникальный индекс с этими двумя полями: *subscriber_id, текущий*.

Возникает вопрос: как это можно сделать в MySQL?


person Alex Kovshovik    schedule 17.01.2011    source источник
comment
Какова цель уникального индекса? Что нельзя делать с неуникальным индексом? Это немного похоже на преждевременную оптимизацию...   -  person dkretz    schedule 18.01.2011
comment
У нас есть несколько серверов приложений (веб), которые могут попытаться вставить одну и ту же запись одновременно (и это действительно происходит). Нам нужно предотвратить дублирование в таблице покрытий.   -  person Alex Kovshovik    schedule 18.01.2011


Ответы (1)


Вы можете сделать это, используя значения NULL. Если вы используете NULL вместо "H", MySQL проигнорирует строку при оценке ограничения UNIQUE:

A UNIQUE index creates a constraint such that all values in the index must be
distinct. An error occurs if you try to add a new row with a key value that
matches an existing row. This constraint does not apply to NULL values except
for the BDB storage engine. For other engines, a UNIQUE index permits multiple
NULL values for columns that can contain NULL.

Теперь это немного обман, и это означает, что вы не можете получить свои данные точно так, как вы хотите. Так что это решение может не соответствовать вашим потребностям. Но если вы можете переработать свои данные таким образом, это должно сработать.

person dkarp    schedule 17.01.2011
comment
По какой-то причине я не подумал о NULL :) Это было бы очень хорошо для нас, по крайней мере, в качестве краткосрочного решения... В долгосрочной перспективе мы собираемся разделить эту одну таблицу на две: покрытия и история_покрытия. БОЛЬШОЕ СПАСИБО, ГОСПОДА!!! - person Alex Kovshovik; 18.01.2011