2011-01-07 18 views
8

Mis conocimientos de bases de datos son mediocres en el mejor y tengo que diseñar un modelo de datos para los datos de la encuesta. He pasado algunas reflexiones sobre esto y ahora siento que estoy atrapado entre una especie de EAV model y un diseño que involucra a cientos de mesas, cada una con cientos de columnas (y los miles de registros). Debe haber una mejor manera de hacerlo y espero que los sabios de este foro puedan ayudarme.Modelo de datos de encuesta: ¿cómo evitar el EAV y la desnormalización excesiva?

Mi pregunta es: ¿cómo debo modelar las respuestas a las preguntas de la encuesta en un RDBMS? El uso de SQL Server es obligatorio. Por lo tanto, los sistemas de almacenamiento de datos alternativos deben excluirse de esta discusión. (Claro, algunos deberían y serán evaluados, pero no aquí, por favor.) No necesito una solución para todo el modelo de datos, por ahora solo me interesa la parte de Respuestas.

ya he buscado diversos foros, pero realmente no pude encontrar una solución. Si ya se ha proporcionado en otro lugar, discúlpeme y proporcióneme un enlace para que pueda leerlo.

algunas suposiciones acerca de los datos que tienen que tratar con:

  1. Cada encuesta consta de 1 a n cuestionarios
  2. Cada cuestionario se compone de 100-2.000 preguntas (por favor, ignora que 2.000 preguntas realmente suenan como una mucho para responder ...)
  3. Las preguntas pueden ser de varios tipos: opción múltiple, texto libre, un número (como edad, ingresos, porcentajes, ...)
  4. Cada encuesta involucra a 10-200 países (no son los encuestados. Los encuestados son en realidad personas en los países.)
  5. Dependiendo del tipo de cuestionario, cada cuestionario es contestado por 100-20.000 encuestados por país.
  6. Un país puede adaptar los cuestionarios para una encuesta, es decir, agregar, eliminar o editar preguntas
  7. Los datos de un país se recopilan en una base de datos independiente en ese país. No hay posibilidad de integración en línea desde el principio.
  8. Los datos para todos los países tiene que integrarse más tarde. Esto significa, por ejemplo, si un país ha eliminado una pregunta, esos datos deben derivarse de alguna manera de lo que enviaron para lograr un diseño uniforme en todos los países
  9. Tendré que escribir el software de integración y limpieza, que necesitará para trabajar con los datos de cada país
    1. Al final, los datos deben exportarse a archivos planos, una cuadrícula rectangular por país y cuestionario.

ya he discutido este tema con personas de diversos orígenes y no han llegado a una buena solución todavía. Obtuve principalmente dos tipos de opiniones.

  1. Los expertos de dominio, que están acostumbrados a trabajar con archivos planos (hoja de cálculo de estilo) para el procesamiento de datos y votar el análisis de una estructura sin normalizar con un montón de tablas y columnas como he descrito anteriormente (1 mesa por país y el cuestionario) Esto me suena terrible, porque aprendí que se deben evitar tablas anchas, será molesto determinar qué columnas están realmente en una mesa cuando se trabaja con ella, la base de datos se llenará con cientos de tablas (o incluso necesito configurar múltiples bases de datos, cada una con un diseño similar pero un poco diferente), etc.
  2. O-O-programadores votan por un diseño fuertemente "normalizado", lo que llevaría efectivamente a una mesa central que contiene todas las respuestas de todos los encuestados a todas las preguntas. Esta tabla necesitaría contener una columna de tipo tipo sql_variant o columnas de respuestas múltiples con diferentes tipos para almacenar respuestas de diferentes tipos (opción múltiple, texto libre, ...). El primero sería esencialmente un modelo EAV. Tiendo a seguir a Joe Celko aquí, quien desaconseja fuertemente su uso (lo llama OTLT o "One True Lookup Table"). Esto último implicaría que cada fila contendría celdas nulas para los tipos no aplicables por diseño.

Otra alternativa que podría pensar sería crear una tabla por tipo de respuesta, es decir, una para preguntas de opción múltiple, una para preguntas de texto libre, etc. Eso no es tan genérico, conduciría a una mucha unión se une, creo, y tendría que agregar una tabla si se inventa un nuevo tipo de respuesta.

¡Perdón por aburrirte con todo este texto y gracias por tu aporte!

Saludos, Alex

PS: Me hicieron la misma pregunta aquí: http://www.eggheadcafe.com/community/aspnet/13/10242616/survey-data-model--how-to-avoid-eav-and-excessive-denormalization.aspx

+1

Para mí, esto suena como un buen candidato para una solución [EAV] (http://en.wikipedia.org/wiki/Entity-attribute-value_model). ¿Cuál es su objeción a ir por esa ruta? –

+0

¿Qué hay de usar un documento o base de datos NoSQL? Quizás el problema aquí es adaptar su modelo de dominio a una infraestructura relacional, entonces ¿por qué no simplemente evitarlo ...? Ver http://en.wikipedia.org/wiki/NoSQL. – rsenna

+0

El modelo EAV parece hacer las restricciones de integridad mucho más engorrosas. Básicamente, tendría que exprimir valores de diferentes tipos de datos en una columna. Ver http://www.eggheadcafe.com/software/aspnet/32645959/generic-datatype-table.aspx – AlexDPC

Respuesta

1

Esto suena como que está luchando con un problema común: cómo usar un martillo para fijar un tornillo.

Ambas alternativas enumeradas son malas, cada una por diferentes motivos. Pero eso se debe a que está intentando rellenar su modelo de datos particular en un sistema de base de datos relacional. Un buen enfoque sería mirar más allá de la base de datos relacional al some other database/storage systems, probar un par y encontrar la mejor opción para su proyecto.


He probado el modelo de EAV y se rindió porque era demasiado complejo, y tengo miedo de probar el modelo de múltiples tablas con un sistema de base de datos relacional. La solución más fácil que he encontrado con una base de datos relacional es: almacenar cada respuesta completa como un solo CLOB, serializado en JSON o YAML (o algo más ligero), en una tabla responses.

create table responses (
    id uuid primary key, 
    questionnaire_id uuid references questionnaires.id, 
    data text 
) 
+0

¿Por qué estás tan seguro de eso? Los sistemas relacionales son lo que nosotros y mis compañeros de trabajo aquí comprendemos mejor y para lo que tenemos la infraestructura. Además, se han desarrollado y se están utilizando diseños relacionales similares. Vea, por ejemplo, los 4 diseños de "Cuestionarios" en http://www.databaseanswers.org/data_models/. Por favor no me malinterpretes Siempre estoy ansioso por aprender y usar nuevas tecnologías, pero, especialmente en este caso, tiene que dar sus frutos. Incluso necesito convencer a mucha gente de que tiene sentido alejarse de un sistema caótico de archivos planos en un sistema de directorio ... – AlexDPC

+0

Así que tiene un martillo, está trabajando con un tornillo, ¿y usted recomienda alicates? – Mark

+0

Mi recomendación es: existe una amplia gama de tiendas de datos. No es solo SQL. No mire en el cajón del martillo para encontrar la solución a su problema. Ve a la ferretería Ace y encuentra el destornillador que se ajusta a tu tornillo. – yfeldblum

-1

¿Ha considerado no reinventar la rueda? Ya hay aplicaciones de encuesta de fuente abierta ya compiladas. Incluso si no satisfacen sus necesidades, descargue algunos y revise sus modelos de datos.

+0

Eché un vistazo más de cerca a http://www.limesurvey.org/. Aparentemente crean tablas planas para cada encuesta. Dada la cantidad de tablas que tendría que crear y mantener, me gustaría evitar eso. Como escribí anteriormente, los modelos de EAV también están disponibles. No es que no tenga ninguna idea sobre el diseño en absoluto. Tengo problemas para tomar una decisión y solicito amablemente alguna información aquí. – AlexDPC

1

Si yo estaba usando SQL Server, expreso va a estar bien, entonces yo podría hacer esto:

  • tabla con la lista de preguntas, banderas para el tipo (bits), si la bandera requerida (bits), la respuesta correcta si existe, etc.
  • tabla con la lista de países
  • de enlace Tabla de países y preguntas (algunos países no pueden obtener algunas preguntas
  • Tabla de respuestas ingenio h columnas para la pregunta (s) y una columna xml de las preguntas opcionales incluidos los que se añaden

Si no está versado en la trituración de XML a continuación, utilizar columnas dispersas por todas las preguntas opcionales. No recuerdo exactamente el límite en el número de columnas dispersas en una tabla, pero creo que está por encima de 30,000.SQL Server almacena internamente columnas dispersas como XML y la fragmentará cuando se seleccione la columna y sí se puede indexar

El siguiente diagrama muestra un diagrama creado con SQL Server. la columna AL_A4 contendrá la respuesta a QL_Id = 4 y es de tipo dispersa. El QL_Id en la tabla de lista de preguntas no está marcado, lo que le permite saber para hacer que la columna en AnswerList sea dispersa.

Dado que los países agregarán preguntas, cree QuestionListCustom, QuestiontoCountryCustom y AnswerListCustom tablas y agregue la información de las preguntas personalizadas.

Estoy seguro de que hay otras maneras de diseñar el almacenamiento, esta es la forma en que entregaría la tarea, si esto no es tarea, seguramente trabajas para la ONU.

alt text

+0

Esto ignora por completo el hecho de que las preguntas se agrupan en encuestas –

+0

@Stephanie tiene la razón. Dejé completamente la parte de la encuesta. Nueva tabla ha sido agregada –

+0

Gracias por su sugerencia. No estoy seguro si entiendo la idea detrás de AnswerList. ¿Entiendo bien que contendrá una columna por pregunta (obligatoria)? Si es así, dudo que esto funcione bien cuando se ingresen varias encuestas. Entiendo que los nombres de las columnas son genéricos, por lo que la pregunta 1 para la encuesta A puede ser completamente diferente de la pregunta 1 en la encuesta B. Pero tienen que ser del mismo tipo de datos, lo que podría ser o no ser el caso.¿O lo entiendo completamente mal? – AlexDPC

4

alt text Bueno imgur es hacia abajo de manera que voy a publicar la foto más tarde.

Creo que esto es completamente factible dentro de un modelo relacional. Construí un CDM para mostrar cómo haría esto.

salida

Toma 4 entidades para definir Encuesta de un país. Algunas Encuesta para padres, el país y una lista de preguntas. Sus preguntas tienen una relación interna, por lo que cuando un país "edita" una pregunta, puede hacer un seguimiento tanto de la pregunta formulada por el país como de la pregunta de la que proviene. La otra cosa que necesitas es una entidad/tabla de Respuesta Posible. Cada pregunta puede tener una lista asociada de posibles respuestas (opciones múltiples o rangos, etc.). Esos 4 deben definir completamente el lado "OUTBOUND" de esto.

entrante

El lado "ENTRADA" se encuentra a sólo 2 nuevas entidades, el demandado y la respuesta. El encuestado es sencillo, solo los datos demográficos de esa persona si los conoce y aquí puede incluir una relación con el país. Cada encuestado respondió la encuesta en un país determinado. (La persona puede ser 1: n con el Demandado si la persona viaja o tiene doble ciudadanía)

La respuesta es básica; o bien es una de las opciones enumeradas en la lista de Respuestas posibles o se proporciona. No se deje atrapar por el hecho de que la respuesta puede ser un número, fecha, etc. todavía. O es un FK o una cadena de caracteres.

informes

Un informe es una unión sobre todos ellos ... Usted elige un país y una encuesta, obtiene la lista de preguntas y respuestas.

respuesta Complejidad

depende de dónde se quiere hacer sus cálculos. Si utilizó una columna Varchar2 (4000) para las respuestas proporcionadas por el usuario, puede agregar un atributo a la pregunta para describir el tipo de datos de la respuesta. P: ¿Edad? DT: Entero entre (0 y 130). Entonces su capa de integración puede hacer la validación en lugar de la base de datos que la impone. O puede tener 4 columnas, una para el número, fecha, carácter y CLOB. Y su capa de integración determinará la columna a usar. Cuando informe esas respuestas, simplemente seleccionará las cuatro columnas con Coalesce().

¿Es esta una EAV porque hay una ligera ambigüedad para el tipo de datos de la "respuesta"

No, no lo es.

Un modelo de EAV descompone una entidad en una lista de atributos. así:

Entity  Attribute  Value 
    1   Fname   Stephanie 
    1   Lname   Page 
    1   Age   30 

porque se ve la columna de respuesta del esquema de vigilancia se lleva a cabo ambas palabras y números como la columna Valor hace aquí usted piensa que define EAV. No es asi. Al igual que si agregué 3 columnas de tipo de datos a este modelo, no lo cambiaría DESDE un EAV.

I taaaan odio cuando

que he tenido la gente me dice que la consulta Estoy sintonía tiene que ir "tan rápido como sea posible". Ok, entonces dame mil millones de dólares y 30 años. "Espera, ¿mil millones?" "Tanto como", "tan rápido como" no son requisitos. Puede validar todo lo que desee en una base de datos ... crear una carga de disparadores previos, ¡listo! Validación en abundancia.

¿Cuál es el tipo de datos de una columna de edad? O columna de fecha de nacimiento? Depende de lo que sea su fuente de datos. Algunos registros anteriores solo pueden tener Mes y Año, o solo año, o 'alrededor' o 'circa' algún año. No podría tener solo una columna numérica y hacer 'tanta validación como sea posible'. y NUMBER (2) puede ser una validación MEJOR que simplemente NUMBER. Entonces ahora tendrá NÚMERO (1), NÚMERO (2), NÚMERO ... para tener "tanto como".

Donde yo creo que están consiguiendo un tropiezo

pensar en esto como un modelo de datos conceptual, no física. En esos términos, Encuesta es una entidad. Es Pregunta una entidad o solo un atributo de Encuesta. Si construyó Una tabla PER, está diciendo claramente que la Pregunta es solo un Atributo de la Encuesta y que al almacenarla verticalmente se convierte en un EAV. Lo que muestra este modelo es que Question es en realidad otra entidad. Hay una relación entre las Preguntas, p. 'un país [puede] editar preguntas'. Estaba la pregunta original y editada. Cada pregunta tiene una colección de posibles respuestas. Y lo más importante es que, son todas las preguntas. En un EAV, llamo fname, lname, bdate, age, major, salario, etc ... cosas muy dispares, solo atributos. En este caso, no incluimos el nombre de la agencia que originó la encuesta y la fecha en que se emitió, y la fecha se debe devolver, etc., como preguntas.

Déjenme decirlo de otra manera. Eres Fedex. Desea almacenar marcas de tiempo para ciertos eventos. Cada vez que un paquete entra o sale de una instalación o vehículo. Tiempo en el camión recolector, tiempo fuera del camión y en la primera instalación, tiempo fuera de esa instalación y en un avión, etc. ¿Los almacenas horizontalmente? ¿Cómo sabes la cantidad de saltos por adelantado? Si los almacena verticalmente, ¿eso lo convierte automáticamente en un EAV? Y si es así, ¿por qué?

Eres una empresa meteorológica que obtiene temperaturas de estaciones en todo el país. Digamos que los sensores están diseñados para enviar una lectura cuando la temperatura cambia +/- un grado completo. Si almacena un sensor_ID | timestamp | temp es una tabla de lectura es un EAV? Cada lectura no es un atributo del sensor, son en sí mismas entidades que pertenecen a una colección/serie.

Una cosa que el almacenamiento vertical de respuestas tiene en común con un EAV es su dificultad para realizar consultas analíticas.Si quisiera una lista de todas las personas que respondieron VERDADERO a las preguntas 5 y 10, pero FALSO a 6 y 11 sería muy difícil cuando se hace verticalmente. Quizás es por eso que ves esto un EAV. Si quieres hacer eso, necesitas un almacenamiento diferente. El almacenamiento relacional de las preguntas y respuestas no es la mejor base de datos de informes. Volvamos al ejemplo de Fedex. No es simple hacer un informe de tiempo de "tránsito" cuando las filas son verticales.

+0

Gracias por su sugerencia. Este es otro ejemplo de un modelo EAV. No quiero almacenar las respuestas como cadenas, debido a todo el tipo de conversión que implicaría. También preferiría tener tanta validación como sea posible en la base de datos. Así que tener una columna por tipo de datos me suena mejor. También he pensado en tener una tabla por tipo de datos para reducir la cantidad de nulos. Ahora mi objetivo principal aquí es comprender los beneficios de cualquier solución. Entonces, ¿por qué preferiría su solución sobre un enfoque con múltiples tablas anchas (vea mi pregunta inicial, punto 1 en la parte inferior)? – AlexDPC

Cuestiones relacionadas