2009-06-03 14 views
42

Deseo escribir una aplicación de calendario. En realidad, se trata de elementos recurrentes que lanzan una llave en mano para el esquema DB. Me encantaría obtener información sobre cómo organizar esto.Establecimiento de un esquema de base de datos para una aplicación de calendario

¿Qué pasa si un usuario crea un evento y las entradas que repite todos los lunes, para siempre? ¿Cómo podría almacenar todo eso en la base de datos? No puedo crear eventos infinitos. ¿Simplemente pongo una tabla que contiene la información relevante para que pueda calcular dónde van todos los eventos? Si es así, tendría que calcularlos cada vez que el usuario vea una nueva parte del calendario. ¿Qué pasa si revisan los meses, pero tienen un montón de elementos recurrentes?

Además, el esquema debe controlarse cuando un usuario hace clic en un elemento y dice "Editar este en la secuencia", no todos los elementos de la secuencia. ¿Luego separé un elemento de la secuencia?

Actualización 1

no he mirado iCal en absoluto. Para que quede claro, creo que guardar la información que le permite calcular los elementos recurrentes, y dividir cualquiera que difiera de la secuencia es una gran manera de almacenarlo para poder transferirlo. Pero creo que en una aplicación, esto sería demasiado lento, para hacer las matemáticas de fecha por todas partes.

+1

"¿Luego separe el elemento de la secuencia?" Creo que así es como lo maneja el formato de archivo iCal. ¿Has estudiado ese formato en absoluto? –

+1

¡Qué excelente pregunta! Me preguntaba esto el otro día. –

Respuesta

12

Recientemente creé una aplicación de calendario y este fue uno de los muchos desafíos que enfrenté.

Finalmente se me ocurrió una solución semi-pirata. Creé una columna event_type. En esa columna, tenía: "diario", "semanal", "mensual" o "anual". También tuve una start_date y una end_date columnas. Todo lo demás se manejó en el código de back-end actual.

Nunca intenté dividir un evento si un usuario editó solo un evento. No era necesario en la situación. Sin embargo, podría dividir un evento cambiando la fecha_final del primero, creando un nuevo evento con una nueva fecha de inicio y la fecha final del original, y finalmente, un nuevo evento para el que acaba de elegir para editar. Este proceso terminaría creando 3 eventos.

Hack-ish, lo sé. No pude pensar en una forma inteligente de manejar este problema en ese momento.

+0

Sí, esto es más o menos lo que había pensado, pero ¿no te toma un golpe de rendimiento por hacer todos esos cálculos de fecha? –

+0

Sí, pero lo consideré necesario. No pude encontrar una forma clara de manejarlo con una base de datos sin un extenso código de back-end. – JasonV

+0

¿Puedo obtener el esquema de la base de datos del programador de eventos del calendario, lo que me permite saber qué tablas puedo tomar? – Tejinder

2

Mantenga el elemento recurrente en la tabla de eventos de forma normal, pero marcado como recurrente con las fechas de inicio/finalización apropiadas.

Si el usuario modifica una sola instancia de la cita, simplemente cree un nuevo evento, quizás con un 'parentId' igual al id del evento recurrente.

Lógica de compilación que hace que el calendario anule cualquier evento recurrente en un día en particular con eventos con identificadores principales coincidentes.

Su pregunta sobre el rendimiento es básicamente la cuestión de la velocidad anterior frente al almacenamiento. Realmente no creo que el cálculo requerido exceda el requisito de espacio para almacenar tantas citas. Simplemente lea sobre optimización de bases de datos, indexación, etc.

+0

No es el rendimiento de DB lo que me preocupa. Es el código de backend haciendo la fecha matemática. Entonces, si digo que este evento es cada 3er lunes, comenzando en 08 y que nunca termina, y ahora es 2010, debes averiguar dónde cae eso en tu calendario. Quizás eso no es tan intenso como creo que es. –

+1

Solo tiene que averiguarlo para el rango de fechas visibles. Como si estuviera viendo tres meses, solo tienes que calcular esos meses. Solo necesita recuperar cada registro por cada día, y luego cada registro recurrente (solo una vez) y averiguar a qué días del rango visible se aplica cada uno. No puedo ver que sea demasiado severo. – ChristianLinnell

2

¿Podría unir los dos mundos con una tabla de "caché", en la que precalcula 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, la consulta será UNIÓN one_time_events y cached_recurring_events.

Entonces solo tendrías que hacer cálculos sobre la marcha de la fecha si el usuario intentara mirar una parte del calendario más de X días en el futuro. Me imagino que podrías encontrar una X sana que cubriría la mayoría del uso normal.

La tabla cached_recurring_events debería actualizarse cada vez que un usuario agrega un nuevo evento recurrente, y posiblemente una vez al día sin conexión, mediante un cron-job/scheduled-task. Pero solo en los días en que no se haya creado un nuevo evento recurrente.

0

La mejor manera de hacerlo es almacenar una cadena de patrón de recurrencia basada en estándares (iCal) .. y dejarla en blanco si se trata de un solo evento. Hay algunas API que pueden analizar el patrón de recurrencia y crear objetos de evento que puede vincular a elementos de la UI ... ninguna de las apariciones se debe almacenar en la base de datos, solo el evento inicial (ocurrencia).

+0

Usando este método, ¿cómo selecciono todas las ocurrencias de un evento dentro de un tiempo específico, sin un análisis completo de esa cadena para cada elemento? – Kurucu

12

He estado luchando con el mismo problema, y ​​en realidad estaba jugando con la idea de "tabla de caché" sugerida anteriormente, pero luego me encontré con una alternativa (suggested here) que no parece haber sido representada todavía.

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 mesa para excepciones a estos eventos. Esta tabla utiliza una clave compuesta, compuesta por EventID que se asigna a la tabla de eventos, y una ID de instancia para elegir el evento particular 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 mantiene la tabla de eventos normalizada y evita la división de series para gestionar excepciones.

+0

puede publicar/compartir su último esquema –

0

¿No pudo almacenar los eventos por día con hora de inicio y finalización? Generará una gran cantidad de datos para eventos que suceden todos los días (tal vez no sea relacional para esto) pero facilitará las consultas y será posible hacer excepciones (por ejemplo, el lugar del evento se quemó, o los empleados están en huelga). Para generar los días del evento, sugeriría implementar eso en el front-end derivado de algún patrón ICal-ish.

+0

problema de OP con esto es cómo maneja infinitas fechas de finalización. – nbeuchat

4

¿Por qué no utilizar Google Calendar como base de datos para esta aplicación de calendario confiando en Google Calendar's API para almacenar y recuperar eventos de calendario?

La API de calendario es una API REST a la que se puede acceder a través de llamadas HTTP explícitas; la API expone la mayoría de las funciones disponibles en la interfaz web de Google Calendar, por lo que su aplicación de calendario puede tener tanta funcionalidad como Google Calendar (¡mucha funcionalidad!).

Su aplicación solo necesita implementar OAuth 2.0 para las API de Google, lo que puede simplificarse mediante un servicio de inicio de sesión único como Auth0 para proporcionar los tokens de acceso apropiados. Luego, su aplicación de calendario puede usar estos tokens junto con la API de Calendar para proporcionar un almacenamiento y recuperación sin interrupciones de eventos de calendario en formato JSON.

Los usuarios crean eventos dentro de su propio "Nuevo calendario". Este calendario se comparte con usted en forma de una cuenta de Gmail dedicada a esta aplicación: la cuenta de gmail de la aplicación.

Básicamente, Google Calendar se convierte en su base de datos, donde puede tener la cuenta de gmail de la aplicación no solo almacena todos los eventos de su aplicación, sino que también le permite ver y editar estos eventos con una interfaz intuitiva.

Cuestiones relacionadas