Intenté diseñar una base de datos para un concepto de proyecto y me encontré con lo que parece ser un tema muy debatido. He leído algunos artículos y algunas respuestas de Stack Overflow que dicen que nunca (o casi nunca) está bien almacenar una lista de ID o similares en un campo: todos los datos deben ser relacionales, etc.
Sin embargo, el problema con el que me encuentro es que estoy tratando de hacer un asignador de tareas. Las personas crearán tareas, las asignarán a varias personas y se guardarán en la base de datos.
Por supuesto, si guardo estas tareas individualmente en "Persona", tendré que tener docenas de columnas "TaskID" ficticias y micro-administrarlas porque puede haber de 0 a 100 tareas asignadas a una persona, por ejemplo.
Por otra parte, si guardo las tareas en una tabla de "Tareas", tendré que tener docenas de columnas falsas de "PersonID" y micro-administrarlas, el mismo problema que antes.
Para un problema como este, ¿está bien guardar una lista de ID que toman una forma u otra o simplemente no estoy pensando en otra forma de lograrlo sin romper los principios?
fuente
VARCHAR ARRAY
) para almacenar una lista de etiquetas. Probablemente no sea así como terminarán almacenándose más adelante en la línea, pero las listas pueden ser extremadamente útiles durante las etapas de creación de prototipos, cuando no tiene nada más que señalar y no desea construir todo el esquema de la base de datos antes de poder hacer cualquier otra cosaRespuestas:
La palabra clave y el concepto clave que necesita investigar es la normalización de la base de datos .
Lo que haría, en lugar de agregar información sobre las asignaciones a las tablas de persona o tareas, es agregar una nueva tabla con esa información de asignación, con relaciones relevantes.
Ejemplo, tiene las siguientes tablas:
Personas:
Tareas:
Luego crearía una tercera tabla con Asignaciones. Esta tabla modelaría la relación entre las personas y las tareas:
Entonces tendríamos una restricción de clave externa, de modo que la base de datos imponga que PersonId y TaskIds tengan que ser ID válidos para esos elementos externos. Para la primera fila, podemos ver
PersonId is 1
, por lo que Alfred , se le asigna aTaskId 3
, vacas de ordeño .Lo que debería poder ver aquí es que podría tener la menor cantidad de tareas por tarea o por persona que desee. En este ejemplo, a Ezequiel no se le asigna ninguna tarea, y a Alfred se le asigna 2. Si tiene una tarea con 100 personas, al realizarla
SELECT PersonId from Assignments WHERE TaskId=<whatever>;
obtendrá 100 filas, con una variedad de personas asignadas diferentes. PuedeWHERE
en el PersonId encontrar todas las tareas asignadas a esa persona.Si desea devolver consultas reemplazando los ID con los nombres y las tareas, puede aprender a UNIR tablas.
fuente
Estás haciendo dos preguntas aquí.
Primero, pregunta si está bien almacenar listas serializadas en una columna. Si esta bien. Si su proyecto lo requiere. Un ejemplo podría ser los ingredientes del producto para una página de catálogo, donde no desea tratar de rastrear cada ingrediente individualmente.
Lamentablemente, su segunda pregunta describe un escenario en el que debe optar por un enfoque más relacional. Necesitarás 3 mesas. Uno para las personas, uno para las tareas y otro que mantiene la lista de qué tarea se asigna a qué personas. El último sería vertical, una fila por combinación de persona / tarea, con columnas para su clave principal, ID de tarea e ID de persona.
fuente
Lo que estás describiendo se conoce como una relación de "muchos a muchos", en tu caso entre
Person
yTask
. Por lo general, se implementa usando una tercera tabla, a veces llamada tabla de "enlace" o "referencia cruzada". Por ejemplo:fuente
task_id
primero, si está haciendo consultas filtradas por tarea.El único momento en que puede almacenar más de un elemento de datos en un solo campo es cuando ese campo solo se usa como una entidad única y nunca se considera que está compuesto por esos elementos más pequeños. Un ejemplo podría ser una imagen, almacenada en un campo BLOB. Está compuesto por muchos y muchos elementos más pequeños (bytes), pero estos no significan nada para la base de datos y solo se pueden usar todos juntos (y se ven bonitos para un Usuario final).
Dado que una "lista" está, por definición, compuesta de elementos más pequeños (elementos), este no es el caso aquí y debe normalizar los datos.
No. Tendrá algunas filas en una tabla de intersección (también conocida como entidad débil) entre persona y tarea. Las bases de datos son realmente buenas para trabajar con muchas filas; en realidad son bastante basura trabajando con muchas columnas [repetidas].
Buen ejemplo claro dado por whatsisname.
fuente
Puede ser legítimo en ciertos campos calculados previamente.
Si algunas de sus consultas son costosas y decide ir con los campos precalculados que se actualizan automáticamente mediante los activadores de la base de datos, entonces puede ser legítimo mantener las listas dentro de una columna.
Por ejemplo, en la interfaz de usuario, desea mostrar esta lista utilizando la vista de cuadrícula, donde cada fila puede abrir detalles completos (con listas completas) después de hacer doble clic:
Mantiene la segunda columna actualizada por disparador cuando el cliente visita un nuevo artículo o una tarea programada.
Puede hacer que dicho campo esté disponible incluso para búsquedas (como texto normal).
Para tales casos, mantener listas es legítimo. Solo necesita considerar el caso de que posiblemente exceda la longitud máxima del campo.
Además, si está utilizando Microsoft Access, los campos multivalor ofrecidos son otro caso de uso especial. Manejan tus listas en un campo automáticamente.
Pero siempre puede recurrir a la forma normalizada estándar que se muestra en otras respuestas.
Resumen: Las formas normales de base de datos son modelos teóricos necesarios para comprender aspectos importantes del modelado de datos. Pero, por supuesto, la normalización no tiene en cuenta el rendimiento u otro costo de recuperar los datos. Está fuera del alcance de ese modelo teórico. Pero la implementación práctica a menudo requiere el almacenamiento de listas u otros duplicados precalculados (y controlados).
A la luz de lo anterior, en una implementación práctica, ¿preferiríamos que la consulta se base en una forma normal perfecta y se ejecute 20 segundos o una consulta equivalente que se base en valores precalculados que requieren 0.08 s? A nadie le gusta que su producto de software sea acusado de lentitud.
fuente
Dadas dos tablas; los llamaremos Persona y Tarea, cada uno con su propia ID (PersonID, TaskID) ... la idea básica es crear una tercera tabla para unirlos. Llamaremos a esta tabla PersonToTask. Como mínimo, debe tener su propia identificación, así como las otras dos. Entonces, cuando se trata de asignar a alguien a una tarea; ya no necesitará ACTUALIZAR la tabla Persona, solo tiene que INSERTAR una nueva línea en la Tabla PersonToTask. Y el mantenimiento se vuelve más fácil: la necesidad de eliminar una tarea simplemente se convierte en DELETE según el TaskID, ya no se actualiza la tabla Person y su análisis asociado
¿Qué tal un informe simple o quién está asignado a una tarea?
Por supuesto, podrías hacer mucho más; se podría hacer un Informe de tiempo si agrega campos de fecha y hora para TaskAssigned y TaskCompleted. Todo depende de usted
fuente
Puede funcionar si dice que tiene claves primarias legibles por humanos y desea una lista de números de tarea sin tener que lidiar con la naturaleza vertical de una estructura de tabla. es decir, mucho más fácil de leer la primera tabla.
La pregunta sería: si la lista de tareas debe almacenarse o generarse a pedido, lo que dependería en gran medida de requisitos tales como: con qué frecuencia se necesita la lista, cuán precisa es la cantidad de filas de datos, cómo se utilizarán los datos, etc. .. después de lo cual se debe analizar las compensaciones a la experiencia del usuario y cumplir con los requisitos.
Por ejemplo, comparar el tiempo que llevaría recuperar las 2 filas frente a ejecutar una consulta que generaría las 2 filas. Si lleva mucho tiempo y el usuario no necesita la lista más actualizada (* esperando menos de 1 cambio por día), entonces podría almacenarse.
O si el usuario necesita un registro histórico de las tareas que se le asignaron, también tendría sentido si la lista estuviera almacenada. Así que realmente depende de lo que estés haciendo, nunca digas nunca.
fuente
Estás tomando lo que debería ser otra mesa, girándola 90 grados y calzándola en otra mesa.
Es como tener una tabla de pedidos donde tiene itemProdcode1, itemQuantity1, itemPrice1 ... itemProdcode37, itemQuantity37, itemPrice37. Además de ser incómodo de manejar mediante programación, puede garantizar que mañana alguien querrá ordenar 38 cosas.
Solo lo haría a su manera si la 'lista' no es realmente una lista, es decir, dónde se encuentra en su conjunto y cada línea de pedido individual no se refiere a alguna entidad clara e independiente. En ese caso, solo tiene que incluir todo en algún tipo de datos lo suficientemente grande.
Por lo tanto, un pedido es una lista, una lista de materiales es una lista (o una lista de listas, lo que sería aún más una pesadilla para implementar "de lado"). Pero una nota / comentario y un poema no lo son.
fuente
Si "no está bien", entonces es bastante malo que cada sitio de Wordpress tenga una lista en wp_usermeta con wp_capabilities en una fila, lista de despedidos_wp_pointers en una fila, y otras ...
De hecho, en casos como este, podría ser mejor para la velocidad, ya que casi siempre querrá la lista . Pero Wordpress no es conocido por ser el ejemplo perfecto de las mejores prácticas.
fuente