2009-11-04 4 views
0

Je stocke un ensemble de messages dans une table SQL. Chaque message a une taille et il y a une colonne dans la table qui contient la taille du message. Ces messages sont connectés à des comptes. Quand un nouveau message arrive, j'ai besoin de vérifier que la taille du compte courant + la taille du nouveau message est inférieure au quota du compte (qui est juste une colonne "maxaccountsize" dans une rangée dans la table des comptes). Sinon, je dois signaler à l'expéditeur que le message ne rentre pas dans le compte.Mise en cache d'objets pour améliorer les performances

Pour simplifier:

Table messages: 
    ID int 
    AccountID int 
    Size int 

Table accounts: 
    ID int 
    MaxSize int 

Pour calculer la taille totale de chaque compte, j'exécute des déclarations similaires à SELECT SUM (Taille) des messages OU AccountID = 12345.

Dans une grande bases de données utilisateur où il y a des centaines de milliers de messages dans les comptes, cette opération est lourde et devient un gros goulot d'étranglement lors de la réception d'un message. Mon logiciel utilise à la fois Microsoft SQL Server, MySQL et PostgreSQL comme backend.

Pour résoudre ce problème, j'ai ajouté un cache en mémoire de la valeur. Ceci est lourd pour moi car j'ai besoin d'implémenter des mises à jour thread-safe du cache, et je dois m'assurer que le cache est toujours à jour. En outre, cela ne fonctionne pas si quelqu'un modifie manuellement la base de données.

Une solution alternative consisterait à stocker la taille du compte actuel dans la table des comptes. Cependant, cela voudrait dire que j'ai des données quelque peu redondantes (bien sûr, on peut dire que c'est déjà le cas aujourd'hui avec mon cache en mémoire). Si je choisis cette solution, je dois m'assurer de toujours mettre à jour la taille du compte lors de la création ou de la suppression de messages. C'est aussi un peu lourd et je peux parier qu'il y aura des moments où la somme (taille) ne sera pas égale à la valeur CurrentAccountSize dans la ligne Accounts. Avec le cache en mémoire, il sera au moins réinitialisé à sa valeur correcte lorsque le serveur est redémarré.

Est-ce que quelqu'un a une opinion sur ce qui devrait être fait dans des situations comme celles-ci?

Répondre

3

Dans ce cas d'utilisation, je stockerais certainement des données redondantes dans votre base de données.

Pensez-vous que votre compte bancaire calcule la somme de toutes les transactions de son historique lors du calcul de votre solde?

+0

C'est la bonne chose à faire. Dans le cas où vous êtes enfermé dans un SGBD spécifique, vous pouvez utiliser des déclencheurs pour faire le sale boulot sans craindre que votre applogic ne le rate. Les déclencheurs se déclencheront toujours sur les insertions, les mises à jour, les suppressions, etc. même si un administrateur sql ou un travail par lots mettra à jour/insère/supprime des messages – mhaller

+0

Autant que je déteste les déclencheurs (et je le fais vraiment), c'est probablement un cas où leur utilisation est approprié. – DanSingerman

+0

Bon point. Je vois une légère différence entre mon cas et l'exemple de la banque, mais je comprends ce que vous voulez dire. – Nitramk

Questions connexes