2008-09-13 7 views
7

Iba a hacer una pregunta aquí sobre si mi diseño para algunas tablas de bases de datos de usuarios/roles era aceptable, pero después de algunas investigaciones encontré esta pregunta:Múltiples tipos de permisos (roles) almacenados en la base de datos como decimal simple

What is the best way to handle multiple permission types?

suena como un enfoque innovador, así que en vez de una tabla de muchos-a-muchos relación users_to_roles, I tener varios permisos definidos como un solo decimal (tipo de datos int supongo). Eso significa que todos los permisos para un solo usuario están en una fila. Probablemente no tenga sentido hasta que lea la otra pregunta y responda

No puedo entender esto. ¿Alguien puede explicar el proceso de conversión? Suena "bien", pero simplemente no entiendo cómo convierto los roles a un decimal antes de que aparezca en el archivo db, y cómo se convierte de nuevo cuando sale del archivo db. Estoy usando Java, pero si lo apagaste, eso también sería genial.

Aquí está la respuesta original en la remota posibilidad de la otra pregunta se elimina:

"En lo personal, a veces uso una enumeración bandera de permisos de esta manera se puede usar AND, OR, NOT y operaciones bit a bit XOR sucesivamente. . artículos de la enumeración

[Flags] 
public enum Permission 
{ 
    VIEWUSERS = 1, // 2^0 // 0000 0001 
    EDITUSERS = 2, // 2^1 // 0000 0010 
    VIEWPRODUCTS = 4, // 2^2 // 0000 0100 
    EDITPRODUCTS = 8, // 2^3 // 0000 1000 
    VIEWCLIENTS = 16, // 2^4 // 0001 0000 
    EDITCLIENTS = 32, // 2^5 // 0010 0000 
    DELETECLIENTS = 64, // 2^6 // 0100 0000 
} 

a continuación, se pueden combinar varios permisos usando el operador AND bit a bit.

Por ejemplo, si un usuario puede ver & editar usuarios, el resultado de la operación binaria es 0000 0011 que convertida a decimal es 3. Luego puede almacenar el permiso de un usuario en una sola columna de su Base de datos (en nuestro caso sería 3).

Dentro de su aplicación, sólo necesita otra operación en modo bit (OR) para verificar si un usuario tiene un permiso especial o no."

+0

Pregunta muy útil ... y contestador ... –

Respuesta

4

Utiliza operaciones a nivel de bit. El pseudo-código sería algo como:

bool HasPermission(User user, Permission permission) { 
    return (user.Permission & permission) != 0; 
} 

void SetPermission(User user, Permission permission) { 
    user.Permission |= permission; 
} 

void ClearPermission(User user, Permission permission) { 
    user.Permission &= ~permission; 
} 

permiso es el tipo de enumeración se define en su puesto, a pesar de cualquier tipo que es tiene que estar basada en un tipo entero similar. Lo mismo se aplica al campo User.Permission.

Si esos operadores (&, | = y & =) no tienen sentido para usted, entonces lea en operaciones bit a bit (Y a nivel de bit y O a nivel de bit).

+0

¿Sería justo decir que la desventaja de esta técnica es que las definiciones de permisos están en la enumeración, por lo que se requiere acceso a la aplicación para comprender qué se coloca en la base de datos? –

+0

Eso sería una afirmación justa, aunque también podría definir los valores en una tabla en la base de datos (aunque no podría usar una clave externa ...). Esta "desventaja" es verdadera para cualquier enumeración basada en enteros en la base de datos. – Brannon

+0

Si eso es un problema, siempre puede ir con roles basados ​​en filas (y una relación muchos a muchos). – Brannon

3

En realidad, esto es cómo determinamos la autoridad dentro de una aplicación web bastante grande que yo soy el DBA para

Si usted va a hacer algo como esto, que realmente va a beneficiar de tener un numbers table esto hará que sus cálculos mucho más rápido

la configuración básica incluye las siguientes tablas...:

  1. Grupos - para hacer muchos a muchos de los usuarios y los puntos de seguridad
  2. puntos de seguridad - que contienen un valor de autorización en el anonimato y otra para usuarios autenticados que no forman parte de un grupo separado
  3. punto de seguridad Grupo tabla de unión
  4. Una tabla especial de números BitMask que contiene entradas para los valores^2. Por lo tanto, hay una entrada para 2 (2) y dos entradas para tres (2 y 1). Esto nos evita tener que calcular valores cada vez.

Primero determinamos si el usuario está conectado. De lo contrario, devolvemos la autorización anónima para el punto de seguridad.

A continuación determinamos si el usuario es miembro de cualquier grupo asociado con el punto de seguridad a través de un simple EXISTS usando un JOIN.Si no lo son, devolvemos el valor asociado con el usuario autenticado. La mayoría de los valores predeterminados anónimos y autenticados están configurados en 1 en nuestro sistema porque le solicitamos que pertenezca a grupos específicos.

Nota: Si un usuario anónimo consigue un acceso, la interfaz de los arroja a un registro en la caja para que puedan iniciar sesión y vuelve a intentarlo.

Si el usuario es un miembro de uno o más grupos, entonces seleccione valores distintos de la mesa BitMask para cada uno de los valores definidos para los grupos. Por ejemplo, si pertenecía a tres grupos y tenía un nivel de autorización de 8, uno con 12 y el último con 36, nuestra selección contra la tabla Máscara de bit devolvería 8, 8 y 4, y 4 y 32, respectivamente. Al hacer una distinción obtenemos el número 4, 8 y 32 que mordieron correctamente las máscaras a 101100.

Ese valor se devuelve como el nivel de autorización de los usuarios y procesado por el sitio web.

¿Tiene sentido?

+0

Definitivamente estoy interesado en cómo funcionaría esta técnica. No tiene que profundizar mucho, pero algunos detalles adicionales serían muy útiles, especialmente sobre cómo mapear el proceso de conversión a lo que está almacenado en el DB. –

Cuestiones relacionadas