46 votos

El diseño de un esquema de base de datos para una aplicación de calendario

Quiero escribir una aplicación de calendario. Es realmente recurrentes que lanzar una llave inglesa en las obras para el esquema DB. Me gustaría alguna opinión sobre cómo organizar esto.

¿Qué pasa si un usuario crea un evento y las entradas que se repite todos los lunes, para siempre? Cómo puedo almacenar todos los que en la base de datos? Yo no puedo crear una infinidad de eventos. Puedo simplemente poner una tabla que contiene la información relevante para que yo pueda calcular donde todos los acontecimientos que se vaya? Si es así, me gustaría tener a calcular cada vez que el usuario visita una nueva parte de la agenda. ¿Y si la página a través de los meses, pero ellos tienen un montón de elementos periódicos?

También, el esquema debe manejar cuando un usuario hace clic en un elemento y dice "Editar esta en la secuencia" no todos los elementos de la secuencia. Puedo, a continuación, dividir el elemento de la secuencia?

Actualización 1

No he mirado en iCal. Para ser claro, creo que el ahorro de la información que permite calcular los recurrentes, y la división de cualquiera que difieren de la secuencia es una gran manera de almacenar para ser capaz de transferir. Pero creo que en una aplicación, esto sería demasiado lento, para hacer de la fecha de matemáticas de todo el lugar.

14voto

Justin Puntos 156

He estado luchando con el mismo problema, y en realidad estaba jugando con la "tabla de caché" idea sugerida por encima, pero luego me encontré con una alternativa (que aquí se sugiere) que parece que no han sido representados.

Construir una tabla que contiene todos los eventos

EventID (primary key)
Description
StartDate
PeriodType - days, weeks, months, years
PeriodFreq - # of days, weeks, etc between events
EndDate
... other attributes that can be modified

A continuación, añadir una tabla de excepciones a estos eventos. Esta tabla se utiliza una clave compuesta, formada por la EventID que se asigna a la tabla de eventos, y un IDENTIFICADOR de instancia para recoger el evento de la serie.

EventID (key)
InstanceID (key)
InstanceDate - the modified date of the exception 
IsCancelled - a flag to skip this date when traversing the series
... other attributes that can be modified

Parece que para mantener la tabla de eventos normalizado, y evita la separación de la serie para el manejo de excepciones.

12voto

JasonV Puntos 485

Recientemente he creado un calendario de aplicación y este fue uno de los muchos retos a los que me enfrentaba.

Finalmente me vino con un semi hack-ish solución. He creado un event_type columna. En esa columna, tuve: "diariamente", "semanal", "mensual" o "anual". Yo también tenía una start_date y un end_date columnas. Todo lo demás fue manejado en el backend de código.

Nunca he intentado dividir un evento cuando un usuario ha editado un solo evento. No era necesario en la situación. Sin embargo, usted puede dividir un evento por el cambio de la end_date de la primera, la creación de un nuevo evento con una nueva fecha de inicio y la end_date de la original, y por último, un nuevo evento para el que solo edite. Este proceso terminó creando 3 eventos.

Hack-ish, lo sé. Yo no podía pensar en una forma inteligente para manejar este problema en el momento.

3voto

ChristianLinnell Puntos 774

Mantenga pulsado el elemento recurrente en la tabla de eventos de manera normal, pero marcado como recurrente con las correspondientes fechas de inicio/ fin.

Si el usuario modifica una sola instancia de la cita, basta con crear un nuevo evento, tal vez con un 'parentId' igual al evento recurrente de la id.

Crear una lógica que hace que el calendario para reemplazar cualquiera de los eventos que se repiten en un día en particular con los eventos de coincidir con los padres de IDs.

A tu pregunta sobre el rendimiento es básicamente el viejo velocidad vs problema de almacenamiento. Yo realmente no creo que el cálculo requiere exceda el requerimiento de espacio para almacenar tantas citas. Acabo de leer en optimización de base de datos de indexación, etc.

2voto

Ben Dunlap Puntos 1101

Podría salvar a los dos mundos con un "cache" de la tabla, en la que se pre-calcular los próximos X días de eventos?

Así que tres tablas:

recurring_event_specs
one_time_events
cached_recurring_events

Para cualquier parte del calendario dentro de X días de hoy, su consulta UNIÓN one_time_events y cached_recurring_events.

A continuación, sólo tiene que hacer sobre la marcha, cálculos de fecha, si el usuario traté de mirar una parte del calendario de más de X días en el futuro. Me imagino que usted podría encontrar un sano X que cubren la mayoría de las normales de uso.

El cached_recurring_events tabla debe ser actualizada cada vez que un usuario añade un nuevo evento recurrente-y, posiblemente, una vez al día fuera de línea, por un cron job/programado-tarea. Pero sólo en los días cuando no hay nuevos eventos recurrentes ha sido creado.

0voto

Daniel Bardi Puntos 139

La mejor manera de hacer esto es para almacenar una basada en estándares de la recurrencia de la cadena de patrón (iCal).. y dejar en blanco si se trata de un evento único. Hay un par de APIs que pueden analizar el patrón de repetición y crear objetos de evento que usted puede unirse a los elementos de interfaz de usuario.... ninguno de los sucesos tienen que ser almacenados en la base de datos, sólo el evento inicial (ocurrencia)..

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by: