Bonjour à tous !
Je viens demander quelques conseils quant à un problème de conception de bases de données.
Je dois concevoir un agenda avec des événements. Sommairement, un événement comprend une date/heure de début, une date/heure de fin et une description (d'autres champs viendront compléter cette entité plus tard).
Le problème est que je dois prendre en compte les répétitions ; à la création d'un événement, il est possible d'indiquer que cet événement doit avoir lieu tous les lundis par exemple, à partir de la semaine prochaine et jusqu'à une date précise ou pas.
Je vois deux possibilités de conception ;
- créer une table events avec comme champs id, start_datetime, end_datetime et description.
Lors de l'ajout d'un nouvel événement, on génère autant de lignes qu'il y a d'événements répétés.
Avantages : il suffit de faire un SELECT * pour récupérer tous les événements, sans algorithme particulier. De plus, il est possible de modifier les descriptions de chaque occurrence d'un événement, dans la mesure où ils sont considérés comme tous différents.
Inconvénient (MAJEUR !) : si on ne met pas de date de fin pour avoir une répétition infinie, on ne va pas mémoriser une infinité d'événements...- s'inspirer de la méthode décrite sur ce lien, c'est-à-dire faire deux tables :
- table events
id description
1 Événement simple le 23/11/2018 08:00-09:30 2 Événement répété :
- tous les lundis de 10:00 à 12:00 à partir du lundi 26/11/2018
- tous les mercredis à partir du 28/11/2018 de 14:00 à 14:45 jusqu'au 27/02/2019
- table event_repetitions
id
event_id start_datetime
end_datetime interval
end_date
1 1 2018-11-23 08:00:00 2018-11-23 09:30:00 NULL NULL 2 2 2018-11-26 10:00:00 2018-11-26 12:00:00 604800 NULL 3 2 2018-11-28 14:00:00 2018-11-28 14:45:00 604800 2019-02-27
Note : interval désigne le nombre de secondes séparant chaque occurrence, ici 604800 = 24 (heures) * 3600 (secondes) * 7 (jours).
Avantage : dans le cas de répétitions infinies (cas de l'event d'id 2), on a très peu de lignes à écrire et les performances sont accrues.
Inconvénients : si on souhaite modifier la description de l'événement (ou d'autres éventuels champs) pour une occurrence précise et pas une autre, on ne peut pas sans créer une troisième table, event_descriptions par exemple :
id
event_id user_id datetime description
1 2 1 2018-11-26 10:00:00 Commentaire du 26/11/2018 2 2 2 2018-12-03 10:00:00 Commentaire de la deuxième occurrence, c'est-à-dire du 02/12/18
Note : user_id désigne l'utilisateur connecté qui a écrit le commentaire.
Un autre inconvénient est que pour obtenir la liste des événements pour un jour, une semaine ou un mois donné, la requête de sélection sera plus complexe et utilisera des jointures. La table event_descriptions risquera, lorsqu'il y aura des centaines de milliers d'événements, d'être très grosse.
Ma question est donc : que conseilleriez-vous comme alternative plus efficace ? Peut-être que la deuxième solution est bonne ? Qu'en pensez-vous ?
Au niveau des technologies utilisées, je compte partir sur du MySQL, le SGBD que je connais le mieux. Néanmoins, si vous pensez qu'utiliser par exemple MongoDB est meilleur en cas de très importants nombres de lignes, n'hésitez pas à le signaler.
Pour information, mon application est une API développée avec API Platform, sur du Symfony 4 donc.
Merci d'avance de vos réponses.
Partager