Cómo manejar el diseño de tablas con columnas variables


17

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!


Hola, ¿cómo manejaste tu problema? Me estoy ejecutando en el mismo tipo de escenario y estoy a punto de crear una tabla relacional por información adicional, y renderizarla con vistas como una "tabla única".
Benj

Respuestas:


15

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.


Escuché que también puedes usar tablas dinámicas o algo así
Alexander Mills el

2

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.


0

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.

House Table:
ID, Addr, City, State, Zip, custom_string1,cs_2,cs_3,custom_integer_1,ci_2,ci_3 ...

create view house_2014 as 
select ID, Addr, City, State, Zip,
custom_string1 as last_name,cs_2 as first_name ...

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.

create table house_2014_archive as select * from house_2014;
drop house_2014;
create view house_2015 as "select column list for new year";

0

¿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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.