Wie implementiere ich eine Datenbank / Tabelle als Stapel?

11

Ich habe eine Zustandsmaschine, die einige Dateinamen für verschiedene Benutzer pushen / einfügen muss. Ich würde traditionell Stapel als Wahl der Datenstruktur verwenden, aber dies muss unter Verwendung einer Datenbank erfolgen, da ich keine Möglichkeit habe, die Datenstruktur zwischen eingehenden Webanforderungen beizubehalten.

Ich habe mich gefragt, wie ich die Stack-Funktionalität mithilfe von Datenbanken implementieren kann.

Ich muss unterstützen:

  • push (Dateiname, Benutzer): Drücken Sie einen Dateinamen für den Benutzer
  • pop (Benutzer): Pop den obersten Dateinamen für den Benutzer

EDIT :

Ich arbeite als Prototyp einer Idee und verwende daher sqlite3 mit Python.

Vielen Dank!

Brainydexter
quelle
Erwarten Sie, dass derselbe Benutzer mehrere gleichzeitige Verbindungen hat? Welche Bände? Welcher Db-Motor bitte auch?
Gbn
@gbn Möglicherweise hat derselbe Benutzer gleichzeitig Verbindungen. Aber im
Moment
@brainydexter Ich würde sehr gerne wissen, was Sie versuchen zu tun. Ich habe das Gefühl, dass Sie möglicherweise die falsche Lösung für Ihr Problem finden. Vielleicht möchten Sie uns Ihr Problem mitteilen und nach dem besten Weg fragen, um es zu lösen. Das Implementieren eines Stapels als Datenbanktabelle klingt nach einer schlechten Idee.
Xenoterracide
@xenoterracide: Die allgemeine Absicht dessen, was ich bei SO versuche: stackoverflow.com/questions/5145051/… Stack hat nicht vollständig funktioniert, daher suche ich immer noch nach einer Lösung für dieses Problem .
Brainydexter
1
@brainydexter nicht wirklich überrascht, SQL ist eine schreckliche Sprache, um einen Stapel zu implementieren, da nach relationaler Definition eine Menge ungeordnet ist, sodass Ihr Stapel keine Reihenfolge hat und Sie sie sortieren müssten. Vielleicht liegt ein Teil Ihres Problems darin, dass Sie den Leuten sagen, wie die Antwort lauten soll, und Sie fragen, wie. Anstatt ihnen zu sagen, was das Problem ist, und zu fragen, was. Sogar Ihre SO-Frage führt die Antwort auf etwas Bestimmtes. Fragen Sie nach der Lösung, an die Sie nicht denken.
Xenoterracide

Antworten:

6

Wenn Sie sich fragen, welche Datenbank Sie verwenden möchten, hängt dies wirklich von Ihren persönlichen Vorlieben ab und davon, was Sie davon erwarten. Da ich nur mit MySQL vertraut bin, beantworte ich den anderen Teil der Frage unter der Annahme von MySQL:

Sie möchten verwenden, INNODBda Ihre Tabelle schreibintensiv sein wird und bei großen Tabellen die Zeilensperrung von INNODB lebensrettend ist MyISAM.

Was das Tischdesign angeht, brauchen Sie anscheinend nur einen Tisch:

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`;

Ich habe eine beliebige 'id'-Spalte gewählt, AUTO_INCREMENTda der Primärschlüssel in jedem Eintrag jedes Index repliziert wird. Wenn Sie also einen Primärschlüssel von (Benutzer, Dateiname) eingeben, kann dies zu Leistungsproblemen führen, wenn Ihre Dateinamen extrem lang sind.

Die Größe Ihrer ID-Spalte hängt davon ab, wie groß Ihre Tabelle wird. Mit unsigned Smallint erhalten Sie 65.000 Zeilen.

Benutzer- und Dateinamen sind varchar, da sie sich in der Länge drastisch unterscheiden, nehme ich an.

Dies date_insertist nur eine Möglichkeit, Ihre Ergebnisse nach dem Zeitpunkt des Einfügens zu ordnen (hilfreich für Ihren POP).

Derek Downey
quelle
Ich dachte daran, eine Kombination (ID, Benutzer) als Primärschlüssel zu erstellen, da ich basierend auf dem Benutzer pushen oder popen möchte. Was denkst du ? Wäre es für die POP-Operation nicht besser, den Datensatz für den Benutzer mit der maximalen ID zu finden?
Brainydexter
@brainydexter dev.mysql.com/doc/refman/5.0/de/innodb-restrictions.html hat einige Einschränkungen hinsichtlich der automatischen Inkrementierung (in bestimmten seltenen Fällen werden niedrigere Autoinkrementierungswerte wiederverwendet). weil es eine Möglichkeit ist, habe ich mich für ein date_insert-Feld entschieden. Die Verwendung von (ID, Benutzer) als Primärschlüssel hat keinen Sinn, außer mehr Speicherplatz zu beanspruchen. ID identifiziert die Zeile eindeutig. Nur 'Benutzer' allein identifiziert die Zeile nicht. Sie können also einfach einen nicht eindeutigen Index für 'Benutzer-ID' anstelle eines eindeutigen (Benutzer, Dateiname) verwenden, wenn Sie möchten.
Derek Downey
6

Wenn Sie eine Oracle-Datenbank in Betracht ziehen, sollten Sie Advanced Queuing mit einem LIFO- Warteschlangenmuster (last in first out) in Betracht ziehen .

Auf der grundlegendsten Ebene der Warteschlange stellt ein Produzent eine oder mehrere Nachrichten in eine Warteschlange. Jede Nachricht wird von einem der Verbraucher einmal in die Warteschlange gestellt und verarbeitet. Eine Nachricht bleibt in der Warteschlange, bis ein Verbraucher sie aus der Warteschlange entfernt oder die Nachricht abläuft. Ein Produzent kann eine Verzögerung festlegen, bevor die Nachricht zum Verzehr verfügbar ist, und eine Zeit, nach der die Nachricht abläuft. Ebenso kann ein Verbraucher warten, wenn er versucht, eine Nachricht aus der Warteschlange zu entfernen, wenn keine Nachricht verfügbar ist. Ein Agentenprogramm oder eine Anwendung kann sowohl als Produzent als auch als Verbraucher fungieren.

Leigh Riffel
quelle
klassisches Produzenten / Konsumenten-Setup. Danke für die Info, ich werde es mir merken.
Brainydexter
Hoffentlich wird MySQL jetzt, da Oracle MySQL "besitzt", einige Adance Queue-Funktionen erhalten ...
Derek Downey
1
@DTest: Natürlich gibt es auch die eindeutige Möglichkeit, dass mySQL jetzt weniger wahrscheinlich erweiterte Funktionen erhält, sodass Oracle zwischen freier Software und einer Software unterscheiden kann, für die Sie bezahlen müssen.
Joe
@ Joe danke, dass du mein Wochenende mit diesem Gedanken ruiniert hast!
Derek Downey