¡Espléndida pregunta!
En primer lugar, hagamos algunas suposiciones sobre "mejor".
Supongo que no le importa mucho el espacio en disco: una máscara de bits es eficiente desde el punto de vista del espacio, pero no estoy seguro de que eso importe mucho si está utilizando un servidor SQL.
Supongo que te importa la velocidad. Una máscara de bits puede ser muy rápida cuando se utilizan cálculos, pero no podrá utilizar un índice al consultar la máscara de bits. Esto no debería importar mucho, pero si desea saber qué usuarios tienen acceso de creación, su consulta sería algo como
select * from user where permsission & CREATE = TRUE
(no tengo acceso a SQL Server hoy, en el camino). Esa consulta no podría usar un índice debido a la operación matemática, por lo que si tiene una gran cantidad de usuarios, esto sería bastante doloroso.
Supongo que le importa la mantenibilidad. Desde el punto de vista de la capacidad de mantenimiento, la máscara de bits no es tan expresiva como el dominio del problema subyacente como el almacenamiento de permisos explícitos. Es casi seguro que tendrá que sincronizar el valor de los indicadores de la máscara de bits en varios componentes, incluida la base de datos. No imposible, pero dolor en el trasero.
Entonces, a menos que haya otra forma de evaluar "mejor", diría que la ruta de la máscara de bits no es tan buena como almacenar los permisos en una estructura de base de datos normalizada. No estoy de acuerdo en que sea "más lento porque tiene que unirse"; a menos que tenga una base de datos totalmente disfuncional, no podrá medir esto (mientras que las consultas sin el beneficio de un índice activo pueden volverse notablemente más lento incluso con unos pocos miles de registros).
Personalmente, usaría una tabla asociativa.
Un campo de máscara de bits es muy difícil de consultar y unirse.
Siempre puede asignar esto a su enumeración de banderas de C # y, si el rendimiento se convierte en un problema, refactorice la base de datos.
Legibilidad sobre optimización prematura;)
fuente
Almacene los permisos normalizados (es decir, no en una máscara de bits). Si bien obviamente no es un requisito para su escenario (especialmente si los permisos no cambian con frecuencia), hará que las consultas sean mucho más fáciles y obvias.
fuente
No hay una respuesta definitiva , así que haga lo que le funcione . Pero aquí está mi truco:
Utilice la opción 1 si
Utilice la opción 2 si
fuente
La única vez que puedo pensar en cuándo usaría un campo de máscara de bits para almacenar permisos, es cuando realmente está realmente limitado en la cantidad de memoria física que tiene ... como tal vez en un dispositivo móvil antiguo. En verdad, la cantidad de memoria que ahorras no vale la pena. Incluso para millones de usuarios, el espacio en el disco duro es barato, y puede ampliar los permisos, etc., mucho más fácilmente utilizando el enfoque sin máscara de bits (se trata de informar sobre quién tiene qué permisos, etc.)
Uno de los mayores dolores de cabeza con los que me he encontrado es la asignación de permisos a los usuarios directamente en la base de datos. Sé que debería probar y usar la aplicación para administrarse a sí misma y no mucho con los datos de la aplicación en general, pero a veces, es solo necesario. A menos que la máscara de bits sea en realidad un campo de caracteres, y pueda ver fácilmente qué permisos tiene alguien en lugar de un número entero, intente explicarle a un analista, etc., cómo otorgar acceso de escritura, etc.a alguien actualizando el campo ... y rezar tu aritmética es correcta.
fuente
Será útil cuando no cambien en su estructura y siempre se usen juntos. De esa manera, tiene pequeños viajes de ida y vuelta al servidor. También son buenos en cuanto al rendimiento porque puede afectar todos los derechos en una sola asignación de una variable.
Personalmente, no me gustan ... En algunas aplicaciones de alto rendimiento, todavía se usan. Recuerdo haber implementado una IA de ajedrez usando estos porque se podía evaluar un tablero en una sola comparación. Es un dolor trabajar con él.
fuente
Siempre lo almacenaría normalizado a menos que la base de datos simplemente contenga el registro por usted, y nunca hará nada con esto además de recuperar y guardar. Un escenario para esto es si al iniciar sesión, se obtiene la cadena de permiso de su usuario y, en el código del servidor, se procesa y almacena en caché. En ese caso, realmente no importa demasiado que esté desnormalizado.
Si lo está almacenando en una cadena y está tratando de trabajar en él a nivel de base de datos, tendrá que hacer algo de gimnasia para obtener los permisos para la página X, lo que puede ser doloroso.
fuente
Aconsejo no usar una máscara de bits por las siguientes razones:
Dependiendo de sus patrones de consulta, conjunto de características planificadas y distribución de datos, elegiría su opción 1, o incluso algo simple como:
user_permissions( user_id ,read ,create ,download ,print ,approve ,primary key(user_id) );
Agregar una columna es una modificación del esquema, pero supongo que agregar un privilegio "Purgar" requerirá algún código que lo acompañe, por lo que es posible que los privilegios no tengan que ser tan dinámicos como cree.
Si tiene una distribución de datos enferma, como que el 90% de la base de usuarios no tiene un solo permiso, el siguiente modelo también funciona bien (pero se desmorona cuando se realizan escaneos más grandes (una combinación de 5 vías frente a una sola tabla completa escanear).
user_permission_read( user_id ,primary key(user_id) ,foreign key(user_id) references user(user_id) ) user_permission_write( user_id ,primary key(user_id) ,foreign key(user_id) references user(user_id) ) user_permission_etcetera( user_id ,primary key(user_id) ,foreign key(user_id) references user(user_id) )
fuente
Sus consultas se ejecutarán más rápido usando una enumeración de banderas (máscara de bits), porque no necesitará incluir una combinación a la tabla asociada para entender el valor.
fuente
USER_PERMISSION
tabla, parece poco probable que la diferencia de rendimiento sea significativa (es poco probable que sea la operación de cuello de botella) y hay una pérdida sustancial de claridad en el código.