Question

J'utilise Firebird 2.1 et je suis à la recherche de la meilleure façon de résoudre ce problème.

J'écris une application calandrer. Les entrées de l'agenda de différents utilisateurs sont stockés dans une grande table de calendrier. Chaque entrée de calendrier peut avoir un ensemble de rappel -. Un seul rappel / entrée

Statistiquement, la table de calendrier pourrait atteindre des centaines de milliers d'enregistrements au fil du temps, alors qu'il y aura beaucoup moins de rappels.

Je dois interroger les rappels sur une base constante.

Quelle est la meilleure option?

A) Stockez l'information de rappels dans le tableau du calendrier (dans ce cas, je vais à des centaines de requêtes de milliers d'enregistrements pour IsReminder = 1)

B) Créer une table Reminders séparée qui ne contient que l'ID d'entrées de calendrier qui ont des rappels définis, puis interroger les deux tables avec une opération JOIN (ou peut-être créer une vue sur eux)

C) je peux stocker toutes les informations sur les rappels dans le tableau Reminders, alors que la requête de cette table. L'inconvénient est que certaines informations doivent être reproduites dans les deux tableaux, comme pour montrer le rappel, je vais avoir besoin de connaître et de stocker dans la table Reminders de starttime de l'événement - ainsi je maintenant deux tables avec les mêmes valeurs.

Que pensez-vous?

Et une autre question: Le tableau de calendrier contiendra le calendrier de plusieurs utilisateurs, séparés seulement par un champ UserID. Comme il peut y avoir que 4-5 utilisateurs, même si je mets un index sur ce champ, sa sélectivité va être très mauvais - qui est pas bon pour une table avec des centaines de milliers de disques. Y at-il une solution de contournement ici?

Merci!

Était-ce utile?

La solution

Il y a des avantages et des inconvénients à trois choix. Whis est le mieux dépend de détails que vous n'avez pas fourni. En général, ne vous inquiétez pas trop sur la sélection de trois ou quatre entrées sur cent mille, à condition que les indices que vous avez mis en place permettent la stratégie de récupération à droite. Si vous ne comprenez pas l'indexation, vous êtes susceptible d'être en difficulté, peu importe lequel des trois choix que vous faites.

Si c'était moi, j'aller avec le choix B. Je voudrais aussi stocker tous les attributs d'un rappel dans le tableau pour les rappels.

Soyez très prudent si vous identifiez un événement par EventId seul ou par (UserId, EventId). Si vous choisissez ce dernier, il vous appartient d'utiliser une clé primaire composée pour la table d'événements. Ne vous inquiétez pas trop sur les clés primaires composées, en particulier avec Firebird.
Si vous déclarez une clé primaire composée, il faut savoir que la déclaration (UserId, EventId) ne seront pas les mêmes conséquences que la déclaration (EventId, UserId). Ils sont logiquement équivalents, mais la structure de l'index généré automatiquement sera différent dans les deux cas.

Cela aura une incidence sur la vitesse des requêtes comme « trouver tous les rappels pour un utilisateur donné. »

Encore une fois, si elle était moi, il faut éviter le choix C. l'introduction de redondance nuisibles dans un schéma porte avec elle la responsabilité d'une programmation très attention quand vous allez mettre à jour les données. Sinon, vous pouvez vous retrouver avec une base de données qui stocke les versions contradictoires du même fait dans des endroits différents de la base de données.

Et, si vous voulez vraiment savoir l'effet sur perfromance, essayez les trois façons, charge avec des données de test, et faire vos propres repères.

Autres conseils

Je pense que vous avez besoin de créer réalistes, les données utilisateur de faux et de mesurer la différence avec certaines requêtes typiques que vous attendez à courir.

L'indexation, l'optimisation des requêtes et les types de résultats de la requête dont vous avez besoin peut faire une grande différence, il est donc difficile de dire ce qui est mieux sans en savoir plus.

Lors du choix d'option (A), vous devez

  • fournir un index sur "IsReminder" (ou un indice combiné sur IsReminder, UserId, ce qui convient le mieux à vos requêtes destinées)
  • assurez-vous que vos requêtes utilisent cet index

L'option B est préférable à un si vous avez plus d'un drapeau booléen pour chaque rappel pour stocker (par exemple, le nombre de minutes, l'utilisateur doit être informé avant l'événement). Vous devez cependant faire un peu deviner combien de fois dans votre programme, vous devrez joindre les deux tables.

Si vous pouvez, option éviter C. Si vous ne voulez pas de référence les trois cas, je suggère commencer par A ou B, selon les circonstances décrites, et probablement la solution que vous choisissez sera assez rapide, vous ne pas déranger les autres cas.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top