sql - mascaras - mascara de bits en c
¿Existe un límite práctico para el tamaño de las máscaras de bits? (7)
Algunos lenguajes (creo que perl does, no estoy seguro) permiten la aritmética bit a bit en las cadenas. Te da un rango efectivo mucho mayor. (Combinaciones (strlen * 8bit chars))
Sin embargo, no utilizaría un solo valor para la superposición de más de un / tipo / de datos. El triplete r / w / x básico de ints de 3 bits probablemente sea el límite "práctico" superior, no por razones de eficiencia de espacio, sino por razones prácticas de desarrollo.
(Php usa este sistema para controlar sus mensajes de error, y ya he descubierto que es un poco exagerado cuando tienes que definir valores en los que las constantes de php no son residentes y debes generar el entero a mano, y se honesto, si chmod no soportaba la sintaxis de estilo ''ugo + rwx'', nunca querría usarlo porque nunca puedo recordar los números mágicos)
En el instante en que tienes que abrir una tabla de constantes para depurar el código, sabes que has ido demasiado lejos.
Hay una forma común de almacenar múltiples valores en una variable, mediante el uso de una máscara de bits. Por ejemplo, si un usuario tiene privilegios de lectura, escritura y ejecución en un elemento, puede convertirlo en un solo número diciendo read = 4 (2^2), write = 2 (2^1), execute = 1 (2^0)
y luego agréguelos para obtener 7.
Utilizo esta técnica en varias aplicaciones web, donde generalmente almacenaba la variable en un campo y le doy un tipo de MEDIUMINT o lo que sea, dependiendo de la cantidad de valores diferentes.
Lo que me interesa es si hay un límite práctico para la cantidad de valores que puede almacenar de esta manera. Por ejemplo, si el número era superior a 64, no podría usar números enteros (64 bits). Si este fuera el caso, ¿qué usarías? ¿Cómo afectaría la lógica de su programa (es decir, si todavía pudiera usar comparaciones bit a bit)?
Sé que una vez que comiences a obtener grandes conjuntos de valores, un método diferente sería la solución óptima, pero estoy interesado en los límites de este método.
Con un entero de 64 bits, puede almacenar valores de hasta 2 ^ 64-1, 64 es solo 2 ^ 6. Así que sí, hay un límite, pero si necesita más de 64, vale la pena, estaría muy interesado en saber qué estaban haciendo todos :)
¿En cuántos estados necesitas pensar? Si tiene 64 estados potenciales, la cantidad de combinaciones en que pueden existir es el tamaño completo de un entero de 64 bits.
Si necesita preocuparse por 128 banderas, entonces un par de vectores de bits sería suficiente (2 ^ 64 * 2).
Además : en Programming Pearls, hay una discusión extensa sobre el uso de una matriz de bits de longitud 10 ^ 7, implementada en números enteros (para contener números 800 usados): es muy rápida y muy apropiada para la tarea descrita en ese capítulo.
Etiquetaste esta pregunta SQL, por lo que creo que debes consultar la documentación de tu base de datos para encontrar el tamaño de un entero. Luego resta un bit para el signo, solo para estar seguro.
Editar: Tu comentario dice que estás usando MySQL. La documentación para los Tipos Numéricos de MySQL 5.0 establece que el tamaño máximo de un NÚMERO es de 64 o 65 dígitos. Eso es 212 bits para 64 dígitos.
Recuerde que el idioma que elija debe poder trabajar con esos dígitos, de todos modos, puede estar limitado a un número entero de 64 bits.
He usado máscaras de bits en el código del sistema de archivos donde la máscara de bits es mucho más grande que una palabra de máquina. pensar en ello como una "variedad de booleanos";
(Máscaras de recorrido en la memoria flash si quieres saber)
muchos compiladores saben cómo hacer esto por ti . Adda un poco de código OO para tener tipos que operan de manera sensata y luego su código comienza a verse como si fuera su intención, no como un ataque de bits.
Mis 2 centavos.
Por ejemplo, .NET usa una matriz de enteros como almacenamiento interno para su clase BitArray. Prácticamente no hay otra alternativa.
Dicho esto, en SQL necesitará más de una columna (o usar BLOBS) para almacenar todos los estados.
En la parte superior de mi cabeza, escribiría una función set_bit
y get_bit
que podría tomar una matriz de bytes y un desplazamiento de bits en la matriz, y usar algunos giros de bits para establecer / obtener el bit apropiado en la matriz. Algo como esto (en C, pero espero que entiendas la idea):
// sets the n-th bit in |bytes|. num_bytes is the number of bytes in the array
// result is 0 on success, non-zero on failure (offset out-of-bounds)
int set_bit(char* bytes, unsigned long num_bytes, unsigned long offset)
{
// make sure offset is valid
if(offset < 0 || offset > (num_bytes<<3)-1) { return -1; }
//set the right bit
bytes[offset >> 3] |= (1 << (offset & 0x7));
return 0; //success
}
//gets the n-th bit in |bytes|. num_bytes is the number of bytes in the array
// returns (-1) on error, 0 if bit is "off", positive number if "on"
int get_bit(char* bytes, unsigned long num_bytes, unsigned long offset)
{
// make sure offset is valid
if(offset < 0 || offset > (num_bytes<<3)-1) { return -1; }
//get the right bit
return (bytes[offset >> 3] & (1 << (offset & 0x7));
}
Viejo hilo, pero vale la pena mencionar que hay casos que requieren máscaras de bits hinchadas, por ejemplo, huellas dactilares moleculares, que a menudo se generan como matrices de 1024 bits que hemos empaquetado en 32 campos bigint (SQL Server no admite UInt32). Las operaciones de bits funcionan bien, hasta que la mesa comienza a crecer y se da cuenta de la lentitud de las llamadas a funciones separadas. El tipo de datos binarios funcionaría si no fuera por la prohibición de T-SQL de que los operadores bit a bit tengan dos operandos binarios.