¿Debo usar la cadena de bits PostgreSQL?

18

He estado aprendiendo sobre el bit stringtipo de datos últimamente, y tengo mucha curiosidad sobre:

  1. Al final de esta página del documento está la oración:

    ... más 5 u 8 bytes de sobrecarga dependiendo de la longitud de la cadena

  2. Cómo se manejan las cadenas de bits en otros lenguajes como PHP, Java, C #, C ++, etc., a través de controladores como Npgsql, ODBC, etc.

Para la pregunta n. ° 1, el uso de smallint o bigint será mucho más eficiente en el almacenamiento y tal vez ofrezca una ganancia de rendimiento ya que los enteros son compatibles en todas partes. La mayoría de los lenguajes de programación manejan operaciones de bits en enteros con facilidad. Si ese es el caso, ¿cuál es el punto de introducir el tipo de datos de cadena de bits? ¿Es solo para casos que necesitan una gran cantidad de máscaras de bits? ¿Quizás la indexación de campo de bits? Tengo más curiosidad acerca de cómo se realiza la indexación de campo de bits en PostgreSQL.

Para el # 2, estoy confundido, más que curioso. Por ejemplo, ¿qué pasa si almaceno máscaras de bits de día de la semana en un campo de bit (7), un bit por día, con el bit más bajo que representa el lunes. Luego consulto el valor en PHP y C ++. ¿Que voy a obtener? La documentación dice que tendré una cadena de bits, sin embargo, una cadena de bits no es algo que pueda usar directamente, como con los enteros. Entonces, en este caso, ¿debería renunciar al campo de bits?

¿Alguien puede explicar por qué y cuándo debo usar bit o bit variable?

Jackey Cheung
fuente
2
La respuesta de Erwin sobre SO es excelente (y si no te importa copiarla en @Erwin, sería útil tenerla aquí), pero me gustaría agregar mi propia precaución: en la mayoría de los casos no contemplarías almacenar información en cadenas de bits en un RDBMS, utilizando columnas booleanas separadas en la solución normal, independientemente de la 'eficiencia' de almacenamiento.
Jack Douglas
@JackDouglas: No me importaría copiar mi respuesta. Sin embargo, me pregunto: ¿es una buena idea duplicar una respuesta en los sitios de SE?
Erwin Brandstetter
@Erwin No veo por qué no: hay cierta superposición entre los sitios y se supone que ambos están solos (por ejemplo, no podríamos, y de todos modos no podríamos) cerrar una pregunta aquí como un duplicado si hubiera una pregunta idéntica sobre SO). Nuestro enfoque se centra más en los problemas de los "expertos", pero IMO su respuesta se ajusta a esa categoría tal como está :)
Jack Douglas
@JackDouglas: Bueno, tiene sentido. ¿Y cómo podría estar en desacuerdo después de los elogios que recibiste? ;)
Erwin Brandstetter

Respuestas:

18

Si solo tiene algunas variables, consideraría mantener booleancolumnas separadas .

  • La indexación es fácil. En particular, los índices en las expresiones son fáciles.
  • Las condiciones para las consultas y la indexación parcial son fáciles de escribir y leer y tienen sentido.
  • Una columna booleana ocupa 1 byte. Para solo unas pocas variables, esto ocupa el menor espacio.
  • A diferencia de las otras opciones, las columnas booleanas permiten NULLvalores para bits individuales si lo necesita. Siempre puede definir columnas NOT NULLsi no lo hace.

Optimizando el almacenamiento

Si tiene más de una mano de variables completas pero menos de 33, una integercolumna puede servirle mejor. (O a bigintpara hasta 64 variables).

  • Ocupa 4 bytes en el disco.
  • Indización muy rápida para coincidencias exactas ( =operador).
  • El manejo de valores individuales puede ser más lento / menos conveniente que con bit stringo boolean.

Con incluso más variables, o si desea manipular mucho los valores, o si no tiene tablas enormes y espacio en disco / RAM no es un problema, o si no está seguro de qué elegir, lo consideraría bit(n)obit varying(n) .

Ejemplos

Para solo 3 bits de información, las booleancolumnas individuales funcionan con 3 bytes, integernecesita 4 bytes y bit string6 bytes (5 + 1).

Para 32 bits de información, un integertodavía necesita 4 bytes, un bit stringocupa 9 bytes para el mismo (5 + 4) y las booleancolumnas ocupan 32 bytes.

Otras lecturas

Erwin Brandstetter
fuente
Sí estoy de acuerdo con usted. Actualmente, estoy usando samllint para almacenar la máscara de bits de los días laborables. Se adaptaba al caso, eficiencia de almacenamiento / rendimiento amplio. Sin embargo, si tuviera un poco más de indexación / filtrado en máscaras de bits, fallaría debido al bajo rendimiento.
Jackey Cheung
3

Todos los tipos de PostgreSQL son útiles para algunas cosas y menos útiles para otras. En general, obtiene más de preocuparse por la funcionalidad primero y el rendimiento después. PostgreSQL tiene una gran cantidad de funciones para manipular varios tipos de tipos de datos y estos no son una excepción.

Esperaría en la capa de aplicación, a menos que su controlador db lo maneje a través de algún tipo de conversión de tipo, obtendrá una representación de cadena y tendrá que manejar esto. Por lo tanto, puede o no ser útil en esa capacidad.

Donde probablemente sea útil es cuando desea seleccionar registros basados ​​en operaciones bit a bit, como bit a bit o bit a bit, o manipular los datos en consultas SQL. A menos que esté haciendo esto, muchas de las características más esotéricas de PostgreSQL son menos útiles.

Tenga en cuenta también que para cadenas más largas de información binaria hay una interfaz de objeto grande que le permite hacer streaming, etc. y una interfaz bytea que permite una representación de cadena más compacta.

tl; dr: Si lo necesitas lo sabrás. De lo contrario, archívelo en la sección "reservado para uso futuro" de su mente.

Chris Travers
fuente