Máxima cantidad de columnas en una tabla

3 comentarios

Si te preguntan ¿cuántas columnas puede tener una tabla de Firebird? tu respuesta debe ser: “depende de los tipos de datos de las columnas”

¿Por qué eso?

Porque en Firebird no hay una cantidad máxima de columnas, como sí hay en Visual FoxPro, en Access y en otros lenguajes o motores de bases de datos. En los dos anteriormente nombrados el límite es de 255 columnas, pero en Firebird no existe tal cosa.

¿Por qué no?

Porque en Firebird una fila puede tener un máximo de 65.536 bytes y por lo tanto la cantidad máxima de columnas que puede tener una tabla varía entre 1 y 65.536

 Veamos esto más detalladamente:

Algunos tipos de datos ocupan una cierta cantidad predeterminada de bytes. Por ejemplo, SMALLINT ocupa siempre 2 bytes, INTEGER ocupa siempre 4 bytes, BLOB ocupa siempre 4 bytes, etc.

Pero tenemos dos casos especiales, que son CHAR y VARCHAR, la cantidad de bytes que ellos ocupan dependen del CHARACTER SET usado. Si no especificamos un CHARACTER SET o especificamos uno de los llamados “occidentales” entonces 1 carácter ocupará siempre 1 byte. Para nosotros que escribimos en castellano, portugués, francés, inglés, u otros idiomas occidentales eso es lo normal. Pero para quienes escriben en árabe, hebreo, chino, japonés, coreano, vietnamita, etc., eso ya no es cierto. Entonces, si el CHARACTER SET de la columna es por ejemplo ISO8859_1 (el recomendado para guardar texto escrito en castellano) una columna definida como CHAR(20) se cuenta como 20 bytes pero si el CHARACTER SET de la columna es UTF8 entonces una columna definida como CHAR(20) se cuenta como 40 bytes, ya que cada carácter ocupa 2 bytes cuando se usa UTF8.

¿Qué implica todo esto?

Que solamente tendremos problemas si la suma de los bytes ocupados por todas las columnas supera la cantidad de 65.536, si es igual o menos que eso estará todo bien.

Como vimos anteriormente, es muy fácil hacer esa suma.

Ejemplo 1:

Evidentemente, cada caso es distinto, depende de la estructura de la tabla para saber cuantas columnas como máximo puede tener pero supongamos lo siguiente para este ejemplo:

La cantidad de bytes que ocupa cada columna de una tabla es en promedio de 20. Por lo tanto, dividiendo 65.536 por 20 obtenemos como resultado 3.276 y para esa tabla en particular podríamos tener hasta 3.276 columnas.

Como vemos, mucho más que las 255 columnas del Visual FoxPro o del Access

De todas maneras, si necesitas una tabla que tenga tantas columnas lo más probable es que tu diseño esté muy mal y tendrías que ver la forma de mejorarlo.

Ejemplo 2:

En una tabla solamente necesitamos guardar números enteros y como cada columna de tipo INTEGER ocupa 4 bytes entonces podríamos tener un máximo de 65.536 / 4 columnas lo cual nos da como resultado 16.384 columnas.

Ejemplo 3:

En una tabla necesitamos guardar una columna de tipo SMALLINT, tres columnas de tipo INTEGER, y el resto serán columnas de tipo CHAR(60). Entonces tenemos: 65.536 – 2 – 3 * 4 = 65.522, y como 65.522 / 60 es igual a 1.092, podríamos tener hasta 1.096 columnas en esa tabla (1 columna SMALLINT, 3 columnas INTEGER, y 1.092 columnas CHAR(60)).

Conclusión:

En Firebird no hay una cantidad máxima de columnas que puede tener una fila de una tabla, lo que sí hay es una cantidad máxima de bytes que puede tener una fila de una tabla. Ese número es 65.536 bytes y es muchísimo más que suficiente para todas las necesidades que podamos tener. Si llegamos a necesitar más que 65.536 bytes entonces es seguro que nuestra Base de Datos está mal diseñada y deberíamos preocuparnos por mejorar eso.

Artículos relacionados:

Entendiendo a los conjuntos de caracteres

Algo más sobre los conjuntos de caracteres

Funciones útiles con los conjuntos de caracteres

Cantidad de columnas de una tabla

El índice del blog Firebird21

El foro del blog Firebird21

 

 

Anuncios

¿Cómo las bases de datos de Firebird aumentan de tamaño?

2 comentarios

El tamaño que ocupan en el disco duro las Bases de Datos de Firebird no es tan sencillo de conocer como a primera vista se podría uno imaginar.

Cuando creas una Base de Datos de Firebird ésta no está vacía sino que ya tiene dentro suyo muchas tablas que luego serán usadas durante las tareas que se realicen en esa Base de Datos. A esas tablas internas se las conoce como “metadatos“.

Entonces, lo primero que notarás después de crear una Base de Datos si miras su tamaño es que éste es de cientos de kilobytes. Eso es debido a los metadatos. Está ok, así tiene que ser.

Luego, tú o los usuarios empiezan a realizar operaciones de manipulación de datos (inserciones, modificaciones, borrados) y allí puedes notar algo curioso: el tamaño de la Base de Datos parece ser muy grande para la cantidad de filas que hay en las tablas.

¿Por qué?

Porque cuando el Firebird necesita que la Base de Datos tenga más espacio para las filas que estás insertando, modificando o borrando no aloja espacio solamente para esa fila en particular sino que aloja mucho más espacio.

¿Y por qué hace eso, por qué no aloja solamente el espacio en disco exactamente necesario?

Por tres motivos:

  1.  Porque la tarea de alojar más espacio lleva tiempo, no es instantánea. Si cada vez que se inserta una nueva fila tendría que estar alojando espacio en el disco duro para esa fila entonces esas inserciones demorarían demasiado tiempo en bases de datos donde hay muchas inserciones concurrentes y los usuarios se quejarían de la extrema lentitud
  2. Porque como el Firebird aloja el espacio en páginas esos continuos alojamientos fragmentarían excesivamente al disco duro
  3. Porque si el disco duro se queda sin espacio entonces hay una gran posibilidad de que la Base de Datos aún tenga suficiente espacio libre previamente alojado para que pueda terminar todas las operaciones que se estaban realizando en ella, sin corrupción.

Entonces, alojar más espacio del necesario, para tener bastante espacio libre disponible tiene tres grandes ventajas: a) se consigue una gran rapidez en todas las operaciones de inserción, modificación, borrado, porque el espacio ya está disponible, b) no se fragmenta excesivamente el disco duro y c) si el disco duro se queda sin espacio libre es muy probable que la Base de Datos no se corrompa porque los datos que faltaban grabarse se grabarán en el espacio previamente alojado.

Claro que esto también tiene sus desventajas. Estas son: a) cada vez que hay que alojar más espacio ocurre una demora, y b) la Base de Datos puede estar ocupando en el disco duro mucho espacio y si la cantidad libre en el disco duro es escasa eso afectará a los otros programas.

Claro que la desventaja b) es muy improbable que ocurra en esta época en que los discos duros son gigantescos y muy baratos, además si se cuenta con un Administrador que verifique el espacio libre en el disco duro nunca debería ocurrir algo así.

Un gráfico que ilustra el concepto

En este gráfico podemos ver como se aloja el espacio en una Base de Datos de Firebird.

ESTRUCTURA1

Gráfico 1. Si haces clic en la imagen la verás más grande

El espacio en C) está libre, nada hay ahí pero ya está asignado a la Base de Datos y para el Sistema Operativo es espacio ocupado por la Base de Datos y por ese motivo no puede ser usado por otros archivos. Cuando los usuarios insertan, modifican, o borran filas, esas inserciones, modificaciones, o borrados ocurren en C) y cuando el espacio en C) ya es pequeño se aloja más espacio a la Base de Datos, para que siempre tenga espacio libre a su disposición. Pero siempre esos alojamientos sirven para alojar a cientos o a miles de filas, no son para alojar a una o a dos filas sino a cientos o a miles de ellas. O sea que cada vez que se aloja un nuevo C) hay suficiente espacio en él para cientos o miles de filas.

¿Y cuántos bytes se alojan cada vez que la Base de Datos requiere de más espacio?

Cuando el Servidor descubre que la Base de Datos ya casi no tiene espacio libre debe reservar más espacio para ella. En el gráfico anterior la parte B) va creciendo hacia arriba haciendo que la parte C) sea cada vez más pequeña. Es entonces que el Servidor le aloja más espacio, según esta fórmula:

Al tamaño actual de la Base de Datos lo divide por 16

Nunca aloja más espacio que el establecido en la entrada DatabaseGrowthIncrement del archivo FIREBIRD.CONF (que por defecto es 128 Mb) ni menos de 128 Kb

Ejemplos:

Si la Base de Datos tiene 16 Mb entonces aloja 1 Mb (o sea, el tamaño de la Base de Datos dividido 16)

Si la Base de Datos tiene 16 Gb entonces aloja 128 Mb. No aloja 1 Gb sino que aloja 128 Mb. ¿Por qué? porque ese es el valor de la entrada DatabaseGrowthIncrement (que indica cual es el incremento máximo), salvo que haya sido cambiada. Recuerda: Nunca aloja más que el incremento máximo.

Si la Base de Datos tiene 16 Gb y la entrada DatabaseGrowthIncrement tiene el valor 268435456 (que equivale a 256 Mb) entonces aloja 256 Mb.

¿Es conveniente aumentar o disminuir el valor de la entrada DatabaseGrowthIncrement?

En general, el valor por defecto de 128 Mb es bastante bueno para la gran mayoría de las situaciones y podríamos dejarlo así, pero en bases de datos que tienen muchísimo movimiento y crecen mucho y rápido puede ser conveniente aumentarlo, para que el Firebird no esté a cada rato alojando nuevo espacio. Disminuirlo no se justifica (salvo que el disco duro tenga poquísimo espacio libre) porque disminuir significa aumentar la fragmentación del disco duro algo que nunca es conveniente porque un disco duro fragmentado tarda más en ser leído.

El valor de la entrada DatabaseGrowthIncrement se expresa en bytes, no en megabytes. Por lo tanto en ella por defecto veremos el número 134217728 que equivale a 128 Mb.

Conclusión:

Para que las operaciones de mantenimiento de tablas (inserción, modificación, borrado) sean muy rápidas el Firebird les asigna a las bases de datos más espacio en el disco duro que el estrictamente necesario. Eso además tiene la ventaja de que es muy improbable de que ocurra corrupción porque si el disco duro se queda sin espacio libre es muy posible que la Base de Datos no, que aún tenga suficiente espacio libre previamente alojado para terminar exitosamente todas las operaciones que estaban realizando los usuarios.

 Para saber cuantos bytes debe alojar cada vez que lo hace, el Firebird divide por 16 al tamaño actual de la Base de Datos. El tamaño mínimo que aloja es 128 Kb y el tamaño máximo que aloja lo determina la entrada DatabaseGrowthIncrement del archivo FIREBIRD.CONF que por defecto es de 128 Mb pero que puede ser cambiado. Si se cambia entonces lo aconsejable es aumentarlo porque disminuirlo aumentará la fragmentación del disco duro, algo que nunca es bueno.

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21