Tengo un escenario de diseño de tabla y, como tipo que no es DBA, me gustaría tener opiniones sobre cuál es más escalable.
Digamos que se le pide que registre información sobre casas para un área metropolitana, comenzando con un vecindario pequeño (200 casas) pero eventualmente creciendo a más de 5000000 casas.
Se requiere que almacene la información de base: ID # (Un # de lote único que podemos usar como índice único), Addr, Ciudad, Estado, Código postal. Bien, simple mesa lo manejará.
Pero cada año, se le pedirá que registre información adicional sobre todas las casas, y QUÉ información cambiará cada año. Entonces, por ejemplo, el primer año, se le pide que registre el apellido y los pies cuadrados de los propietarios. El segundo año, se le pide que mantenga el apellido, pero que elimine los pies cuadrados y, en su lugar, comience a recopilar los nombres de los propietarios.
Por último, cada año cambiará el número de columnas adicionales. Podría comenzar con 2 columnas adicionales, luego pasar a 6 el próximo año y luego volver a 2.
Entonces, un enfoque de tabla es tratar de agregar la información personalizada como columnas en las tablas de la casa para que solo haya una tabla.
Pero tengo una situación en la que alguien dispuso las tablas para esto como:
Columnas "Tabla de la casa": ID, Dirección, Ciudad, Estado, Código postal, con una fila por casa
ID Addr City State Zip
-------------------------------------------
1 10 Maple Street Boston MA 11203
2 144 South Street Chelmsford MA 11304
3 1 Main Avenue Lowell MA 11280
Columnas "Tabla de información personalizada": ID, Nombre, Valor, con una tabla similar a:
ID Name Value
1 Last Name Smith
2 Last Name Harrison
3 Last Name Markey
1 Square Footage 1200
2 Square Footage 1930
3 Square Footage
Por lo tanto, hay varias filas para cada registro de casa individual. Cada año, cuando la información opcional requiere cambios, esta tabla se reconstruye literalmente, por lo que el próximo año podría verse así:
1 Last Name Smith
2 Last Name Harrison
3 Last Name Markey
1 First Name John
2 First Name Harry
3 First Name Jim
Eventualmente acumulas 100,000 filas de casas Y un año hay 10 datos adicionales; la segunda tabla ahora tiene 1,000,000 de filas de información, muchas de las cuales tienen información redundante (descripción). Los requisitos generales de la base de datos son que las personas necesitarán obtener la información de la fila de la casa + los valores de campo personalizados asociados miles de veces por día.
Entonces mi pregunta: ¿sería una práctica mala (u horrible) en su lugar:
A) Diseñe la tabla de la casa con el número máximo de columnas personalizadas (llamado quizás "1" a "10") e inserte esos valores personalizados directamente en las filas de la casa
O
B) Almacene la información personalizada en la tabla de la casa, pero cada año, cuando los requisitos cambien, reconstruya la tabla de la casa con solo el número de columnas necesarias para la información personalizada, con la idea de que los requisitos podrían volverse locos y nunca se sabe cuántos máximos campos opcionales pueden ser solicitados?
Gracias, espero que esto tenga sentido!
fuente
Respuestas:
Tienes casi 4 opciones:
NoSQL - definición Cada registro se almacena como un conjunto de pares clave / valor. Es muy flexible y rápido. No todos los redactores de informes por ahí admiten este estilo de almacenamiento. Hay muchas implementaciones de bases de datos de ejemplo de NoSQL. El que parece ser más popular en este momento, es MongoDB.
EAV - definición Aquí es donde gira la tabla completa o una parte (en otra tabla) de lado. Esta es una buena opción si ya tiene una base de datos relacional interna de la que no puede alejarse fácilmente. El ejemplo de tabla de información personalizada que dio es un buen ejemplo de una tabla EAV.
Tablas estándar con columnas XML : piense en esto como NoSQL cumple con las tablas relacionales. Los datos almacenados en una columna XML pueden tener cualquier formato compatible con XML, incluidos múltiples datos secundarios correlacionados. Para las columnas que sabe que serán columnas "normales", se pueden construir como el tipo de columna apropiado para almacenar los datos (Apellido, Dirección, Ciudad, Estado, etc.).
Tablas estándar con muchas columnas adicionales : tiene una base de datos relacional, no puede usar XML o EAV, y NoSQL no es una opción. Agregue muchas columnas adicionales de cada tipo. Supongo que 30 o más varchar, 30 o más enteros, 15 o más números. Y una vez que use una columna para un valor, no la reutilice . Y tampoco elimines la columna .
De todas estas soluciones, mi propia opinión es que encontrará que el enfoque NoSQL o EAV es el más exitoso con la menor cantidad de refactorización de su código y su esquema.
Tendrá una situación en la que recopilará datos un año, no el siguiente, y luego los recopilará nuevamente después. Intentar actualizar los datos más antiguos con la información correcta es problemático y costoso. El almacenamiento no es ninguno.
fuente
Para responder a su pregunta sobre esas 2 opciones, ninguna me parece correcta. A) te encerrará y B) es mucho trabajo. El esquema actual que describe no es tan malo (excepto por tener el nombre de la información ("nombre", "pie cuadrado", etc.) como una cadena en lugar de una ID referenciada a una tabla de búsqueda.
Sin embargo, esto me parece un buen candidato para una base de datos NoSQL ( http://en.wikipedia.org/wiki/NoSQL ). Si bien nunca trabajé con dicha base de datos, lo que usted describe es un escenario típico que esto resuelve.
fuente
Si el número concurrente de columnas personalizadas es finito y se conocen los límites (por ejemplo, no más de 10-20 columnas personalizadas para cadenas, no más de x columnas para enteros, etc.)
Puede usar la tabla base con campos adicionales por tipo de datos y en su lugar de reconstruir la tabla cada año, cree una vista para ese año que incluya solo las columnas personalizadas relevantes y cambie el nombre de los campos genéricos para reflejar el contenido de ese año.
El problema con este enfoque es que no tiene historial, pero podría hacer una copia fácilmente cada año antes de cambiar los requisitos de la columna.
fuente
¿Puede enumerar todos los escenarios para los que desea almacenar estos datos?
Si hay un número finito de combinaciones de columnas que se pueden aplicar a la tabla, intente modelar una "tabla base" con columnas comunes que se apliquen a todos los escenarios, luego cree más tablas (para implementar algún tipo de herencia; esto se conoce como subtipo / supertipo en ERD y diseño de bases de datos).
una tabla para cada escenario, de esta manera al menos mantendrá las tablas limpias y podrá evitar tener la dirección de la calle almacenada en la columna "apellido" ...
Eche un vistazo a esta pregunta de diseño: /programming/554522/something-like-inheritance-in-database-design
fuente