2015-07-24 10 views
0

У меня есть таблица, где я нажимаю связанные данные. Он имеет 6 столбцов с нулевым значением. Исходя из некоторой логики, комбинация из 2 всегда не равна нулю (1-й + один из последних 4 & второй + один из последних 4). Таким образом я избегал иметь 8 разных таблиц для хранения данных.Уникальный индекс SQL Server в (все) значения NON-NULL строк

Есть ли T-SQL (начало довольно новый специфики SQL Server) ярлык, чтобы создать уникальный ключ на этих 6 столбцов, говорит гарантировать, что любая непустая комбинация из столбцов, указанных в индексе (1 - 6-й) уникален, но не стал действительно конкретным?

Я могу создать уникальные индексы для каждой комбинации, но мне было интересно, есть ли какой-нибудь ярлык, чтобы оставаться ленивым и использовать (написать) 1 индекс против 8 из них. Это, очевидно, не большое усилие, но что-нибудь короче, лучше ... в коде, в большинстве случаев!

+2

Имея нулевые столбцы, чтобы избежать создания правильных таблиц, это плохой дизайн, и одним из последствий является то, что вам нужно добавить проверки и ограничения, чтобы избежать плохих значений. Вместо этого создайте правильный дизайн. Если вы хотите сразу прочитать данные из всех таблиц, используйте представление с объединением –

+0

@PanagiotisKanavos. Я знаю, что это плохой дизайн, но 8 таблиц облегчают жизнь SqlServer, а 1 делает мой. И учитывая тот факт, что таблица на 99% читается только и не так часто посещается ... для меня более приоритетной является жизнь. ;) – CodeAngry

+1

Тогда почему у вас возникли проблемы? Фактически, они делают вещи хуже: как для сервера, так и для программиста. SQL Server имеет некоторые дополнительные функции, которые могут преодолеть недостатки, но в конце концов вам нужно исправить дизайн. –

ответ

1

Создать вычисляемый столбец на что-то вроде:

COALESCE(
    cast(1 as binary(1)) + cast(col1 as binary(4)) /* Choose appropriate length for the type of col1 */ 
    ,cast(2 as binary(1)) + cast(col2 as binary(4)) /* Choose appropriate length for the type of col2 */ 
) 
+ COALESCE(
    cast(3 as binary(1)) + cast(col3 as binary(4)) /* Choose appropriate length for the type of col3 */ 
    ,cast(4 as binary(1)) + cast(col4 as binary(4)) /* Choose appropriate length for the type of col4 */ 
    ,cast(5 as binary(1)) + cast(col5 as binary(4)) /* Choose appropriate length for the type of col5 */ 
    ,cast(6 as binary(1)) + cast(col6 as binary(4)) /* Choose appropriate length for the type of col6 */ 
) 

Вы, возможно, не нужно первое значение в каждой паре - в зависимости от того, (17, нуль, 1, NULL, NULL, NULL) должен быть одинаковым как (null, 17, null, null, 1, null) или нет.

Но так или иначе, с помощью этого вычисленного столбца вы можете поместить на него уникальный индекс. :)

Вы можете сделать это в двух столбцах, но вы можете сделать это в одном подобном.

+0

Отфильтрованный индекс разрешил бы это. Лучший дизайн базы данных будет намного лучше, чем –

+1

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

+0

Я бы не использовал одну таблицу с нулями, чтобы «избежать» создания нескольких таблиц в первую очередь. Исключает проблему полностью. Из описания, похоже, требуется только 2 таблицы с четырьмя нулевыми столбцами. –

0

Я не думаю, что есть, индекс в SQL-Server уникален (по всем строкам в индексе), или он не уникален.

+0

Для получения дополнительных сведений об этом: https://technet.microsoft.com/en-us/library/ms188783(v=sql.105).aspx –

0

Просто создать уникальный индекс на 6 колонок

+0

Как насчет нулевых значений? 6 столбцов, только 2 не являются нулевыми в любой момент времени. – CodeAngry

+0

Как насчет нулевого? Если два не являются нулевыми и уникальными, добавьте в 4 null и все еще уникально. – Paparazzi

2
  1. сделать проверочное ограничение, чтобы гарантировать, что только один из двух первых установлен и один из последних 4
  2. сделать вычисляемый столбец coalesce(c1, c2) и колонка coalesce(c3, c4, c5, c6).
  3. Сделайте уникальный подсчет (computed1, computed2).

Надеюсь, я исправился. Возможно, вам нужно немного изменить это.

+1

Это отличная идея. У меня уже была «ПРОВЕРКА». Одна из проблем заключается в том, что значения - это числа, указывающие на хэш-таблицы, чтобы они могли столкнуться. Но я могу написать решение с этими вычисленными столбцами * просто нужно добавить еще 2 с 'case' *, которые содержат число (1/2) для первого ненулевого столбца и (3/4/5/6) для второго не- - нулевая колонка. - * Возможно, я пропустил вычисляемые столбцы ... стоило задать вопрос. Спасибо! * – CodeAngry

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