style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

New SQL: Las bases de datos (pseudo) relacionales contraatacan

Parece que el movimiento NoSQL podria esta llegando a su fin, para ser sustuido por la nueva generacion de bases de datos (pseudo) relacionales: NewSQL, como VoltDB, que ademas de contar con propiedades de integridad transaccional (como ya es tradicion en las (P) RDBMs) cuenta ademas con la capacidad de escalar igual de bien que las NoSQL...

El principio del fin para las NoSQL? O daran un contra golpe? (Ojala que alguna de estas NewSQL adoptara un enfoque verdaderamente relacional... mmm... me pregunto que tan dificil sera construir un interprete de Rel encima de VoltDB....)

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

Interesante

Suena como MongoDB que hace web scale, pero prestando atención a la integridad referencial y transaccional.

En la liga de NewSQL mencionan muchas otras opciones similares. Me parece muy bien que esté apareciendo este software (ya sea en el mundo, si es que es nuevo, o en el radar bloggero, si es que ya tenía rato). Me gustaría echarle un ojo a alguna de estas opciones pero por falta de tiempo lo más factible será que espere a que alguien conocido adopte una de esas bases de datos y ver cómo le va.

What is worse...

Concuerdo con lo que dice @ezamudio, y a fin de cuentas, en una DB cómo Mongo necesitas usar (si o si) relaciones, porqué, ¿de qué sirve la información aislada en un sistema?...Casi toda la información en los sistemas se relaciona (ej. Un usuario tiene un blog, un blog tiene varias entradas, etc.), por lo que por más "No-relacional" que digan ser; las NoSQL terminan usando relaciones, me pasaron un proyecto con que usa Mongo y veía cosas cómo:

//Una consulta a un objeto ventas tenía
{ id: 111222333, subtotal: 1599.90, tax: 16, customer_id: 052687, date: 09/03/2011 }

//Y aún así tenían otra tabla de detalle_venta
{ id: 6520000, product_id: D5639OK03, sale_id: 111222333, price: 35.96, quantity: 1 }
//Y obviamente los demás resultados que arroja la consulta

A fin de cuentas digo, la gente sigue utilizando un enfoque relacional sólo que ahora en lugar de usar joins (en el caso de Mongo los joins son inexistentes) se usa una propia implementación (un tanto rudimentaria) tipo:

venta = db.sales.find({'id':111222333});
productosVenta = db.salesdetails.find({'sale_id': venta.id});

Pero, ¿porqué en NoSQL seguimos con el uso de ids y de relaciones?. Sencillo, porqué después ya los quiero ver pariendo cuates con los Tetha joins:

{
----id:111222333,
----user: {
--------name: "Chachito",
--------lastname: "Perez",
--------id: 333222111,
--------password: DFKNLI987650987,
--------sales: [
------------{
-----------------id: 111222333,
-----------------user:{
. //¿Y que es lo que vemos? Pues nada más que una redundante redundancia.
.
.
.
-----------------}
------------},
------------{
------------}
--------]                  
----},
}

Vemos este enfoque NewSQL...Esperemos además que sea todo lo que en realidad estabamos buscando.

Imagen de luxspes

Network vs Relational (What is worse? it depends)

Concuerdo con lo que dice @ezamudio, y a fin de cuentas, en una DB cómo Mongo necesitas usar (si o si) relaciones, porqué, ¿de qué sirve la información aislada en un sistema?

Aislada, como dices, la información no sirve de nada, por eso no me gustan bases de datos como Mongo, por que, al no poder definir Theta Joins, te es imposible efectuar consultas entre elementos para los que no hay relaciones definidas por adelantado (problema típico de las bases de datos network de la epoca CODASYL/COBOL, rescatadas de estado de coma por el movimiento NoSQL). En cambio, en una base de datos relacional (o al menos pseudo relacional) puedes escribir escribir un join entre cualquier par de campos, sin importar que se haya ocurrido (o no) definir una relación desde el principio. Así pues, en una base de dato relacional, tengo la confianza de que si la info esta ahi, podré combinarla del modo que se me antoje para obtener la respuesta, mientras que en una Network, habrá momentos en que me daré cuente en que, al no poder usar Theta Joins, mi única opción es volver a diseñar la base de datos (o resolver el problema proceduralmente).

Casi toda la información en los sistemas se relaciona (ej. Un usuario tiene un blog, un blog tiene varias entradas, etc.), por lo que por más "No-relacional" que digan ser; las NoSQL terminan usando relaciones,

Ah, pero es que las relaciones del enfoque relacional son muy diferentes a las del enfoque network. En una base de datos (pseudo) relacional, una Tabla es una relacion (Tabla == Relacion), en una base de datos Network (NoSQL), una relacion es un apuntador entre 2 Nodos (Relacion = Apuntador entre Nodos). La diferencia es muy profunda, y la gente suele confundirse, creyendo que las restricciones de integridad en una base de datos (pseudo) relacionales son relaciones, cuando en realidad no lo son, son reglas que controlan la integridad entre las relaciones (tablas). De esta forma, yo puedo hacer un join entre los campos de cualquier par de tablas (par de relaciones) y generar una nueva relación (vista) independientemente del las restricciones de integridad subyacentes, pero nunca puedo violar esas restricciones. En cambio en el enfoque Network, las relaciones son apuntadores entre los nodos, y generalmente no existen reglas de integridad generales, aunque la estructura de apuntadores fuerza a los datos a tomar una forma determinada, el problema, de nuevo, es que solo puedo navegar a través de esas relaciones predefinidas, y el día que me piden un reporte que no este representado en ese grafo de relaciones, ese día me doy cuenta que tengo que re-modelar mi base de datos (o resolver el problema proceduralmente).

A fin de cuentas digo, la gente sigue utilizando un enfoque relacional sólo que ahora en lugar de usar joins (en el caso de Mongo los joins son inexistentes) se usa una propia implementación (un tanto rudimentaria) tipo:

venta = db.sales.find({'id':111222333});
productosVenta = db.salesdetails.find({'sale_id': venta.id});

Lo que no parece tan malo, hasta que te piden que encuentres a todos los productos de todas las ventas de un día determinado (te reto a escribir esa consulta, con un proceso tan eficiente como si la base de datos (pseudo) relacional) (Nota: Tu código debe poder, buscar las ventas de la fecha, y una vez que encuentre una, en paralelo y obtener los productos de esa venta mientras en otro hilo sigue buscando la venta siguiente, y cuando la encuentre, disparar un hilo mas para empezar a acumular los productos de esa venta, mientras que continua buscando en el hilo previo mas ventas, como dificultad extra, debe ser capaz de determinar el numero de hilos optimo tomando en cuenta el numero de procesadores disponibles en la maquina)

Pero, ¿porqué en NoSQL seguimos con el uso de ids y de relaciones?. Sencillo, porqué después ya los quiero ver pariendo cuates con los Tetha joins:

Un theta join es un join en el que 2 campos (cualesquiera) son comparados utilizados para efectuar la operación de selección/restricción, en una base de datos (pseudo) relacional puedo utilizar cualquier par de campos que necesite. En una network (como Mongo) si no tengo a la relación definida desde antes, ya me amolé. (No veo la relación entre esto y tu ejemplo... podrías por favor explicarme?)

Imagen de luxspes

Ejemplo de Theta joins (Relacional es mejor)

Un ejemplo de Theta join, basándonos en el ejemplo que has estado manejando, seria: "encuentra a todos los productos de todas las ventas en donde el día de la venta sea el siguiente al día en que el cliente fue dado de alta en el sistema".

Normalmente, en una base de datos network, la persona que la modela pone relaciones (apuntadores entre nodos) para indicar que "la venta" esta relacionada con ciertos "productos" y cierto "cliente", y pone campos para indicar las fechas en las que ocurren las cosas, pero no pone una relación para poder obtener a través de ella los productos comprados el día después de la alta del cliente (una petición así no viene hasta que gerencia empieza a pedir reportes).

Y si queremos hacerlo mas emocionante:

Un ejemplo de Theta join, basándonos en el ejemplo que has estado manejando, seria: "encuentra a todos los productos de todas las ventas en donde el día de la venta sea durante la primera semana posterior al día en que el cliente fue dado de alta en el sistema y el precio del producto cubra al menos el 60% del monto total de alguna de las ventas".

Sin una base de datos relacional (o al menos pseudo relacional), sencillamente te dan ganas de suicidarte después de oír que te piden algo así, especialmente si después te dicen que el parámetro de porcentaje, y el rango de fechas relevantes debe llegar interactivamente.... ;-) . Tendrías que reestructurar tu modelo definiendo nuevas relaciones cada vez que el usuario piense en parámetros distintos! (y toma en cuenta estas consultas son cosas verdaderamente fáciles de expresar en Rel, e inclusive en SQL, sin tener que alterar el modelo)

(no olvides que ademas, el código de todos estos queries, al ser escrito en un lenguaje relacional (o al menos pseudo relacional, como SQL) se escribe de forma declarativa, por lo que el planeador de consulta puede comparar al query con el numero de procesadores en el equipo , y tomar la mejor decisión posible en cuando al grado de paralelismo a aplicar)

Imagen de luxspes

Ejemplo de Theta joins en Rel

Bueno, definamos el modelo, primeramente, tendriamos una Relvar para las ventas:

VAR sales BASE RELATION
{  

sale_id INTEGER,
subtotal RATIONAL,
tax RATIONAL,
customer_id INTEGER,
sale_date INTEGER

}

KEY { sale_id } ;

Y luego una de detalle de ventas:

VAR sales_detail BASE RELATION
{  

sale_detail_id INTEGER,
sale_id INTEGER,
product_id CHAR,
price RATIONAL,
quantity INTEGER

}

KEY { sale_id, sale_detail_id } ;

y una de clientes

VAR customers BASE RELATION
{  

customer_id INTEGER,
name CHAR,
register_date INTEGER

}

KEY { customer_id } ;

y no olvidemos la de productos:

VAR products BASE RELATION
{  

product_id CHAR,
manufacturer_name CHAR,
model_name CHAR

}

KEY { product_id } ;

Insertemos unos datos para hacerlo interesante:

INSERT sales RELATION {
        TUPLE {sale_id 111222333, subtotal 1599.5, tax 16.5, customer_id 52687, sale_date 20110903}
 };

INSERT sales_detail RELATION {
        TUPLE {sale_detail_id 6520000, sale_id 111222333 , product_id 'D5639OK03', price 35.5 , quantity 1}
 };

INSERT customers RELATION {
        TUPLE {customer_id 52687, name 'Joseph Smith' ,  register_date 20110902}
 };

INSERT products RELATION {
        TUPLE {product_id 'D5639OK03', manufacturer_name 'Acme' ,  model_name 'FooBar'}
 };

Ahora, como quedaría la consulta "a todos los productos de todas las ventas en donde el día de la venta sea el siguiente al día en que el cliente fue dado de alta en el sistema "?

Ahora, si quiero obtener los product_id, simplemente escribo:

sales_detail {product_id}

Ahora, como muestro solo los de una fecha determinada?

sales join sales_detail where sale_date = 20110903

Okey, pero me sobran columnas, como lo dejo solo con el product_id... asi de facil:

(sales join sales_detail where sale_date = 20110903) {product_id}

de ahi, si quisiera hacer un join con una la relvar (tabla) products, seria algo como:

products join ((sales join sales_detail where sale_date = 20110903) {product_id})

Ahora como muestro aquellos "donde el día de la venta sea el siguiente al día en que el cliente fue dado de alta en el sistema". Asi de facil:

products join ((customers join sales join sales_detail where sale_date = (register_date + 1) ){product_id})

Y ahora el "dificil": "encuentra a todos los productos de todas las ventas en donde el día de la venta sea durante la primera semana posterior al día en que el cliente fue dado de alta en el sistema y el precio del producto cubra al menos el 60% del monto total de alguna de las ventas"

Para filtrar la parte de la semana posterior:

products join ((customers join sales join sales_detail where  register_date  <  sale_date  and sale_date < (register_date + 8)   ){product_id})

Y para la parte del porcentaje "dificilisimo":

products join ((customers join sales join sales_detail where   (register_date ) <  sale_date  and sale_date < register_date + 8  and  price  >  ((subtotal + tax / 0.6) )  ){product_id})

Sospecho que hacer esto mismo en Mongo no nada es facil.... aunque ciertamente se debe facilitar un poco debido a que la relvar sales tiene los montos precalculados.... (pero ya es tarde, asi que dejare la comparativa sin montos precalculados para otro dia)

Imagen de luxspes

Mongo (en cierto sentido es) mas primitiva que COBOL?

Estoy sospechando que el ejemplo de wishmaster:

{
----id:111222333,
----user: {
--------name: "Chachito",
--------lastname: "Perez",
--------id: 333222111,
--------password: DFKNLI987650987,
--------sales: [
------------{
-----------------id: 111222333,
-----------------user:{
. //¿Y que es lo que vemos? Pues nada más que una redundante redundancia.
.
.
.
-----------------}
------------},
------------{
------------}
--------]                  
----},
}

Implica que en realidad en Mongo no hay apuntadores... si no que es meramente jerarquico (de ahí la redundante redundancia mencionada)....

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">