2009-09-02 6 views
1

Dans mon application, les utilisateurs doivent être en mesure de définir des dates lorsqu'elles sont disponibles. C'est à dire. utilisateur joe peut définir qu'il est disponible:
- tous les lundis, mercredis et dimanches entre 15h00 et 17h00 du 1.09.2009 au 15.11.2009. - au 2.09.2009 entre 12:00 et 14:00 et ainsi de suite ...Conception de table pour les dates cycliques

Les dates peuvent être définies au maximum 1 an à l'avenir.

Les utilisateurs peuvent ajouter, modifier et supprimer des dates définies.

D'autres utilisateurs peuvent rechercher des utilisateurs disponibles. - trouver tous les utilisateurs disponibles 8.09.2009 à 15:30

Le problème est de savoir comment concevoir des tables sql, qui permettent de créer et d'éditer des dates cycliques et une recherche efficace. J'utilise postgresql mais je cherche plutôt des lignes directrices. Peut-être que quelqu'un a de l'expérience avec un problème similaire?

Merci à l'avance

Répondre

1

Quand j'ai eu affaire avec des données comme ça avant, j'ai pris une « règles » approche similaire à celle d'accueillir par jour la planification et l'ordonnancement bloc:

CREATE TABLE availability_rules (
    id SERIAL UNIQUE, 
    user_id NOT NULL REFERENCES users(id), 
    day_of_week INTEGER CONSTRAINT valid_day_of_week CHECK (day_of_week BETWEEN 0 and 6) 
    start_time TIME, 
    start_date DATE, 
    end_time TIME, 
    end_date DATE 
); 

Remarque: vous devez Ajoutez des contraintes supplémentaires à la table de règles pour vous assurer que end_date + end_time> = start_date + start_time, etc.

Ensuite, vous pouvez créer une vue "availability" pour générer un planning normalisé avec user_id, date, start_time et end_time . En utilisant 8.4, ceci est facile avec les nouvelles capacités de datetime de generate_series. (http://www.postgresql.org/docs/current/static/functions-srf.html) Il est assez facile d'écrire une fonction qui fait la même chose si vous êtes sur 8.3 ou plus tôt.

+0

contraintes sont certainement une bonne idée. Mon approche actuelle utilise generate_series mais j'ai peur que pour un milion d'enregistrement ce soit inefficace, les index ne seront pas utilisés. – mlomnicki

+0

Je pense que tout ira bien. Mais, pour des performances maximales ... vous pouvez matérialiser la vue dans une table de disponibilité mise en cache et, plutôt que de la mettre à jour en une fois, utiliser des déclencheurs pour insérer ou mettre à jour de manière sélective en fonction de quelle règle a été modifiée et comment. Ensuite, vous pouvez effectuer une requête sur une vue matérialisée pour obtenir la disponibilité tout en conservant les règles séparément. Avant d'emprunter cette route, j'exécuterais au moins une ANALYZE EXPLAIN avec la vue pour mesurer la performance. –

+0

c'est certainement la meilleure proposition. Cependant, je n'ai rien trouvé à propos de la «table de disponibilité mise en cache». Comment le gérer dans postgres? Donnez-moi un lien ou des instructions de base, s'il vous plaît. – mlomnicki

0

Vous souhaitez stocker une disponibilité des utilisateurs dans la base de données et utiliser un langage de programmation pour vérifier la disponibilité plutôt que d'avoir une logique complexe dans la base de données elle-même. L'utilisation d'un outil ORM faciliterait cela.

La disponibilité d'un utilisateur consisterait en une liste de paires de datetime.

+0

Il y aura des millions de dossiers. J'ai peur de le faire au niveau de l'application sera trop lent. – mlomnicki

1

Option 1

Vous stockeriez la disponibilité avec 3 colonnes (en supposant un seul identifiant col pour identifier un utilisateur)

availability_start, availability_end, user_id 

recherche basée sur un datetime serait alors quelque chose comme

select 
    user_id 
from 
    availability 
where 
    desired_datetime > availability_start 
and 
    desired_datetime < availability_end 

vous pouvez supprimer des dates antérieures en fonction de la fonctionnalité que vous souhaitez offrir. Évidemment, vous devrez décider jusqu'à quel point dans l'avenir pour stocker les dates en fonction des définitions de date cyclique des gens.

Option 2

Si elle est toujours aussi simple que le choix des jours individuels de la semaine et les heures pour les jours. Vous pouvez stocker des dates cycliques comme

user_id, day_of_week, availability_time_start, availability_time_end 

Les heures de début et de fin ne nécessitent aucun composant de date. Recherche basée sur un jour de la semaine et un temps serait quelque chose comme

select 
    user_id 
from 
    availability 
where 
    desired_day_of_week = day_of_week 
and 
    desired_time > availability_time_start 
and 
    desired_time < availability_time_end 

En aparté, il y a des bibliothèques qui aident à la création de ces modèles de date récurrents, où je travaille, nous utilisons this (Java) , il pourrait bien y avoir des implémentations RFC 2445 dans un langage qui vous convient.

Si vous utilisez quelque chose comme ça, alors vous ne stockez pas les dates réelles, mais seulement les détails des modèles de récurrence qui ne vous aideront pas vraiment avec votre problème.Nous stockons ces détails en prenant simplement les valeurs de la définition de récurrence et en les conservant dans le champ db one to one. Vous pouvez également stocker les dates/heures pour une durée définie dans le futur et les recalculer en cas de modification des définitions de récurrence. Cela peut évidemment devenir une opération assez importante en fonction du nombre de plannings des utilisateurs et de la manière dont loin dans le futur, vous voulez stocker des données.

+0

J'ai ajouté la description de la date maximale. Pour autant que je sache RFC2445 peut être utilisé uniquement pour le calendrier d'exportation. Je ne peux pas imaginer comment stocker le format icalendar dans db et faire des recherches dessus. J'aime les idées simples, mais je pense que c'est trop simple. Qu'en est-il du stockage et de l'édition des dates cycliques? – mlomnicki

+0

J'ai ajouté l'option 2 qui peut être d'une aide et une brève mention de la façon dont nous persistons simplement RFC 2445 définitions – Robin

0

Ce que vous pouvez faire est d'avoir une table qui a la conception suivante:

Availability 
    - userId, Foreign key to user table 
    - startDate, datetime 
    - endDate, datetime 
    - startTime, datetime 
    - endTime, datetime 
    - monday, bit 
    - tuesday, bit 
    - wednesday, bit 
    - thursday, bit 
    - friday, bit 
    - saturday, bit 
    - sunday, bit 

Maintenant, vous pouvez vérifier la disponibilité à certains jours de la semaine avec les éléments suivants (MSSQL yntax)

SELECT * FROM User u WHERE EXISTS(
    SELECT 1 FROM Availability WHERE userId = u.id AND 
    @startDate >= startDate AND @endDate <= endDate AND 
    @startTime >= startTime AND @endTime <= endTime AND 
    (monday = 1 OR tuesday = 1) 
) 

Ce qui serait vous donne tous les utilisateurs disponibles entre @startDate et @endDate les lundis ou mardis entre @startTime et @endTime.

+0

c'est une idée très intéressante, je vais vérifier tout de suite – mlomnicki

Questions connexes