2011-02-10 20 views
11

Estoy intentando crear una restricción INDEX ÚNICA para dos columnas, pero solo cuando otra columna contiene el valor 1. Por ejemplo, column_1 y column_2 deberían ser ÚNICOS solo cuando active = 1 . Las filas que contienen active = 0 pueden compartir valores para column_1 y column_2 con otra fila, independientemente de cuál sea el valor de la otra fila para active. Pero las filas donde active = 1 no pueden compartir valores de column_1 o column_2 con otra fila que tenga active = 1.Restricción ÚNICA, solo cuando un campo contiene un valor específico

Lo que quiero decir con "compartir" son dos filas que tienen el mismo valor (es) en la (s) misma (s) columna (s). Ejemplo: row1.a = row2.a AND row1.b = row2.b. Los valores se compartirían solo si ambas columnas en la fila 1 coincidían con las otras dos columnas en la fila2.

Espero haber sido claro. : \

Respuesta

0

los índices son independientes de las influencias externas. Este tipo de restricción debería implementarse fuera de su base de datos.

0

En SQL Server esto podría lograrse con restricciones de verificación, sin embargo, no sé si MySQL admite algo similar.

Lo que funcionará en cualquier base de datos, es que puede dividir la tabla en dos. Si los registros donde está activo = 0 son solo registros de historial, y nunca se volverán a activar, podría simplemente moverlos a otra tabla y establecer una restricción única simple en la tabla original.

+0

Recibí una sugerencia similar en IRC; crea una tabla activa y una tabla inactiva. Pero la forma en que lo pones tiene más sentido; tener una tabla histórica y una tabla activa. Sin embargo, esta tabla tiene muchos campos y parece que duplicar esos campos en dos tablas sería lo incorrecto. ¿Cómo sugeriría que evite este tipo de redundancia? – Sam

+0

Una pequeña desnormalización puede ser muy útil, así que no se preocupe por las definiciones duplicadas. Por supuesto, también tendrá que hacer cambios en la tabla original a la tabla histórica, así que eso es un poco sobrecargado, pero, en mi humilde opinión, vale la pena limpiar los datos. – SWeko

+0

Hmm, ¿y si tuviera que separar solo los datos que necesitan una indexación única? Las tablas: mydata, mydata_active, mydata_inactive. De esta forma mydata contiene la clave principal y las columnas de datos.Y, mydata_active y mydata_inactive solo contendrán las columnas que deben indexarse ​​de forma exclusiva y una clave externa que hace referencia a mydata. Esta es otra forma, pero requiere una tabla extra (tercera). – Sam

11

Puede intentar hacer que el índice UNIQUE de varias columnas con column_1, column_2 y active, y luego establecer active = NULL para las filas donde no se requiere unicidad. Alternativamente, puede usar los disparadores (see MySQL trigger syntax) y verificar cada fila insertada/actualizada si dichos valores ya están en la tabla, pero creo que sería bastante lento.

+0

Recomendaría la solución NULL: es fácil, NULL es igual a FALSE (no se lo digas a un SQLer fundamentalista), y lo mejor de todo es que hace que tu base de datos haga todo el trabajo por ti. –

+0

En la solución NULL, ¿cómo distingue la base de datos la singularidad de 2 filas en la situación cuando son idénticas? ¿MySQL evita la verificación de restricciones en ese momento? –

2

Estoy intentando crear una restricción UNIQUE INDEX por dos columnas, pero sólo cuando otra columna contiene el valor 1

puede establecer el valor de "otra columna" a un valor único que no es igual a 1. por ejemplo, la identificación de un registro.

Entonces, la restricción de índice única podría aplicarse a las tres columnas, incluida la "otra columna". Llamemos a la columna "otra columna" X. Establezca el valor de columnX en 1 si desea aplicar la restricción única a un registro. Establezca el valor de columnX en un valor único si no desea aplicar la restricción única.

Entonces no se necesitan trabajos/disparadores adicionales. El índice único de las tres columnas podría resolver su problema.

Cuestiones relacionadas