subconsultas registros español ejemplos desde datos consultas concatenar con complejas cero bases aprender administración sql sql-server-2008 bit-manipulation

registros - Cómo manejar una gran cantidad de banderas para un registro de SQL



manual de postgresql 10 en español pdf (8)

Necesito consejos sobre cómo manejar un conjunto relativamente grande de banderas en mi tabla SQL2k8.

Dos preguntas, tengan paciencia, por favor :)

Digamos que tengo 20 banderas que me gustaría almacenar para un registro.

Por ejemplo:

CanRead = 0x1 CanWrite = 0x2 CanModify = 0x4 ... y así sucesivamente a la bandera final 2 ^ 20

Ahora, si configuro la siguiente combinación de un registro: Permisos = CanRead | Puede escribir

Puedo verificar fácilmente si ese registro ha requerido permiso haciendo WHERE (Permisos y CanRead) = CanRead

Eso funciona.

Pero, también me gustaría recuperar todos los registros que pueden escribir O modificar.

Si publico WHERE (Permisos & (CanWrite | CanModify)) = (CanWrite | CanModify) Obviamente no obtendré mi registro que tiene permisos establecidos en CanRead | Puede escribir

En otras palabras, ¿cómo puedo encontrar registros que coincidan con NINGUNO de los indicadores en mi máscara que estoy enviando al procedimiento?

Segunda pregunta, ¿qué rendimiento tiene en SQL 2008? ¿Sería realmente mejor crear campos de 20 bits?

Gracias por tu ayuda


¿No es tan simple como ...

WHERE (Permissions & ( CanWrite | CanModify )) > 0

... como cualquier ''bit'' se establece en 1 dará como resultado un valor distinto de cero para el operador ''&''.

Es tarde en el día y estoy a punto de irme a casa, por lo que mi cerebro podría estar funcionando de manera ineficiente.


DÓNDE (Permisos y CanWrite) = CanWrite O (Permisos y CanModificar) = CanModify

creo


Haga esto solo si también está consultando por alguna otra tecla.

No hagas esto si consultas por combinaciones de banderas. Un índice en contra de esta columna no lo ayudará en general. Estará restringido a escaneos de tabla.


No, eso no funcionará.

Enviaré solo una máscara para el procedimiento

Algo como @filter que en C # llene con @filter = CanModify | Puede escribir

Entonces, el procedimiento obtiene el valor OR-ed como un filtro.

Oh, y por cierto, NO es un modelo de permiso, lo estoy usando solo como un ejemplo.

Realmente tengo alrededor de 20 banderas únicas que mi objeto puede tener.


Qué pasa

WHERE (Permissions & CanWrite) = CanWrite OR (Permissions & CanModify) = CanModify

?


Supongo que su columna Permisos es una Int. Si es así, te animo a jugar con el código de muestra que proporciono a continuación. Esto debería darle una indicación clara de cómo funciona la funcionalidad.

Declare @Temp Table(Permission Int, PermissionType VarChar(20)) Declare @CanRead Int Declare @CanWrite Int Declare @CanModify Int Select @CanRead = 1, @CanWrite = 2, @CanModify = 4 Insert Into @Temp Values(@CanRead | @CanWrite, ''Read,write'') Insert Into @Temp Values(@CanRead, ''Read'') Insert Into @Temp Values(@CanWrite, ''Write'') Insert Into @Temp Values(@CanModify | @CanWrite, ''Modify, write'') Insert Into @Temp Values(@CanModify, ''Modify'') Select * From @Temp Where Permission & (@CanRead | @CanWrite) > 0 Select * From @Temp Where Permission & (@CanRead | @CanModify) > 0

Cuando usa lógica y, obtendrá un número con el conjunto de 1 apropiadamente basado en su condición. Si nada coincide, el resultado será 0. Si 1 o más condiciones coinciden, el resultado será mayor que 0.

Dejame mostrarte un ejemplo.

Supongamos que CanRead = 1, CanWrite = 2 y CanModify = 4. Las combinaciones válidas son:

Modify Write Read Permissions ------ ----- ---- ----------- 0 0 0 Nothing 0 0 1 Read 0 1 0 Write 0 1 1 Read, Write 1 0 0 Modify 1 0 1 Modify, Read 1 1 0 Modify, Write 1 1 1 Modify, Write, Read

Ahora, supongamos que quiere probar para Leer o Modificar. Desde su aplicación, pasaría (CanRead | CanModify). Esto sería 101 (en binario).

Primero, probemos esto contra una fila en la tabla que el ÚNICO ha leído.

001 (Row from table) & 101 (Permissions to test) ------ 001 (result is greater than 0)

Ahora, probemos contra una fila que solo tiene escritura.

010 (Row from table) & 101 (Permission to test) ------ 000 (result = 0)

Ahora pruébelo contra la fila que tiene los 3 permisos.

111 (Row from table) & 101 (Permission to test) ------ 101 (result is greater than 0)

Espero que pueda ver que si el resultado de la operación AND arroja un valor = 0, entonces ninguno de los permisos probados se aplica a esa fila. Si el valor es mayor que 0, entonces al menos una fila está presente.


No a eso. Es como guardar una cadena de CSV en un campo memo y anular el propósito de una base de datos.

Use un valor booleano (bit) para cada indicador. En esta muestra específica encontrará todo lo que puede leer y puede escribir o modificar:

WHERE CanRead AND (CanWrite OR CanModify)

Simple SQL puro sin hacks inteligentes. Los 7 bits extra que estás desperdiciando por cada bandera no valen la pena.


Sería considerablemente mejor tener un modelo de permisos diferente.

20 banderas me indicarán que se requiere un replanteamiento, la mayoría de los sistemas de archivo pueden funcionar con 12 indicadores básicos y ACLS, tal vez con una tabla separada que simplemente otorga permisos o grupos de objetos o accesadores para permitir un control diferente.

Esperaría que un select sea más rápido para tener 20 campos separados, pero tampoco agregaría 20 campos para el rendimiento.

--actualizar--

la consulta original escrita como

WHERE (Permissions & ( CanWrite | CanModify )) > 0

sería suficiente, sin embargo, parece ser que lo que tienes en la base de datos es un conjunto de atributos que una entidad puede tener. En este caso, la única forma sensata (en términos de bases de datos) de hacerlo es con una relación de uno a muchos con una tabla de atributos.