2011-01-17 11 views
1

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

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

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

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

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

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

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

+0

Какова цель уникального индекса? Что вы не можете сделать с уникальным индексом? Это звучит немного как преждевременная оптимизация ... – dkretz

+0

У нас есть несколько серверов приложений (сеть), которые могут попробовать вставить одну и ту же запись одновременно (и это происходит на самом деле). Нам нужно предотвратить дублирование в таблице покрытий. –

ответ

2

Вы можете сделать это, используя значения NULL. Если вы используете NULL вместо «H», MySQL will ignore the row when evaluating the UNIQUE constraint:

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. 

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

+0

По какой-то причине я не думал о NULL :) Это было бы очень полезно для нас, по крайней мере, в качестве краткосрочного решения ... В долгосрочной перспективе мы собираемся разбить эту таблицу на две части: покрытия и покрытие_истории. БЛАГОДАРИМ ВАС ТАК ЧЕМ, Сэр !!! –

 Смежные вопросы

  • Нет связанных вопросов^_^