Saltar al contenido

Integrar el almacenamiento de documentos BLOB con SQL Server

Las plataformas NoSQL pueden soportar bases de datos altamente escalables con archivos adjuntos BLOB (imágenes, documentos y otros archivos), pero si cree que necesita adoptar una solución NoSQL en lugar de SQL Server sólo porque tiene un alto volumen de BLOBs en su base de datos, piénselo de nuevo.

Si tiene buenas razones para optar por el NoSQL, y puede aceptar los compromisos de una eventual consistencia transaccional, puede encajar bien en la factura. Pero las aplicaciones críticas de línea de negocio no siempre pueden permitirse las relajadas restricciones de las bases de datos NoSQL, y normalmente requieren esquemas fuertemente tipificados, con total integridad transaccional; es decir, un sistema de base de datos relacional completo (RDBMS). Sin embargo, las plataformas de bases de datos relacionales como el SQL Server fueron originalmente diseñadas y optimizadas para trabajar principalmente con datos estructurados, no con BLOBs. Y así, históricamente, nunca ha sido factible almacenar grandes cantidades de datos BLOB directamente en la base de datos. Es decir, hasta FILESTREAM.

Integrar el almacenamiento de documentos BLOB con SQL Server
Integrar el almacenamiento de documentos BLOB con SQL Server

Con FILESTREAM, Microsoft aborda el dilema de almacenar BLOBs dentro de la base de datos relacional. Mi nuevo curso, Transmisión de archivos nativos de SQL Server 2012-2014, explica esta innovadora característica en detalle. En este post, cubriremos cómo FILESTREAM (y sus tecnologías relacionadas) pueden ser utilizadas para implementar una solución de almacenamiento de BLOBs altamente escalable que esté completamente integrada con una base de datos relacional de SQL Server. También encontrarán demostraciones en vivo de todo lo que cubre este post en el curso.

Presentamos FILESTREAM

Aunque originalmente el servidor SQL nunca fue pensado para manejar BLOBs a gran escala, este ya no es el caso con FILESTREAM (introducido en el SQL Server 2008). Antes de FILESTREAM, el Servidor SQL se vio obligado a empujar los BLOBs en los grupos de archivos de la base de datos estándar, que están realmente optimizados para almacenar datos de filas estructuradas en páginas de 8k. Debido a que los BLOBs no encajan naturalmente dentro de esta estructura, deben ser empujados a un almacenamiento fuera de la fila, lo que hincha los grupos de archivos estructurados, y en última instancia mata el rendimiento.

FILESTREAM cambia todo eso. Primero, para ser claros, FILESTREAM no es en realidad un tipo de datos. Más bien es un atributo que se aplica al tipo de datos varbinario(max), el mismo tipo de datos que se usaría para almacenar BLOBs directamente dentro de la fila. Pero al simplemente agregar el atributo FILESTREAM al tipo de datos varbinario(max), SQL Server toma un enfoque radicalmente diferente para el almacenamiento físico de BLOBs.

En lugar de inundar los grupos de archivos de la base de datos estándar con BLOBs, el Servidor SQL almacena el contenido de los BLOBs como archivos en el sistema de archivos al que pertenecen. Al mismo tiempo, establece y mantiene puntos de referencia entre las filas de los grupos de archivos estándar y los archivos del sistema de archivos que están vinculados a las columnas varbinarias (máx.) de esas filas. Toda esta magia se produce entre bastidores, y es totalmente transparente para cualquier código existente que trabaje con columnas varbinarias(max) ordinarias.

De esta manera, los datos de la BLOB se almacenan físicamente por separado de los datos de las filas estructuradas, pero son una parte integral de la base de datos. Así que por ejemplo, hacer una copia de seguridad de la base de datos incluye los datos BLOB, con la opción de realizar una copia de seguridad parcial que excluye el grupo de archivos FILESTREAM cuando se desea crear copias de seguridad más pequeñas que no incluyen los datos BLOB.

Además, esta solución proporciona una total coherencia transaccional, porque FILESTREAM se integra con el sistema de archivos NTFS, y NTFS es un sistema de archivos transaccionales. Así pues, cuando se inicia una transacción en la base de datos y se inserta una fila, y esa fila incluye datos BLOB almacenados en una columna varbinaria(max) FILESTREAM, entonces SQL Server inicia automáticamente una transacción del sistema de archivos NTFS sobre esos datos. Luego, el destino de la transacción del sistema de archivos depende del de la transacción de la base de datos. Si la transacción de la base de datos se confirma y cuando lo haga, SQL Server también confirmará la transacción del sistema de archivos NTFS; del mismo modo, al retroceder la transacción de la base de datos se retrocede automáticamente la transacción NTFS.

Acceder a los BLOBs con T-SQL

Con FILESTREAM, puedes tratar a los BLOBs como columnas varbinarias ordinarias (máx.) en T-SQL. Por ejemplo, puedes usar la función OPENROWSET con el proveedor BULK para importar un archivo externo en una columna varbinaria(max). Y si esa columna está decorada con el atributo FILESTREAM, SQL Server almacenará automáticamente una copia de ella como BLOB en el sistema de archivos NTFS entre bastidores, en lugar de encajarla a la fuerza en los grupos de archivos de la base de datos estándar.

Por ejemplo:

INSERTA EN EL ÁLBUM DE FOTOS (FotoId, FotoDescripción, Foto)

VALORES(3, $0027Montañas$0027,

(SELECCIONE LA COLUMNA DE AMPLIACIÓN DE LA OPENROWSET(BULK $0027C:DemoAscent.jpg$0027, SINGLE_BLOB) AS x))

Para recuperar BLOBs, es un simple SELECCIONAR:

SELECCIONE * DEL Álbum de fotos

Usando SqlFileStream y el Streaming API

Aunque FILESTREAM ofrece almacenamiento escalable aprovechando el sistema de archivos NTFS entre bastidores, el acceso a BLOB también necesita escalar. Es genial que pueda disfrutar de una transparencia total con sólo usar el acceso T-SQL, pero deténgase un momento y considere lo que necesita hacer SQL Server al recuperar BLOBs con T-SQL. Para poder servir la columna de fotos en el conjunto de resultados que se muestra arriba para la instrucción SELECT, por ejemplo, el Servidor SQL necesitaba leer todo el contenido de cada BLOB del sistema de archivos NTFS que está administrando internamente, y esto puede fácil y repentinamente poner una gran presión de memoria en el servidor.

Para abordar esta preocupación, FILESTREAM expone el API de streaming. Cuando se utiliza esta API, el Servidor SQL sigue administrando el sistema de archivos entre bastidores, sólo que cambia la carga y los requisitos de memoria de la lectura y escritura de BLOBs en el sistema de archivos de sí mismo y en la aplicación cliente. Esto mantiene los requerimientos de memoria en el Servidor SQL muy magros, sin importar cuán grandes sean sus BLOBs.

La clase SqlFileStream es un envoltorio de código administrado alrededor de la API de streaming, lo que lo hace extremadamente fácil de usar desde .NET. En C# o VB .NET, se inicia una transacción de base de datos y se emite una declaración INSERT, pero en realidad no se incluye el contenido BLOB con la declaración INSERT. En su lugar, el Servidor SQL te devuelve la información que necesitas para crear un objeto SqlFileStream.

Este objeto hereda de la clase base System.IO.Stream, lo que significa que soporta todos los métodos estándar de lectura/escritura de las clases estándar de streams .NET, incluyendo streams de memoria, streams de petición/respuesta HTTP y streams de archivos locales. Por lo tanto, es fácil entonces transmitir sus BLOBs dentro y fuera, usando los buffers de memoria asignados a su aplicación, no al Servidor SQL. Luego, sólo tienes que confirmar la transacción de la base de datos, y el Servidor SQL confirma automáticamente la transacción del sistema de archivos NTFS al mismo tiempo.

En mi curso, les muestro SqlFileStream de cerca, y les demuestro cómo programar contra la API de streaming desde una aplicación cliente gruesa, una aplicación cliente/servidor (Web), y en un escenario de n niveles (WCF).

Presentamos FileTable

La historia de FILESTREAM sólo mejora con FileTable, añadido en SQL Server 2012. Aunque FILESTREAM revoluciona el almacenamiento BLOB en SQL Server, sólo es accesible para desarrolladores y administradores. ¿Qué pasa con los usuarios comunes? Ciertamente no van a escribir T-SQL o código API de streaming para acceder a los BLOBs. Y tampoco hay manera de que las aplicaciones cliente ordinarias accedan a los datos de FILESTREAM.

La solución es FileTable, que combina FILESTREAM con el tipo de datos jerárquicos para proporcionar un sistema de archivos «emulado» (un sistema de archivos con el que pueden trabajar los usuarios y las aplicaciones, pero que en realidad es un FileTable en una base de datos de SQL Server). Un FileTable es sólo una tabla normal, excepto que tiene un esquema fijo; específicamente, tiene columnas predeterminadas para los metadatos del sistema de archivos emulado:

Cada fila de una Tabla de Archivos representa un archivo o una carpeta (dependiendo de la columna is_directory), y el valor de la jerarquía en la columna path_locator es lo que implementa la estructura de carpetas del sistema de archivos emulado. El tipo de datos de la jerarquía tiene métodos que se pueden utilizar para consultar y manipular la estructura; por ejemplo, se pueden mover programáticamente subárboles enteros de un padre a otro.

Para las filas que representan archivos, la columna file_stream contiene el BLOB real, y esta es una columna varbinaria(max) FILESTREAM. Así que entre bastidores, se almacena en el sistema de archivos NTFS como lo sería una columna varbinaria(max) FILESTREAM de una tabla ordinaria (una no-FileTable).

Y así, además de poder utilizar T-SQL o la API de streaming con un FileTable, el sistema de archivos emulados que representa un FileTable también se expone a los usuarios y las aplicaciones cliente a través de un intercambio de archivos de Windows. Como resultado, los cambios realizados en la tabla de la base de datos se reflejan en el sistema de archivos emulados y, a la inversa, los cambios realizados en el sistema de archivos emulados por los usuarios o las aplicaciones cliente se reflejan automáticamente en la base de datos, que en última instancia empuja hacia abajo en el sistema de archivos NTFS físico que se utiliza para el almacenamiento de BLOB entre bastidores.

Resumen

Con FILESTREAM, las aplicaciones de línea de negocio pueden adoptar la integración escalable BLOB sin verse forzadas a considerar una alternativa NoSQL a SQL Server. Si está interesado en echar un vistazo más profundo a cómo funciona todo, asegúrese de revisar mi curso de Transmisión de Archivos Nativos de SQL Server 2012-2014.