De acuerdo con la CREATE INDEX
documentación:
Se pueden combinar hasta 16 columnas en una sola clave de índice compuesta.
Tenemos una tabla con ~ 18 columnas que deben formar una combinación única. Esta tabla no es sensible al rendimiento: raramente actualizamos valores / insert registros. Solo necesitamos asegurarnos de evitar la duplicación de nuestros registros ... y pensamos que podríamos imponer una restricción de unicidad simple.
¿Algunas ideas? Estoy abierto a evitar el índice / restricción único por completo si hay una mejor manera.
Respuestas:
Agregue una columna calculada persistente que combine las 18 claves, luego cree un índice único en la columna calculada:
Consulte Crear índices en columnas calculadas .
Otro enfoque es crear una vista indizada:
Consulte Crear vistas indizadas .
Ambos enfoques permiten un agregado clave parcial: agregado c1 + c2 + c3 como k1, c4 + c5 + c6 como k2, etc. luego indexar / crear una vista indexada en (k1, k2, ...). Thia podría ser beneficioso para los escaneos de rango (el índice se puede usar para buscar en c1 + c2 + c3.
Por supuesto, todas las
+
operaciones en mi ejemplo son agregación de cadenas, el operador real a usar depende de los tipos de todas esas columnas (es decir, puede que tenga que usar conversiones explícitas).PD. Como las restricciones únicas se aplican mediante un índice único, cualquier restricción en los índices únicos se aplicará también a las restricciones únicas:
Sin embargo, crear la restricción en una columna computada persistente funciona:
Obviamente, la columna persistente consume el espacio en el disco, por lo que el enfoque puede ser malo para una tabla muy grande. El enfoque de vista indexada no tiene este problema, solo consume el espacio para el índice , no el espacio para la columna y el índice calculados .
fuente
Creo que sería mucho mejor poner su verificación de índice única en una columna calculada que se genera usando
HASHBYTES('MD5', ...)
la combinación de sus 18 columnas.fuente
Encontré este problema y mi DBA senior sugirió usar una función de verificación de singularidad. Mis inserciones son relativamente pequeñas e infrecuentes (~ 1000 filas, insertadas al comienzo de cada mes) y mi única preocupación es hacer cumplir la unicidad.
@RBarryYoung, todavía no tengo el representante para comentar, pero tuve problemas con la solución HASHBYTES porque uno de mis tipos de datos era una fecha y cometí el error de novato (?) De no proporcionar el argumento de estilo opcional a mi CONVERTIR la función al convertir a varchar. Sin el estilo, obtiene el siguiente error cuando intenta agregar las
PERSISTED UNIQUE NONCLUSTERED
restricciones:fuente
Puede combinar algunos de los valores para crear un nuevo valor único y almacenarlo además de los datos actuales.
Cree una función definida por el usuario para crear los nuevos valores y un desencadenante para llenar el campo cuando se agreguen datos, entonces no tendrá mucha más sobrecarga en el mantenimiento del campo.
La combinación de dos o tres de sus campos lo colocaría por debajo del límite de 16.
fuente
Podrías ir con un disparador para
insert
/update
. Haga una agrupación selecta por sus columnas con una cláusula dehaving count(*) > 1
. Si eso vuelve no vacío, retroceda.fuente
Esto es lo que haría. Crearía un disparador DESPUÉS para INSERTAR, ACTUALIZAR que hace una
ROW_NUMBER ()
función y particiones por las 18 columnas únicas. Si el número máximo de filas es mayor que uno, entonces aROLLBACK
.fuente