Comment implémenter une base de données / table comme une pile

11

J'ai une machine à états qui doit pousser / pop certains noms de fichiers pour différents utilisateurs. J'utiliserais traditionnellement des piles comme choix de structure de données, mais cela doit être fait en utilisant une base de données car je n'ai pas de moyen de conserver la structure de données entre les requêtes Web entrantes.

Je me demandais quel serait un bon moyen d'implémenter la fonctionnalité de pile à l'aide de bases de données?

Je dois soutenir:

  • push (fileName, user): push un fileName pour l'utilisateur
  • pop (utilisateur): affiche le nom de fichier le plus élevé de l'utilisateur

MODIFIER :

Je prototype une idée et j'utilise donc sqlite3 avec python.

Merci!

brainydexter
la source
vous attendez-vous à ce que le même utilisateur ait plusieurs connexions simultanées? quels volumes? quel moteur Db aussi s'il vous plait?
gbn
@gbn Finalement, le même utilisateur peut avoir des connexions simultanées. Mais pour l'instant, je suis en train de prototyper une idée et je suppose une connexion unique par utilisateur
brainydexter
@brainydexter J'aimerais beaucoup savoir ce que vous essayez de faire. J'ai l'impression que vous créez peut-être la mauvaise solution à votre problème. Vous pourriez envisager de nous faire part de votre problème et de demander la meilleure solution pour le résoudre. L'implémentation d'une pile en tant que table de base de données semble être une mauvaise idée.
xenoterracide
@xenoterracide: L'intention générale de ce que j'essaie de faire chez SO: stackoverflow.com/questions/5145051/… La pile n'a pas fonctionné complètement, alors je cherche toujours une solution à cela.
brainydexter
1
@brainydexter n'est pas vraiment surpris, SQL est un langage horrible pour implémenter une pile, car par définition relationnelle un ensemble n'est pas ordonné, donc votre pile n'aura pas d'ordre, et vous devrez le trier. Une partie de votre problème est peut-être de dire aux gens ce que vous voulez que la réponse soit, et vous demandez comment. Au lieu de leur dire quel est le problème et de demander quoi. Même votre question SO mène la réponse à quelque chose de spécifique. Essayez de demander la solution à laquelle vous ne penserez pas.
xenoterracide

Réponses:

6

Si vous demandez quelle base de données utiliser, cela dépend vraiment de vos préférences personnelles et de ce que vous en voulez. Comme je ne connais que MySQL, je répondrai à l'autre partie de la question en supposant que MySQL:

vous voudrez utiliser INNODBparce que votre table va être gourmande en écriture et pour les grandes tables, le verrouillage des lignes d'INNODB sera un épargnant de vie MyISAM.

En ce qui concerne la conception des tables, il semble que vous n'ayez vraiment besoin que d'une seule table:

CREATE TABLE `wordpress`.`<table_name>` (
`id` smallint(4) NOT NULL AUTO_INCREMENT UNSIGNED,
`user` varchar(30) NOT NULL,
`filename` varchar(255) NOT NULL,
`date_insert` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE `userFile`(user, filename)
) ENGINE=`InnoDB`;

Je suis allé avec une colonne 'id' arbitraire définie sur AUTO_INCREMENTcar la clé primaire est répliquée dans chaque entrée de chaque index. Donc, faire une clé primaire de (utilisateur, nom de fichier) peut entraîner des problèmes de performances si vos noms de fichiers sont extrêmement longs.

La taille de votre colonne 'id' dépend de la taille de votre table. Un Smallint non signé vous donnera 65 000 lignes.

L'utilisateur et les noms de fichiers sont varchar, car ils varient considérablement en longueur, je suppose.

C'est date_insertjuste un moyen de classer vos résultats en fonction du moment où ils ont été insérés (utile pour votre POP)

Derek Downey
la source
Je pensais faire une combinaison (id, utilisateur) comme clé primaire, car j'aimerais pousser ou sauter en fonction de l'utilisateur. Qu'est-ce que tu penses ? De plus, pour l'opération POP, ne serait-il pas préférable de trouver l'enregistrement de l'utilisateur avec l'identifiant maximum?
brainydexter
@brainydexter dev.mysql.com/doc/refman/5.0/en/innodb-restrictions.html a quelques restrictions sur l'auto-incrémentation (il réutilisera les valeurs d'auto-incrémentation «inférieures» dans certains cas rares). parce que c'est une possibilité, je suis allé avec un champ date_insert. Quant à l'utilisation (id, utilisateur) comme clé primaire, cela ne sert à rien sauf à prendre plus de stockage. ID identifie de façon unique la ligne. juste «utilisateur» en lui-même n'identifie pas la ligne, vous pouvez donc avoir un index non unique sur «userID» au lieu d'un unique (utilisateur, nom de fichier) si vous le souhaitez.
Derek Downey
6

Si vous envisagez une base de données Oracle, vous devez envisager d'utiliser Advanced Queuing avec un modèle de retrait de file d' attente LIFO (dernier entré premier sorti) .

Au niveau de mise en file d'attente le plus élémentaire, un producteur place un ou plusieurs messages dans une file d'attente. Chaque message est retiré de la file d'attente et traité une fois par l'un des consommateurs. Un message reste dans la file d'attente jusqu'à ce qu'un consommateur le retire ou que le message expire. Un producteur peut stipuler un délai avant que le message ne soit disponible pour être consommé, et un délai après lequel le message expire. De même, un consommateur peut attendre lorsqu'il essaie de retirer un message si aucun message n'est disponible. Un programme ou une application d'agent peut agir à la fois comme producteur et comme consommateur.

Leigh Riffel
la source
configuration classique producteur / consommateur. Merci pour l'info, je vais m'en souvenir.
brainydexter
Espérons que MySQL obtiendra une fonctionnalité de file d'attente d'Adance maintenant qu'Oracle "possède" mysql ...
Derek Downey
1
@DTest: bien sûr, il y a aussi la possibilité distincte que mySQL est maintenant moins susceptible d'obtenir des fonctionnalités avancées, afin qu'Oracle puisse faire la différence entre un logiciel gratuit et un logiciel que vous devez payer.
Joe
@Joe merci d'avoir gâché mon week-end avec cette pensée!
Derek Downey