Necesito admitir campos y valores dinámicos en un gran datawarehouse para almacenar el registro de solicitudes de API, mi caso de usuario es que necesito almacenar todas las cadenas de consulta de solicitudes de API y poder realizar consultas en el futuro (por lo que no es solo almacenamiento, así que no puedo usar blob para ellos)
p.ej http://example.com/?action=test&foo=abc&bar=def...
Necesito almacenar todas las field => value
asignaciones, es decir (action => test), (foo => abc), (bar => def)
, y dado que el campo es tan dinámico, la única solución que he encontrado es usar Entity-Attribute-Value, sin embargo, la gente sigue diciendo que es un diseño muy malo.
Entonces, considere mi caso de uso anterior, ¿cuál sería una alternativa adecuada al EAV?
Mi esquema actual usando KAV
Tabla
requests
(id, timestamp, uri)
por ejemplo(1, 149382220, '/')
Tabla
params
(request_id, key, value)
por ejemplo(1, 'action', 'test'), (1, 'foo', 'abc'), (1, 'bar', 'def')
¿Alguna sugerencia?
Actualización: ejecutamos el almacén en AWS RedShift
SQL
No es lo suficientemente específico. Te han preguntado dos veces. Soy el tercerohstore
ojson
los tipos de datos (ojsonb
si / cuando "actualizar" a 9.4).Respuestas:
Puedo pensar en tres soluciones: EAV, XML y columnas dispersas. Este último es específico del proveedor y puede no serle útil.
Cualquiera que sea el método que elija, puede considerar almacenar los datos de la solicitud original en un formato sin formato, en una tabla o archivo sin formato. Le facilitará probar nuevas formas de almacenar los datos, le permitirá volver a cargar los datos si descubre un error con la forma en que analiza sus solicitudes, y ofrecerá oportunidades para analizar las solicitudes API utilizando el procesamiento por lotes o "big data" herramientas si encuentra que su almacén de datos no puede manejar eficientemente los datos.
Consideraciones de EAV
EAV / KVS, como lo describió anteriormente, es probable que sea la implementación más sencilla.
Desafortunadamente, también será muy costoso: para obtener cualquier tipo de consultas eficientes sobre las claves de uso común, necesitará tener índices en la columna de claves, que podrían fragmentarse mucho. Consultar claves particulares sería extremadamente costoso.
Es posible que pueda reducir el costo de la indexación o los escaneos de índices al admitir su tienda EAV con vistas materializadas (muchos proveedores lo respaldan) para consultar claves o valores que le interesan.
XML
La mayoría de los sistemas de bases de datos empresariales ofrecen un manejo XML muy maduro, que incluye validación, indexación y consultas sofisticadas.
Cargar la solicitud API en la base de datos como XML proporcionaría una tupla por solicitud, lo que lógicamente podría ser un poco más aceptable para usted que tener un número desconocido de filas en una tabla EAV.
Si esto es eficiente dependería mucho de su proveedor RDBMS y su implementación.
¡El mayor inconveniente es que esta es probablemente la única forma de administrar datos que es más complicada que la manipulación de cadenas de la solicitud original!
Columnas dispersas / mesas tradicionales
Es posible que pueda cargar sus datos en una estructura de tabla tradicional, con una columna por clave.
La función Columnas dispersas de SQL Server es una gran alternativa a una tienda EAV. Una tabla con columnas dispersas se comporta de manera muy similar a una tabla normal, excepto que puede tener hasta 30,000 columnas, y los valores NULL en columnas dispersas no consumen espacio en la tabla.
Combinarlos con índices filtrados (otra característica específica de SQL Server) puede proporcionar una alternativa extremadamente eficiente a un almacén EAV si consulta con frecuencia un par de columnas y / o valores específicos.
El uso de una tabla tradicional con otros proveedores puede ser viable: IBM admite más de 700 columnas por tabla y Oracle alrededor de 1000, y características como la compresión o el tratamiento de Oracle de los valores nulos finales pueden significar que puede almacenar sus datos API de manera bastante eficiente.
La desventaja obvia de este enfoque es que a medida que agrega nuevas claves a su API, necesitará ajustar su esquema en consecuencia.
fuente
hstore
ojson
. En los próximos 9.4jsonb
sería mi recomendación.EAV no es un mal diseño, per se, es simplemente un diseño que requiere una buena cantidad de previsión y puede ser forjado con problemas de rendimiento a medida que aumenta la cantidad de datos. Puede ser que para su sistema funcione bien.
Cuando diseñé un sistema para almacenar cadenas de consulta, no tenía idea de antemano en qué campos estaría interesado. Creé una tabla para almacenar la cadena de consulta en formato binario serializado y construí un sistema que me permitió dividir la consulta. encadenar en sus piezas componentes una vez que supiera las piezas que me interesaban. A partir de ahí, creé un conjunto de tablas; uno para los conjuntos de datos comúnmente contenidos dentro de la cadena de consulta.
Por ejemplo, eventualmente tuve una tabla para datos de referencia, una para datos de solicitud de destino y otra para elementos relacionados con el usuario, como la consulta de búsqueda que ingresaron.
Encontré la capacidad de almacenar toda la cadena de consulta en una sola tabla como un blob, mientras que la capacidad de dividir ese blob en el futuro satisfizo muy bien mis necesidades.
fuente
BLOB
se usa el término que significa Objeto binario largo. Preferiría usar unCLOB
(Objeto largo de caracteres) o algo parecidotext
en PostgreSQL, ya que estamos hablando de caracteres y no de datos binarios.