Consultas a tablas que tienen columnas de tipo BLOB

4 comentarios

Si escribimos un SELECT a una tabla que tiene columnas de tipo BLOB ¿cómo afectan a la velocidad de respuesta esas columnas?

Las columnas de tipo BLOB son muy útiles para guardar textos largos, fotografías, canciones, vídeos, etc. pero recuperar esa cantidad masiva de bytes puede hacer demorar mucho a nuestras consultas, entonces ¿qué podemos hacer para tener una buena velocidad de respuesta?

Primero, tener a las columnas de tipo BLOB en una tabla separada, exclusiva para ella. Por ejemplo, tenemos una tabla llamada PRODUCTOS y otra tabla relacionada llamada PRODUCTOSFOT, y en esta última tabla guardaremos las fotografías de los productos.

Segundo, si en una columna de tipo BLOB no se guardarán (aún, por lo menos) datos. ¿Es preferible que su valor sea NULL o que su valor sea un espacio en blanco?

Para no tener que escribir COALESCE(MiColumnaBLOB, ») alguna gente prefiere guardar un espacio en blanco en la columna BLOB, ¿es esa una buena práctica?

No. Y la razón es que si el Firebird encuentra un NULL en una columna de tipo BLOB entonces ya sabe que no hay datos para esa columna y continúa con su siguiente tarea. Pero si hay cualquier valor distinto de NULL entonces ese valor distinto de NULL es un puntero a una página que guarda BLOBs. Por lo tanto debe visitar esa página para recuperar el contenido que encuentre en ella y que corresponde a la fila actual. Y aunque ese contenido sea un simple espacio en blanco tuvo que visitar igualmente a esa página.

En tablas que tienen pocas filas ese constante ir y venir entre las páginas de datos y las páginas BLOB no afectará mucho a la velocidad de respuesta de las consultas, pero en tablas que tienen cientos de miles o millones de filas ya es otro tema pues allí sí que será notoria la diferencia.

Por lo tanto, para que las columnas de tipo BLOB no hagan demorar mucho a los SELECTs:

  1. Esas columnas deben encontrarse en una tabla separada
  2. Si aún no se guarda algo en ellas, su valor debe ser NULL

Artículos relacionados:

Usando columnas de tipo BLOB

Guardando las columnas BLOB en tablas separadas

Almacenamiento de las columnas de tipo BLOB

Un stored procedure para conocer el tamaño total de los BLOB

Entendiendo las páginas de la Base de Datos

Eligiendo el tamaño adecuado de las páginas de la Base de Datos

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

El índice del blog Firebird21

El foro del blog Firebird21

Solamente llamar a vistas y a stored procedures

4 comentarios

Una característica que siempre se ve en el código fuente de las aplicaciones bien escritas es que solamente llaman a vistas y a stored procedures.

Y a fuer de ser sinceros, tales aplicaciones son escasas, muy escasas.

Muchos programadores escriben en el código fuente de sus aplicaciones los comandos INSERT, UPDATE, DELETE, y SELECT a columnas de tablas.

Y eso está mal, muy mal.

¿Por qué?

Bueno, hay varios motivos. El autor de este blog varias veces ha evaluado aplicaciones y códigos fuentes escritos por otras personas y al finalizar la evaluación ha elevado un informe detallando lo bueno y lo malo que encontró. Y en el capítulo «Comunicación con la Base de Datos» estos son algunos problemas:

  1. El código fuente es desprolijo. Si alguien escribe los comandos mencionados más arriba en general lo hace de forma desordenada, calculando valores de variables, o realizando otras tareas no relacionadas, y eso además de no ser eficiente queda «feo».
  2. No permite el trabajo en equipo. Cuando se trabaja en equipo lo ideal es modularizar al máximo para que cada función o cada rutina sea escrita una sola vez y utilizada por muchos programadores. De esa manera si hay algún error solamente puede estar en un lugar y será fácil encontrarlo y corregirlo. Pero si cada quien escribe los comandos en su propio código fuente entonces los errores pueden estar en muchos lugares y encontrarlos y corregirlos demorará mucho más tiempo. Y cualquier cambio a cualquiera de los códigos fuente puede introducir un nuevo error. Y esto inclusive puede ocurrir aunque se trate de un solo programador pero que tiene por ejemplo el INSERT a una sola tabla en dos o más programas.
  3. No hay un responsable de la Base de Datos. Cuando se trabaja en equipo una persona debe ser la encargada de verificar el correcto diseño y funcionamiento de la Base de Datos. Si cada programador escribe lo que se le ocurre en su propio código fuente, tales verificaciones serán imposibles de realizar y los errores posibles, muchísimos.
  4. No se puede verificar que el comando finalizará sin error hasta el momento de ser ejecutado. Por ejemplo, mirando un INSERT en el código fuente no se puede tener la seguridad de que esa fila será insertada o que ocurrirá una excepción de «table unknown», «column unknown» o alguna otra.
  5. No se puede comprobar la eficiencia del comando. Este es el punto más importante. Los programas de administración gráfica, como el EMS SQL Manager, nos muestran la cantidad de filas leídas, la cantidad de filas extraídas, y en forma gráfica los índices usados. También podemos ver el PLAN utilizado. Así es fácil descubrir que no se está usando un índice cuando sí debería usarse, o que las filas leídas son demasiadas, o que se está usando el índice incorrecto, etc. Y es muy fácil y muy rápido cambiar la vista o el stored procedure con la intención de hacerlo más eficiente. Sin embargo, si escribimos los comandos dentro del código fuente de una aplicación es imposible saber si es eficiente o no lo es. Podemos «creer» que es eficiente y que usa los índices correctos, cuando en realidad no es así. Y hay además otro problema: aunque hoy una vista o un stored procedure sean muy eficientes, podrían dejar de serlo dentro de unos meses cuando las tablas tengan más filas o se hayan cambiado o borrado algunas filas. Escribiendo los comandos INSERT, UPDATE, DELETE, y SELECT a columnas de tablas dentro del código fuente de nuestras aplicaciones jamás podremos estar seguros de que son los más eficientes que podemos tener, en cambio si dichos comandos están dentro de una vista o dentro de un stored procedure sí que podremos tener esa seguridad.

VISTAS-STORED-1

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

VISTAS-STORED-2

Captura 2. Si haces clic en la imagen la verás más grande

Mirando la Captura 1. sabemos que la vista involucra a 3 tablas y que las 3 tablas usan índices (e inclusive sabemos los nombres de esos índices), y que la cantidad de filas parece estar correcta, sin embargo … ese SORT en la Captura 2. nos llama poderosamente la atención porque los SORT son muy lentos, ya que deben ordenar las filas de las tablas; ese ordenamiento se realiza en la memoria del Servidor (cuando tal cosa es posible) o en el disco duro (cuando no puede ordenarse en la memoria). En general, debemos evitar a los SORT como a la peste, porque indican que la tabla, la vista, el stored procedure seleccionable, o los resultados deberán ser ordenados, y eso puede demorar muchísimo tiempo en tablas grandes.

Si en lugar de escribir una vista, como en el ejemplo de arriba, hubiéramos escrito un SELECT en el código fuente de nuestro lenguaje de programación, ¡¡¡jamás nos habríamos percatado de ese SORT malévolo!!!. Y claro, cuando las tablas tuvieran muchas filas los usuarios se quejarían de la lentitud, pero mientras tanto les hicimos perder mucho tiempo innecesariamente porque nuestra consulta no estaba optimizada.

Conclusión:

Si quieres programar correctamente y eficientemente y profesionalmente, en el código fuente de tus aplicaciones solamente debes llamar a vistas y a stored procedures. Nunca, jamás, y por ningún motivo, ejecutar un INSERT, un UPDATE, un DELETE, o un SELECT a columnas de una tabla.

Los SELECT solamente a vistas.

Los INSERT, UPDATE, DELETE, y algunos SELECT, solamente dentro de un stored procedure.

Cuando se programan aplicaciones siempre se van encontrando errores y problemas aquí y allá. Para disminuir esa cantidad de errores y de problemas, y para optimizar las consultas y los procesamientos, siempre lo mejor es desde el código fuente de nuestras aplicaciones llamar a vistas y a stored procedures, y a nada más.

Artículos relacionados:

Optimizando las consultas

Optimizando las subconsultas

Optimizando los JOIN

Evitando que el optimizador … optimice

¿Por qué usar stored procedures?

Usando un stored procedure como una función

Escribiendo un stored procedure

Usando un PLAN

Algo más sobre PLAN

Entendiendo el contenido de un PLAN

El índice del blog Firebird21

El foro del blog Firebird21

Lidiando con la basura

1 comentario

Lo peor que le puede ocurrir a una Base de Datos operativa es que tenga basura dentro de ella porque en ese caso todas las consultas y todos los procesos dejarán de ser confiables. Se llama «basura» a cualquier dato que está guardado en alguna tabla pero no debería estar allí. La basura puede ser de dos tipos:

  • Relacionada con filas
  • Relacionada con columnas

Basura relacionada con filas

Estas se producen cuando dos o más filas tienen los mismos datos, es decir se tienen filas duplicadas; o cuando alguna fila tiene NULL en todas sus columnas.

¿Cómo se evita la basura relacionada con las filas?

Con las restricciones Primary Key y Unique Key.

Todas las tablas deben tener una restricción Primary Key, porque de esta manera se podrá identificar a cada fila sin equivocación posible y no se tendrán filas duplicadas totalmente, ya que al menos la Primary Key será diferente.

Cuando se sabe que una fila no admite duplicados, por ejemplo la columna CODIGO_PRODUCTO debe ser única, entonces una restricción Unique Key será la solución.

Sin embargo, a veces no se puede usar una Unique Key aunque se sospecha que puede haber filas duplicadas. Por ejemplo dos clientes pueden tener el mismo nombre, e inclusive el mismo domicilio, el mismo teléfono y la misma localidad porque son padre e hijo y viven en la misma casa.

Entonces aquí lo importante es detectar que hay filas duplicadas. Para ello podríamos escribir una consulta simple que nos indique si tal cosa ocurre:

Listado 1.

 
SELECT 
   CLI_NOMBRE, 
   COUNT(*) 
FROM 
   CLIENTES 
GROUP BY 
   CLI_NOMBRE 
HAVING 
   COUNT(*) >= 2

La consulta del Listado 1. nos mostrará los nombres de todos los clientes que estén duplicados, o sea que se encuentren dos o más veces en la tabla de CLIENTES.

Sin embargo, escribir esa consulta cada vez que deseamos verificar nuestras tablas puede ser muy tedioso, así que la mejor alternativa es crear una vista que nos de esa información y que podamos ejecutar cada vez que lo deseemos.

Listado 2.

CREATE VIEW V_MOSTRAR_DUPLICADOS(
   NOMBRE_TABLA,
   NOMBRE,
   CANTIDAD_DUPLICADOS)
AS
   SELECT
      'CLIENTES' AS NOMBRE_TABLA,
      CLI_NOMBRE AS NOMBRE,
      COUNT(*) AS CANTIDAD_DUPLICADOS
   FROM
      CLIENTES
   GROUP BY
      CLI_NOMBRE
   HAVING
      COUNT(*) >= 2

   UNION

   SELECT
      'GARANTES' AS NOMBRE_TABLA,
      GAR_NOMBRE,
      COUNT(*) AS CANTIDAD_DUPLICADOS
   FROM
      GARANTES
   GROUP BY
      GAR_NOMBRE
   HAVING
      COUNT(*) >= 2;

La vista V_MOSTRAR_DUPLICADOS nos mostrará de una sola vez a todos los clientes duplicados y también a todos los garantes duplicados. Desde luego que nuestra vista real tendrá a muchas tablas más, en este ejemplo se muestran solamente dos tablas para hacer el Listado 2. corto pero la idea es esa: con una sola vista, y mediante UNION tendremos a todas las filas duplicadas de todas las tablas que nos interesa verificar. Para poder conocer a cual tabla pertenece cada fila, en la primera columna colocamos el nombre de la tabla.

BASURA1

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

Y listo, ahora solamente nos queda comprobar que esas filas son legítimas o que deben ser eliminadas porque realmente están duplicadas.

Basura relacionada con columnas

Esta es la clase de basura que más comúnmente se encuentra en las tablas mal diseñadas. Ocurre cuando en una columna hay un dato incorrecto.

Por ejemplo, el precio de venta del producto es negativo, o la fecha de la cobranza es anterior a la fecha de la venta, o la cantidad vendida es cero, o la venta no tiene fecha, etc.

¿Cómo se evita la basura relacionada con las columnas?

Tenemos varias herramientas que nos permitirán realizar esa tarea:

  • La estructura de la tabla
  • Los dominios
  • La Primary Key
  • Las Foreign Keys
  • Los check
  • Las Unique Keys
  • Los triggers

En la estructura de la tabla podemos determinar que una columna no acepte valores NULL o que tenga un valor por defecto.

BASURA2

Captura 2. Si haces clic en la imagen la verás más grande

BASURA7

Captura 3. Si haces clic en la imagen la verás más grande

En los dominios podemos determinar los valores, o el rango de valores permitidos.

BASURA3

Captura 4. Si haces clic en la imagen la verás más grande

BASURA4

Captura 5. Si haces clic en la imagen la verás más grande

Con la Primary Key evitamos que esa columna tenga valores NULL o valores duplicados.

BASURA5

Captura 6. Si haces clic en la imagen la verás más grande

Con las Foreign Key evitamos que en una columna se introduzca un valor que no se encuentre en otra tabla. Se usa en las relaciones padre-hija y nos asegura que ambas tablas pueden relacionarse y que en ninguna fila de la tabla hija tengamos un valor que no se encuentre también en una fila de la tabla padre.

BASURA6

Captura 7. Si haces clic en la imagen la verás más grande

Con las restricciones check podemos comparar a dos (o más) columnas de la misma fila e inclusive con columnas de otras tablas.

BASURA8

Captura 8. Si haces clic en la imagen la verás más grande

En la Captura 8. vemos a dos restricciones check. La primera nos asegura que el valor colocado en la columna PRD_CODSUC exista en la tabla de SUCURSALES. ¿Y por qué no usar una Foreign Key aquí? Se podría y se obtendría el mismo resultado pero no sería eficiente ¿Por qué no? Porque las sucursales en general son muy pocas y en Firebird indexar por una columna que tiene muy pocos valores distintos es muy mala idea. Y todas las restricciones Foreign Key sí o sí crean un índice, así que lo recomendable es usar una restricción check que verifique si la sucursal existe o no. La segunda restricción check nos asegura que el precio de venta de un producto siempre sea mayor que su precio de costo.

Las restricciones check se deben cumplir siempre que se quiera insertar (INSERT) o actualizar (UPDATE) una fila. Así que en el ejemplo anterior una fila solamente podrá ser grabada si ambas restricciones check se cumplen.

Con las Unique Key nos aseguramos que nunca dos o más filas puedan tener el mismo valor.

BASURA9

Captura 9. Si haces clic en la imagen la verás más grande

En la Captura 9. vemos que hay una restricción Unique Key sobre las columnas PRD_CODSUC y PRD_CODIGO de la tabla PRODUCTOS. ¿Qué significa eso? Que esa combinación nunca podrá repetirse. En la misma Sucursal no podrá haber dos productos que tengan el mismo código. El Firebird no permitirá que la fila sea grabada, si se quiere hacer algo así.

Los triggers son la herramienta más poderosa que tenemos para evitar que entre basura en una tabla. ¿Por qué? Porque se puede escribir mucho código dentro de ellos. Hasta ahora, las herramientas que habíamos visto eran muy simples, por supuesto que nos ayudaban pero ninguna se compara a la potencia de los triggers.

BASURA10

Captura 10. Si haces clic en la imagen la verás más grande

En la Captura 10. vemos un trigger encargado de validar que el e-mail introducido sea válido. Si el e-mail no es válido entonces se lanza una excepción y por lo tanto no se podrá insertar (INSERT) ni actualizar (UPDATE) esa fila. Eso significa que además de todas las otras restricciones que puedan existir en la tabla de CLIENTES, para que se pueda insertar o actualizar una fila el e-mail debe ser válido.

BASURA11

Captura 11. Si haces clic en la imagen la verás más grande

En la Captura 11. el trigger valida que el código del país sea «54» o «595». Cualquier otro código de país será rechazado. Además también valida que en el caso de ser «595» el código del área sea «21» o «61», cualquier otro código de área será rechazado.

Una tabla puede tener muchos triggers, y si aunque sea uno solo de ellos finaliza con una excepción entonces la fila no será grabada en la tabla.

Por consiguiente, para que una fila pueda ser grabada en la tabla todos los triggers, el 100% de ellos, deben finalizar correctamente.

Conclusión:

Lo peor que le puede ocurrir a una Base de Datos operativa es tener basura dentro de ella. ¿Por qué? porque en ese caso ninguna consulta y ningún proceso podrá ser confiable.

Nuestra principal tarea cuando diseñamos una Base de Datos es impedir que entre basura en ella. Si tiene basura, no sirve.

El Firebird nos provee de varias herramientas para ayudarnos con la tarea de evitar a la basura y debemos aprender a usar todas esas herramientas pues para eso están.

La más poderosa de esas herramientas es el trigger, solamente con ella podríamos reemplazar a todas las demás herramientas pero a costa de escribir mucho código. Por lo tanto lo más inteligente es usar a todas las herramientas que tenemos a nuestra disposición y no solamente a los triggers.

Artículos relacionados:

Validando un e-mail

Validando números de teléfono

Asegurando tener datos consistentes en la Base de Datos

La doble validación

Entendiendo a las Foreign Keys

Conceptos sobre las Foreign Keys

Entendiendo las excepciones

Escribiendo un trigger

El índice del blog Firebird21

El foro del blog Firebird21

Escribiendo un trigger

¿Por qué usar stored procedures?

5 comentarios

Si recién estás empezando con Firebird o con bases de datos relacionales entonces es posible que te hayas hecho la pregunta que da título a este artículo.

Con todo derecho podrías preguntarte: ¿para qué me servirá usar stored procedures? ¿qué ganaré si los uso?

En primer lugar hay que aclarar que no es obligatorio usarlos. Todo lo que puedes hacer dentro de un stored procedure también puedes hacerlo en el código fuente de tu lenguaje de programación.

Sin embargo, las ventajas de usar stored procedures son varias y muy importantes:

  1. Rapidez
  2. Seguridad
  3. Independencia
  4. Trabajo en equipo
  5. Encapsulamiento
  6. Capas separadas

Veamos cada una de esas ventajas con más detalle:

Ventaja 1. Rapidez

Esta ventaja a su vez se divide en tres partes:

a) Procesamiento en el Servidor

b) Optimización de los resultados

c) Velocidad en la codificación

Procesamiento en el Servidor

Procesar los datos en el Servidor es muy rápido por varios motivos: por un lado, los datos no deben estar viajando por la red, solamente los resultados finales lo harán. Por ejemplo, si deseas calcular los impuestos a pagar este mes, y la tabla tiene 250.000 filas, el procesamiento de esas 250.000 filas se hará en la memoria de la computadora donde se encuentra el Servidor, no deberán estar viajando por la red para llegar a la computadora Cliente y ser procesadas allí, así que la ganancia en la velocidad de respuesta será muy notoria. Por otro lado, generalmente la computadora donde se encuentra el Servidor es más poderosa que todas (o la mayoría) de las computadoras que usan los Clientes y por lo tanto procesará los datos más rápidamente. Así que sumadas ambas ventajas, la ganancia en velocidad puede ser muy grande.

Optimización de los resultados

Los programas de administración gráfica (como el EMS SQL Manager) te pueden mostrar gráficamente el uso de los índices, y la cantidad de filas de cada tabla que fueron procesadas. Mirando esos gráficos puedes notar que se están procesando más filas de las necesarias o que no se están usando los índices correctos. Entonces, tomando eso en cuenta puedes corregir tu stored procedure y conseguir que realice sus tareas más rápidamente.

SP01

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

En la Captura 1. podemos ver la cantidad de filas que se procesaron en cada tabla. Si conocemos la cantidad de filas de cada tabla (lo cual se puede averiguar muy fácilmente con un SELECT COUNT(*) ) y lo que hace nuestro stored procedure entonces podemos notar que alguna tabla está procesando más filas de las necesarias, o que no usa un índice cuando sí debería usarlo.

Velocidad en la codificación

Cuando escribes un stored procedure allí mismo puedes verificar que esté funcionando correctamente, con un solo clic ya lo ejecutas. Y si no está funcionando correctamente, entonces lo corriges y lo vuelves a ejecutar hasta conseguir los resultados deseados. Hacer eso mismo en tu lenguaje de programación te hará demorar más tiempo porque tendrás que ejecutar tu programa, hacer unos cuantos clics aquí y allá y recién después de eso obtendrás los resultados.

Ventaja 2. Seguridad

En un stored procedure solamente puedes usar tablas y columnas que existen en la Base de Datos. Si escribes mal el nombre de una tabla o de una columna, no podrás compilar el stored procedure. De eso se deduce que los errores serán encontrados en tiempo de compilación y no en tiempo de ejecución. Encontrar errores en tiempo de ejecución puede ser muy malo si es un usuario quien los encuentra. Está muy apurado, necesita procesar algo, y recibe el mensaje: «Table unknown» o el mensaje: «Column unknown». De seguro que no le va a gustar. Algo así no puede pasar si se usó un stored procedure porque el Firebird no permite compilar un stored procedure que tenga esos errores.

Ventaja 3. Independencia

Como los stored procedures se guardan dentro de la Base de Datos están disponibles para ser usados por cualquier programa que se conecte a esa Base de Datos. Ese programa puede estar escrito en cualquier lenguaje de programación (Visual FoxPro, Visual Basic, Delphi, Java, C, C++, etc.).

Por lo tanto, si hoy usas un lenguaje de programación y dentro de unos días decides usar otro lenguaje de programación nada tendrás que cambiar dentro de la Base de Datos, todo estará allí, esperando ser usado.

Y en consecuencia no dependes de un lenguaje de programación, eres independiente, libre de usar cualquier lenguaje que desees.

Ventaja 4. Trabajo en equipo

Esta ventaja está muy relacionada con la anterior. Como los stored procedures son independientes de los lenguajes de programación entonces una persona puede programar en Visual FoxPro, otra persona puede programar en Visual Basic, otra persona puede programar en Delphi, etc. y todos podrán llamar a los mismos stored procedures.

Así, cada programador puede programar en el lenguaje de su preferencia, sin ningún problema.

Además, varias personas podrían estar escribiendo varios stored procedures inclusive al mismo tiempo. Si Juan conoce muy bien el tema de los impuestos entonces a él se le asigna esa tarea, y si María conoce muy bien como procesar los saldos entonces a ella se le asigna esa tarea.

Ventaja 5. Encapsulamiento

Después de compilar un stored procedure se puede dar derechos de ejecución sobre ese stored procedure a un usuario o a un rol o a un programa, quienes nunca verán el código fuente de dicho stored procedure, simplemente lo usarán.

Ventaja 6. Capas separadas

La programación en 3 capas es una metodología muy útil a seguir para construir aplicaciones de calidad porque cada capa se encarga exclusivamente de una tarea.

En la capa de datos se procesa todo lo que tenga que ver con tablas y columnas de una Base de Datos.

La idea es la siguiente: «todo lo que puede procesarse dentro de una Base de Datos debe procesarse dentro de esa Base de Datos».

La ventaja de la programación en 3 capas es que no se tiene código mezclado. Cada capa (capa de presentación, capa de negocios, capa de datos) siempre se encarga de una sola tarea. Es más fácil de entender que si está todo mezclado.

En el caso de la capa de datos, está se encargará de:

  • Insertar, actualizar, o borrar filas de las tablas
  • Procesar el contenido de las tablas
  • Devolver a la capa de negocios los resultados que ésta solicitó

Conclusión:

Aunque no es obligatorio usar stored procedures, es altamente recomendable utilizarlos porque las ventajas son muchas y muy grandes.

Los principiantes en Firebird o en bases de datos relacionales pueden ser un poco reacios a su utilización pero una vez que empiezan a usarlos se dan cuenta de lo muy provechoso que les resulta.

NOTA: ser principiante no es un defecto, todos hemos sido principiantes alguna vez, nadie nació siendo experto en Firebird, todo lo que sabemos lo hemos aprendido mucho después de nacer.

Artículos relacionados:

Entendiendo a los stored procedures

Escribiendo un stored procedure

Similitudes y diferencias entre stored procedures y triggers

¿Es conveniente usar stored procedures?

El índice del blog Firebird21

El foro del blog Firebird21

Backups locales y backups remotos

Deja un comentario

El programa GBAK nos permite realizar backups locales y backups remotos.

  • En un backup local, la Base de Datos que está en el Servidor copiamos a nuestro disco duro local
  • En un backup remoto, la Base de Datos que está en el Servidor copiamos en el Servidor

NOTA: En todos los ejemplos de abajo el comando se ve en 3 líneas para que sea más fácil visualizarlo, pero debe escribirse en 1 sola línea.

Caso 1. Backup local

Ejemplo 1. El backup lo realiza el usuario SYSDBA o el creador de la Base de Datos

GBAK -backup -user NombreUsuario -password Contraseña 
\\SERVIDOR-PC\C:\SISTEMAS\BASESDATOS\MiBaseDatos.FDB 
C:\SISTEMAS\BACKUPS\MiBackup.FBK

Ejemplo 2. El backup lo realiza un usuario que tiene el rol RDB$ADMIN

GBAK -backup -user NombreUsuario -password Contraseña -role RDB$ADMIN
\\SERVIDOR-PC\C:\SISTEMAS\BASESDATOS\MiBaseDatos.FDB 
C:\SISTEMAS\BACKUPS\MiBackup.FBK

Ejemplo 3. El backup se hace mediante conexión por TCP/IP

GBAK -backup -user NombreUsuario -password Contraseña 
192.168.1.1:C:\SISTEMAS\BASESDATOS\MiBaseDatos.FDB 
C:\SISTEMAS\BACKUPS\MiBackup.FBK

Si el usuario que quiere realizar el backup no es SYSDBA ni el creador de la Base de Datos entonces sí o sí debe tener el rol RDB$ADMIN y además deberá especificarlo para que el backup pueda realizarse con éxito.

La Base de Datos que se encuentra en la computadora cuyo nombre es SERVIDOR-PC o cuya dirección IP es 192.168.1.1 será copiada al disco duro local del usuario. Desde luego que estos son ejemplos, en tu caso tanto el nombre de la computadora o la dirección IP pueden ser distintos. El programa GBAK puede encontrarse en el disco duro local o en cualquier otra computadora. Si se encuentra en otra computadora debe estar en una carpeta compartida o no se lo podrá ejecutar.

Caso 2. Backup remoto

Ejemplo 4. Un backup remoto usando el nombre de la computadora

GBAK -backup -service \\SERVIDOR-PC\service_mgr -user NombreUsuario -password Contraseña 
C:\SISTEMAS\BASESDATOS\MiBaseDatos.FDB 
C:\SISTEMAS\BACKUPS\MiBackup.FBK

Ejemplo 5. Un backup remoto usando la dirección IP de la computadora

GBAK -backup -service 192.168.1.1:service_mgr -user NombreUsuario -password Contraseña 
C:\SISTEMAS\BASESDATOS\MiBaseDatos.FDB 
C:\SISTEMAS\BACKUPS\MiBackup.FBK

Para que el backup remoto pueda realizarse se debe llamar al administrador de servicios o service manager de una computadora que tenga instalado al Servidor del Firebird.

Cuando se usa el service manager el backup termina más rápido, eso significa que los backups remotos son más rápidos que los backups locales.

Comentarios:

  1. El programa GBAK debe poder acceder a la Base de Datos. Para ello se puede usar la ubicación de la Base de Datos  (como en los ejemplos anteriores) o un alias que se haya especificado en el archivo ALIASES.CONF (que es lo recomendable)
  2. Como el programa GBAK copiará todo el contenido de la Base de Datos entonces solamente podrá finalizar con éxito si es ejecutado por el usuario SYSDBA, por el creador de la Base de Datos, o por un usuario que se conecte con el rol RDB$ADMIN. Eso es muy lógico, si un usuario tiene acceso restringido a una Base de Datos no se le puede permitir copiar todo el contenido de ella.
  3. La conexión a la Base de Datos puede realizarse mediante named-pipes (o sea, especificando el nombre de la computadora, como en el Ejemplo 1.) o mediante su dirección IP (como en el Ejemplo 3.)
  4. Si se quiere realizar un backup remoto entonces hay que usar la opción -service. Esta opción puede recibir un solo parámetro, el cual se llama service_mgr. El service_mgr solamente existe en las computadoras que tienen al Servidor del Firebird instalado. Por ese motivo, si la computadora desde donde se realiza el backup no tiene instalado al Servidor del Firebird hay que llamarlo al service_mgr desde una computadora que sí lo tenga instalado. Se lo puede llamar usando el nombre de la computadora (como en el Ejemplo 4.) o la dirección IP de la computadora (como en el Ejemplo 5.). Desde luego que si la computadora desde donde se ejecuta al programa GBAK tiene instalado al Servidor del Firebird entonces no será necesario escribir esos prefijos.
  5. Cuando se hace un backup remoto, la carpeta en donde se copiará el backup debe estar compartida. El programa GBAK es un programa más, para el Sistema Operativo no tiene algo de especial, es uno más del montón. Por lo tanto, para que pueda copiar el backup en una carpeta debe tener derecho de escritura en esa carpeta. Si la carpeta está en otra computadora, entonces debe estar compartida, sí o sí.
  6. Cuando se quiere realizar un backup hay que diferenciar dos cosas: 1) El programa GBAK debe poder conectarse a la Base de Datos, como si se tratara de un usuario humano más. Es por eso que debe especificarse el usuario, la contraseña, y quizás el rol. 2) El programa GBAK debe poder crear un archivo en una carpeta de un disco duro. Es por eso que debe tener permiso de escritura en esa carpeta.
  7. Cuando se realiza un backup remoto, hay que ver a la carpeta destino desde el punto de vista del Servidor. En los ejemplos 4. y 5. la carpeta C:\SISTEMAS\BACKUPS\ es una carpeta que se encuentra en la misma computadora donde se encuentra el Servidor. No es una carpeta local, es una carpeta remota, y se la ve como local, pero es local para el Servidor.

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

Para conocer la versión del Firebird que estás usando

2 comentarios

¿Cuál es la versión del Firebird que estás usando?

A veces puede ser interesante poder responder a esa pregunta, inclusive dentro de un programa. Pues bien, la respuesta te la dará el siguiente SELECT:

Listado 1.

SELECT 
   RDB$GET_CONTEXT('SYSTEM', 'ENGINE_VERSION') 
FROM 
   RDB$DATABASE;

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

Copiando completamente o parcialmente una Base de Datos (2)

Deja un comentario

Ya habíamos visto la forma manual de realizar esas tareas en el artículo:

Copiando completamente o parcialmente una Base de Datos (1)

así que ahora es el momento de ver como realizarlas usando un programa de administración gráfica. Todos ellos tienen esas posibilidades, en este artículo usaremos el EMS SQL Manager.

Las opciones que tenemos son:

  1. Copiarla totalmente. Con todos sus metadatos y todos sus datos
  2. Copiar solamente los metadatos. Es decir, su estructura
  3. Copiar todos los metadatos y el contenido de algunas tablas
  4. Copiar algunos metadatos y el contenido de algunas tablas

Opción 1. Copiarla totalmente. Con todos sus metadatos y todos sus datos

BACKUP01

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

Para realizar un backup debemos elegir la opción Services y luego la opción Backup Database…

BACKUP02

Captura 2. Si haces clic en la imagen la verás más grande

BACKUP03

Captura 3. Si haces clic en la imagen la verás más grande

BACKUP04

Captura 4. Si haces clic en la imagen la verás más grande

Cuando el proceso finalice tendrás tu backup, en la carpeta y con el nombre que le indicaste en la Captura 2.

Opción 2. Copiar solamente los metadatos. Es decir, su estructura

Para conseguir esto, en la Captura 3. marcamos la entrada: Backup metadata only

Opción 3. Copiar todos los metadatos y el contenido de algunas tablas

Para este caso lo mejor es crear un archivo de script con el contenido completo de la Base de Datos y luego eliminar lo que no nos interesa, modificar lo que queremos cambiar, y dejar como está a lo demás.

BACKUP05

Captura 5. Si haces clic en la imagen la verás más grande

Aquí, primero hacemos clic con el botón derecho sobre nuestra Base de Datos, luego elegimos la opción Tasks y luego la opción Extract Database…

BACKUP06

Captura 6. Si haces clic en la imagen la verás más grande

BACKUP07

Captura 7. Si haces clic en la imagen la verás más grande

BACKUP08

Captura 8. Si haces clic en la imagen la verás más grande

La Captura 8. solamente la veremos si en la Captura 6. no habíamos marcado la opción Extract all metadata and data of de database. Si marcamos esa opción después de la Captura 7. pasaremos directamente a la Captura 9.

BACKUP09

Captura 9. Si haces clic en la imagen la verás más grande

BACKUP10

Captura 10. Si haces clic en la imagen la verás más grande

En la Captura 10. puedes elegir cuales objetos te interesa extraer. Puedes extraerlos a todos o solamente a algunos de ellos.

BACKUP11

Captura 11. Si haces clic en la imagen la verás más grande

En la Captura 11. tienes la posibilidad de extraer los datos de solamente algunas tablas (como es el caso de este ejemplo), extraer los datos de todas las tablas, o extraer los datos de las tablas seleccionadas en la Captura 10.

BACKUP12

Captura 12. Si haces clic en la imagen la verás más grande

BACKUP13

Captura 12. Si haces clic en la imagen la verás más grande

Y finalmente, para que empiece el proceso de generar el archivo de script hacemos clic sobre el botón Run

Ese archivo generado es un archivo de texto, puedes realizar cualquier cambio que quieras en él.

Opción 4. Copiar algunos metadatos y el contenido de algunas tablas

Es igual a la Opción 3.

Conclusión:

Como has podido ver también en este artículo, con Firebird tenemos la posibilidad de realizar backups completos o parciales de nuestra Base de Datos.

Enviar el backup a un archivo de script tiene la gran ventaja de que todo es legible y así podríamos revisar ese script y descubrir errores o mejoras que se podrían realizar.

Artículos relacionados:

Entendiendo a los scripts

Usando scripts para documentar la Base de Datos

Ejecutando un script desde Visual FoxPro

Copiando completamente o parcialmente una Base de Datos (1)

El índice del blog Firebird21

El foro del blog Firebird21

¿Por qué las bases de datos de Firebird son tan seguras?

9 comentarios

Como seguramente sabrás, las bases de datos de Firebird son muy confiables e inclusive un corte de la energía eléctrica no les afecta. Con un uso normal pueden ser usadas durante decenas de años sin el menor problema. Pero ¿por qué es así? ¿Por qué tenemos tanta seguridad?

Esto se debe a la metodología utilizada para escribir dentro de una Base de Datos.

Su nombre, en inglés es «careful writes» y significa: «escrituras cuidadosas».

Como funciona careful writes.

La idea es nunca tener inconsistencias. Y eso se logra de la siguiente manera:

  1. Cuando se quiere insertar un objeto, primero se inserta el objeto y luego el puntero a ese objeto
  2. Cuando se quiere eliminar un objeto, primero se elimina el puntero y luego el objeto

Ejemplo 1: Agregar una página de datos a una tabla

  1. El número de la página se obtiene de la lista de páginas no usadas y se marca esa página como usada
  2. La página es formateada para indicar que contendrá datos de esa tabla. Luego se la escribe en la Base de Datos
  3. El número de la página es escrito en la lista de páginas que pertenecen a esa tabla

Fíjate que cada uno de esos pasos ha escrito algo en la Base de Datos.

En el paso 1. la intención es evitar que ese número de página sea usado por dos (o más) objetos. Así que o ningún objeto está usando esa página o un solo objeto la está usando. No hay otra alternativa.

¿Qué ocurre si la Base de Datos se detiene entre los pasos 1. y 2. o entre los pasos 2. y 3.?

Supongamos que ocurrió un corte de la energía eléctrica. ¿Cómo quedará la Base de Datos?

  • La página estará marcada como «usada»
  • La página no estará asociada con una tabla, ni con un índice, ni con alguna otra cosa

La página en realidad no está siendo usada, aunque esté marcada como tal, por lo tanto está gastando un poco de espacio pero eso no causa el menor problema. Simplemente está allí ocupando espacio innecesariamente, hasta que un sweep la elimine o la Base de Datos sea restaurada desde un backup.

El espacio que ocupa una página es muy pequeño, lo determinas cuando creas la Base de Datos o cuando restauras un backup. Los valores posibles son: 4096 bytes, 8192 bytes, y 16384 bytes, los cuales para el gigantesco tamaño de los discos duros actuales son totalmente insignificantes.

Y como puedes ver, la Base de Datos mantuvo su consistencia.

Ejemplo 2. Recolectando la basura

Como recordarás, cada vez que se realiza un UPDATE o un DELETE el Firebird agrega una nueva versión de esa fila a la tabla. Cada una de esas versiones tiene un puntero a la versión siguiente, eso se hace así para que se pueda seguir la cadena y conocer el contenido actual de la fila. Entonces, para recolectar la basura que tiene una fila:

  1. Se elimina el puntero a la versión en la siguiente versión
  2. Se elimina la entrada en la página de datos donde se encuentra la fila actual
  3. Se eliminan las entradas de índices que ya no son válidas

¿Qué ocurre si la Base de Datos se detiene entre los pasos 1. y 2. o entre los pasos 2. y 3.?

Supongamos que ocurrió un corte de la energía eléctrica. ¿Cómo quedará la Base de Datos?

La basura continuará allí, por lo tanto ocupando espacio, pero eso no causará problemas, simplemente se estará gastando un poco de espacio innecesariamente. Ese espacio se recuperará cuando se realice un sweep o la Base de Datos sea restaurada desde un backup.

Y como puedes ver, la Base de Datos mantuvo su consistencia.

Conclusión:

Cada vez que el Firebird escribe algo en una Base de Datos lo hace a través de una metodología llamada «careful writes» o escrituras cuidadosas.

Mediante esta metodología hay una seguridad del 100% de que jamás una Base de Datos tendrá inconsistencias. Si ocurre un corte de la energía eléctrica o de la conexión con el Servidor, lo peor que podría ocurrir es que se esté gastando un poco más de espacio de lo que se debería, pero ese espacio gastado es pequeñísimo y además será eliminado cuando se realice un sweep o cuando se restaure la Base de Datos.

Artículos relacionados:

Entendiendo las páginas de la Base de Datos

Eligiendo el tamaño adecuado de las páginas de la Base de Datos

Entendiendo a las transacciones

El índice del blog Firebird21

El foro del blog Firebird21

Versión 4.8.1.0 de Firebird ADO.NET

1 comentario

Hay una nueva versión del ADO.NET provider for Firebird, se trata de la 4.8.1.0 y puede ser descargada desde:

https://www.nuget.org/packages/FirebirdSql.Data.FirebirdClient/

Artículos relacionados:

Conectándose con ADO a las bases de datos

Driver 4.1.5.0 para conectar a Firebird con ADO

El índice del blog Firebird21

El foro del blog Firebird21