Introducción
Existen ocasiones en las que almacenar y organizar nuestros datos en una estructura tabular puede no ser lo ideal, en las que por conveniencia queramos guardar un conjunto de datos fuertemente relacionados en un sencillo xml pero a la vez necesitemos muchas de las características propias de SQL.
Si bien SQL Server nos permite guardar XML (con o sin esquema asociado) e indexarlo, estos índices son muchas veces demasiado grandes y algo lentos y, aunque funcionan obviamente muy bien, podríamos crear nuestro propio sistema de índices más livianos (y también indexar los xml no en tiempo real).
La idea
La idea es crear una delgadísima capa de acceso a datos que nos permita guardar documentos XMLs en la bases de datos utilizando procedimientos almacenados. Estos son básicamente 2: InsertDocument y UpdateDocumet. El objetivo es no solo insertar y actualizar los documentos sino también insertar y actualizar los índices que se hayan creado para los mismo.
Ejemplo
Imaginemos que deseamos guardar datos personales de personas, sus nombres, apellidos, datos de contacto, familiares y otros datos. Para ello usamos documentos XMLs como el que sigue:
Lo primero es crear y registrar la tabla en donde se guardarán los documentos XMLs, para esto utilizamos un procedimiento almacenado: CreateForm y que recibe el nombre de la tabla a crear:
Esto último crea una tabla y la registra dentro de la tabla Forms.
También queremos poder buscar dentro de estos documentos por Nombre, Edad y por el nombre del padre de las personas y por ello crearemos 3 indices mediante el procedimiento almacenado CreateIndex.
Esto último crea 3 tablas, una por cada índice y las registra en la tabla de índices (Indexes). Para la creación del nombre de estas tablas se una como convención NombreTabla_XpathNodo_Idx.
Y ahora si, una vez creados y registrados tanto la tabla como los índices, podemos comenzar a insertar y actualizar documentos. Por ejemplo, para insertar el documento que veíamos al inicio solo debemos invocar al procedimiento
Insertemos otro más:
Veamos cómo quedan los índices luego de insertado este registro:
Ahora podemos buscar los en las tablas de índices y obtener el/los id del/de los documento/s que contiene/n el valor buscado. ¿Pero que sucede si quisiera buscar por más de un valor/columna? Bueno, con estas tablas podemos crear una vista que las uniera mediante un join por DocumentId. Para eso utilizamos el procedimiento almacenado CreateSearchView como sigue:
Lo que crea la vista Personas_SearchView la cual puede utilizarse para búsquedas.
Ahora bien, puesto que el indexado es algo caro, podríamos configurar un Job para que indexe los registros por las noches o lo haga por lotes pequeños de registros o de alguna otra forma que nos permita mover el costo de procesamiento a otro lado o a otro momento. Para ello existe el procedimiento almacenado UpdateIndex el cual recibe como parámetro el nombre del indice a actualizar.
Conclusión
Bien, esta es solo una idea que puede utilizarse en algunos escenarios en los que debamos (o queramos) utilizar SQL mientras que a la vez almacenamos nuestros datos como XMLs sin esquemas las cual puede brindarnos algunas de las características propias de las bases de datos NoSql.
El código está acá.