it-swarm-es.tech

Esquema de base de datos dinámica

¿Qué es una arquitectura recomendada para proporcionar almacenamiento para un esquema de base de datos lógico dinámico?

Para aclarar: cuando se requiere que un sistema proporcione almacenamiento para un modelo cuyo esquema puede ser extendido o alterado por sus usuarios una vez en producción, ¿cuáles son algunas de las buenas tecnologías, modelos de bases de datos o motores de almacenamiento que lo permitirán?

Algunas posibilidades para ilustrar:

  • Crear/alterar objetos de base de datos a través de DML generado dinámicamente
  • Crear tablas con un gran número de columnas físicas dispersas y usar solo las necesarias para el esquema lógico 'superpuesto'
  • Creación de una tabla 'larga y estrecha' que almacena valores de columna dinámicos como filas que luego deben ser pivotadas para crear un conjunto de filas 'corto y ancho' que contenga todos los valores para una entidad específica
  • Usando un sistema de tipo PropertyBag BigTable/SimpleDB

Cualquier respuesta basada en la experiencia del mundo real sería muy apreciada.

63
Fake Jim

Lo que estás proponiendo no es nuevo. Muchas personas lo han intentado ... la mayoría ha descubierto que persiguen una flexibilidad "infinita" y, en cambio, terminan con mucho, mucho menos que eso. Es el "motel de cucarachas" de los diseños de bases de datos: los datos entran, pero es casi imposible sacarlo. Intente y conceptualice escribiendo el código para CUALQUIER tipo de restricción y verá lo que quiero decir.

El resultado final generalmente es un sistema que es MUCHO más difícil de depurar, mantener y lleno de problemas de consistencia de datos. Esto no es siempre el caso, pero la mayoría de las veces, así es como termina. Sobre todo porque el programador (es) no ve venir este choque de trenes y no puede codificar defensivamente contra él. Además, a menudo termina el caso de que la flexibilidad "infinita" en realidad no es tan necesaria; es un "olor" muy malo cuando el equipo de desarrollo obtiene una especificación que dice "Caramba, no tengo ni idea de qué tipo de datos van a poner aquí, así que déjenlos poner CUANDO" y los usuarios finales están bien. al tener tipos de atributos predefinidos que pueden usar (codifique un número de teléfono genérico y permítales crear cualquier # de ellos; ¡esto es trivial en un sistema bien normalizado y mantiene la flexibilidad y la integridad!)

Si tiene un equipo de desarrollo muy bueno y conoce íntimamente los problemas que tendrá que superar con este diseño, puede codificar un pozo con éxito. Sistema diseñado, no terriblemente con errores. La mayor parte del tiempo.

Sin embargo, ¿por qué empezar con las probabilidades acumuladas en tu contra?

No me crees Google "One True Lookup Table" o "single table design". Algunos buenos resultados: http://asktom.Oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:10678084117056

http://thedailywtf.com/Comments/Tom_Kyte_on_The_Ultimate_Extensibility.aspx?pg=

http://www.dbazine.com/ofinterest/oi-articles/celko22

http://thedailywtf.com/Comments/The_Inner-Platform_Effect.aspx?pg=2

36
Matt Rogish

Un campo xml fuertemente tipado en MSSQL nos ha funcionado.

19
Bloodhound

Como han dicho otros, no hagas esto a menos que no tengas otra opción. Un caso en el que se requiere esto es si está vendiendo un producto comercial que debe permitir a los usuarios registrar datos personalizados. El producto de mi compañía cae en esta categoría.

Si necesita permitir que sus clientes hagan esto, aquí hay algunos consejos:
- Cree una herramienta administrativa robusta para realizar los cambios del esquema, y ​​no permita que estos cambios se realicen de otra manera.
- Conviértalo en una característica administrativa; No permita que los usuarios normales accedan a él.
- Registre cada detalle sobre cada cambio de esquema. Esto te ayudará a depurar problemas y también te dará datos de CYA si un cliente hace algo estúpido.

Si puede hacer esas cosas con éxito (especialmente la primera), entonces funcionará cualquiera de las arquitecturas que mencionó. Mi preferencia es cambiar dinámicamente los objetos de la base de datos, porque eso le permite aprovechar las funciones de consulta de su DBMS cuando accede a los datos almacenados en los campos personalizados. Las otras tres opciones requieren que cargue grandes porciones de datos y luego realice la mayor parte de su procesamiento de datos en código.

15
Josh Yeager

Tengo un requisito similar y decidí usar el esquema sin --- MongoDB .

MongoDB (de "humongous") es una base de datos de código abierto, escalable, de alto rendimiento, libre de esquemas y orientada a documentos escrita en lenguaje de programación C++. (Wikipedia)

Reflejos:

  • tiene una rica funcionalidad de consulta (tal vez la más cercana a las bases de datos SQL)
  • listo para producción (foursquare, sourceforge lo usa)

Lowdarks (cosas que debes entender, para que puedas usar mongo correctamente):

9
clyfe

Lo hice en un proyecto real:

La base de datos consistía en una tabla con un campo que tenía una matriz de 50. Tenía un índice de 'Palabra' establecido en ella. Todos los datos fueron tipográficos, por lo que el 'índice de Word' funcionó como se esperaba. Los campos numéricos se representaron como caracteres y la clasificación real se realizó en el lado del cliente. (Todavía es posible tener varios campos de matriz para cada tipo de datos si es necesario).

El esquema de datos lógicos para las tablas lógicas se mantuvo dentro de la misma base de datos con un 'tipo' de fila de tabla diferente (el primer elemento de la matriz). También es compatible con el control de versiones simple en el estilo de copia en escritura utilizando el mismo campo 'tipo'.

Ventajas:

  1. Puede reorganizar y agregar/eliminar sus columnas dinámicamente, sin necesidad de volcar/recargar la base de datos. Cualquier nuevo dato de columna se puede establecer en valor inicial (virtualmente) en tiempo cero.
  2. La fragmentación es mínima, ya que todos los registros y tablas tienen el mismo tamaño, a veces ofrece un mejor rendimiento.
  3. Todo el esquema de la tabla es virtual. Cualquier estructura de esquema lógico es posible (incluso recursiva u orientada a objetos).
  4. Es bueno para los datos de "escribir una vez, leer en su mayoría, no borrar/marcar como borrado" (la mayoría de las aplicaciones web son así).

Desventajas:

  1. Indización solo por palabras completas, sin abreviatura,
  2. Las consultas complejas son posibles, pero con una ligera degradación del rendimiento.
  3. Depende de si su sistema de base de datos preferido admite matrices e índices de Word (se implementó en PROGRESS RDBMS).
  4. El modelo relacional solo está en la mente del programador (es decir, solo en tiempo de ejecución).

Y ahora estoy pensando que el próximo paso podría ser implementar una base de datos de este tipo en el nivel del sistema de archivos. Eso podría ser relativamente fácil.

7
Thevs

El punto central de tener una base de datos relacional es mantener sus datos seguros y consistentes. En el momento en que permite que los usuarios modifiquen el esquema, irá a la integridad de sus datos ...

Si su necesidad es almacenar datos heterogéneos, por ejemplo, como un escenario de CMS, sugeriría almacenar XML validado por un XSD en una fila. Por supuesto, pierde el rendimiento y las capacidades de búsqueda fáciles, pero es una buena compensación en mi humilde opinión.

Ya que es 2016, olvídate de XML! Use JSON para almacenar la bolsa de datos no relacionales, con una columna escrita correctamente como backend. Normalmente no debería necesitar consultar por valor dentro de la bolsa, que será lento a pesar de que muchas bases de datos de SQL contemporáneas entienden JSON de forma nativa.

6
Sklivvz

Crear 2 bases de datos

  • DB1 contiene tablas estáticas y representa el estado "real" de los datos.
  • DB2 es libre de que los usuarios lo hagan como lo deseen, ellos (o usted) tendrán que escribir código para completar sus tablas con formas irregulares desde DB1.
3
AJ.

Me parece que lo que realmente quieres es una especie de "meta-esquema", un esquema de base de datos que puede describir un esquema flexible para almacenar los datos reales. Los cambios dinámicos del esquema son delicados y no es algo con lo que desees meterte, especialmente si los usuarios tienen permiso para realizar el cambio.

No va a encontrar una base de datos que sea más adecuada para esta tarea que cualquier otra, por lo que su mejor opción es seleccionar una basada en otros criterios. Por ejemplo, ¿qué plataforma está utilizando para alojar la base de datos? ¿En qué idioma está escrita la aplicación? etc

Para aclarar lo que quiero decir con "meta-esquema":

CREATE TABLE data (
    id INTEGER NOT NULL AUTO_INCREMENT,
    key VARCHAR(255),
    data TEXT,

    PRIMARY KEY (id)
);

Este es un ejemplo muy simple, es probable que tenga algo más específico para sus necesidades (y con algo más fácil de trabajar), pero sirve para ilustrar mi punto. Debe considerar que el esquema de la base de datos es inmutable en el nivel de la aplicación; cualquier cambio estructural debe reflejarse en los datos (es decir, la creación de instancias de ese esquema).

3
Daniel Spiewak

Sé que los modelos indicados en la pregunta se utilizan en todos los sistemas de producción. En una gran universidad/institución de enseñanza para la que trabajo se está utilizando una bastante grande. Utilizan específicamente el enfoque de tabla estrecha larga para mapear los datos recopilados por muchos sistemas variados de adquisición de datos.

Además, Google lanzó recientemente su protocolo interno de intercambio de datos, buffer de protocolo, como código abierto a través de su sitio de código. Un sistema de base de datos modelado en este enfoque sería bastante interesante.

Compruebe lo siguiente:

Modelo entidad-valor-atributo

Google Protocol Buffer

3
siculars

El enfoque de EAV creo que es el mejor, pero tiene un alto costo

2
kamal

Wikipedia tiene una excelente visión general del espacio problema:

http://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model

2
DenNukem

Sé que es un tema antiguo, pero supongo que nunca pierde actualidad. Estoy desarrollando algo así ahora mismo. Aquí está mi enfoque. Utilizo una configuración de servidor con MySQL, Apache, PHP y Zend Framework 2 como marco de aplicación, pero debería funcionar también con cualquier otra configuración.

Aquí hay una guía de implementación simple, usted puede evolucionar más allá de esto.

Necesitaría implementar su propio intérprete de lenguaje de consulta, porque el SQL efectivo sería demasiado complicado.

Ejemplo:

select id, password from user where email_address = "[email protected]"

El diseño físico de la base de datos:

Tabla 'especificaciones': (debe ser almacenada en caché en su capa de acceso a datos)

  • yo dint
  • parent_id: int
  • nombre: varchar (255)

Tabla 'elementos':

  • yo dint
  • parent_id: int
  • spec_id: int
  • datos: varchar (20000)

Contenido de la tabla 'especificaciones':

  • 1, 0, 'usuario'
  • 2, 1, 'email_address'
  • 3, 1, 'contraseña'

Contenido de la tabla 'elementos':

La traducción del ejemplo en nuestro propio lenguaje de consulta:

select id, password from user where email_address = "[email protected]"

a SQL estándar se vería así:

select 
    parent_id, -- user id
    data -- password
from 
    items 
where 
    spec_id = 3 -- make sure this is a 'password' item
    and 
    parent_id in 
    ( -- get the 'user' item to which this 'password' item belongs
        select 
            id 
        from 
            items 
        where 
            spec_id = 1 -- make sure this is a 'user' item
            and 
            id in 
            ( -- fetch all item id's with the desired 'email_address' child item
                select 
                    parent_id -- id of the parent item of the 'email_address' item
                from 
                    items 
                where 
                    spec_id = 2 -- make sure this is a 'email_address' item
                    and
                    data = "[email protected]" -- with the desired data value
            )
    )

Necesitará tener la tabla de especificaciones en caché en una matriz asociativa o tabla hash o algo similar para obtener el spec_id de los nombres de especificaciones. De lo contrario, necesitaría insertar un poco más de sobrecarga de SQL para obtener el spec_id de los nombres, como en este fragmento:

Mal ejemplo, no use esto, evite esto, ¡caché la tabla de especificaciones en su lugar!

select 
    parent_id, 
    data 
from 
    items 
where 
    spec_id = (select id from specs where name = "password") 
    and 
    parent_id in (
        select 
            id 
        from 
            items 
        where 
            spec_id = (select id from specs where name = "user") 
            and 
            id in (
                select 
                    parent_id 
                from 
                    items 
                where 
                    spec_id = (select id from specs where name = "email_address") 
                    and 
                    data = "[email protected]"
            )
    )

Espero que tengas la idea y puedas determinar por ti mismo si ese enfoque es factible para ti.

¡Disfrutar! :-)

2
Oliver Konig

En el pasado he elegido la opción C - Creando una tabla 'larga y estrecha' que almacena valores de columna dinámicos como filas que luego deben ser pivotadas para crear un conjunto de filas 'corto y ancho' que contiene todos los valores para una entidad específica.. Sin embargo, estaba usando un ORM, y eso REALMENTE hizo que las cosas fueran dolorosas. No puedo pensar en cómo lo harías en, digamos, LinqToSql. Supongo que tendría que crear un Hashtable para hacer referencia a los campos.

@Skliwz: Supongo que está más interesado en permitir que los usuarios creen campos definidos por el usuario.

0
Danimal

En la wiki de c2.com, se exploró la idea de "relacional dinámico". NO necesita un DBA: las columnas y las tablas son Create-On-Write, a menos que comience a agregar restricciones para que se parezca más a un RDBMS tradicional: a medida que un proyecto madura, puede "cerrarlo" de manera incremental.

Conceptualmente, puede pensar en cada fila como una declaración XML. Por ejemplo, un registro de empleado podría representarse como:

<employee lastname="Li" firstname="Joe" salary="120000" id="318"/>

Esto no implica que se debe implementar como XML, es solo una conceptualización útil. Si solicita una columna no existente, como "SELECT madeUpColumn ...", se trata en blanco o nulo (a menos que las restricciones agregadas lo prohíban). Y es posible usar SQL, aunque uno tiene que tener cuidado con las comparaciones debido al modelo de tipo implícito. Pero aparte de la manipulación de tipos, los usuarios de un sistema Relacional Dinámico se sentirían como en casa porque pueden aprovechar la mayor parte de su conocimiento RDBMS existente. Ahora, si alguien simplemente lo construyera ...

0
FloverOwe

ElasticSearch. Debería considerarlo especialmente si está tratando con conjuntos de datos que puede particionar por fecha, puede usar JSON para sus datos y no se fija en el uso de SQL para recuperar los datos.

ES infiere su esquema para cualquier nuevo campo JSON que envíe, ya sea de forma automática, con sugerencias, o manualmente, que puede definir/cambiar mediante un comando HTTP ("asignaciones"). Aunque no es compatible con SQL, tiene algunas capacidades de búsqueda excelentes e incluso agregaciones.

0
Oren