database - personal - la mejor agenda para android 2018
Establecer un esquema de base de datos para una aplicación de calendario (7)
Quiero 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.
¿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? De ser 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 administrarse 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 visto a 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.
¿No podrías almacenar los eventos por día con la hora de inicio y finalización? Generará una gran cantidad de datos para los eventos que suceden todos los días (tal vez no sea relacional para esto) pero facilitará las consultas y será posible hacer excepciones (si el lugar del evento se quemó, o si 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.
¿Podría unir los dos mundos con una tabla de "caché", en la que precalcula los próximos X días de eventos?
Entonces tres tablas:
recurring_event_specs
one_time_events
cached_recurring_events
Para cualquier parte del calendario dentro de X días a partir de hoy, su consulta será UNION 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 siempre que un usuario agregue un nuevo evento recurrente, y posiblemente una vez al día fuera de línea, mediante un cron-job / scheduled-task. Pero solo en los días en que no se haya creado un nuevo evento recurrente.
¿Por qué no utilizar Google Calendar como base de datos para esta aplicación de calendario confiando en la API de Google Calendar 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 Auth0 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, por lo que puede hacer que la cuenta de gmail de la aplicación no solo almacene todos los eventos de su aplicación, sino que también le permita ver y editar estos eventos con una interfaz intuitiva.
Hace poco 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 hack-ish. 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.
He estado luchando con el mismo problema, y en realidad estaba jugando con la idea de "tabla de caché" sugerida anteriormente, pero luego encontré una alternativa ( sugerida aquí ) que no parece haber sido representada todavía.
Crea una tabla que contenga 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, agregue una tabla 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 mantener la tabla de eventos normalizada, y evita dividir series para manejar excepciones.
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 evento único. Hay algunas API que pueden analizar el patrón de recurrencia y crear objetos de evento que puede vincular a elementos de la interfaz de usuario ... ninguna de las apariciones se debe almacenar en la base de datos, solo el evento inicial (aparición).
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, tal vez con un ''parentId'' igual al id del evento recurrente.
Construir lógica que hace que el calendario anule cualquier evento recurrente en un día en particular con eventos con identificadores principales coincidentes.
Tu pregunta sobre el rendimiento es básicamente la vieja velocidad versus el problema de 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, indización, etc.