Come posso implementare un database / tabella come stack


11

Ho una macchina a stati che ha bisogno di spingere / pop alcuni nomi di file per diversi utenti. Tradizionalmente userei gli stack come scelta della struttura dei dati, ma questo deve essere fatto usando un database poiché non ho un modo per conservare la struttura dei dati tra le richieste web in arrivo.

Mi chiedevo quale sarebbe stato un buon modo per implementare la funzionalità dello stack usando i database?

Devo supportare:

  • push (nome file, utente): invia un nome file per l'utente
  • pop (utente): pop il fileName più in alto per l'utente

MODIFICA :

Sto prototipando un'idea e quindi sto usando sqlite3 con Python.

Grazie!


ti aspetti che lo stesso utente abbia più connessioni simultanee? quali volumi? quale motore Db anche per favore?
gbn

@gbn Alla fine lo stesso utente potrebbe avere connessioni simultanee. Ma per ora, sto prototipando un'idea e presumo una singola connessione per utente
brainydexter,

@brainydexter Mi piacerebbe molto sapere cosa stai cercando di fare. Ho la sensazione che tu stia creando la soluzione sbagliata al tuo problema. Potresti prendere in considerazione la possibilità di raccontarci il tuo problema e chiedere alla strada migliore per risolverlo. L'implementazione di uno stack come tabella di database sembra una cattiva idea.
xenoterracide,

@xenoterracide: l'intento generale di ciò che sto cercando di fare su SO: stackoverflow.com/questions/5145051/… Lo stack non ha funzionato completamente, quindi sto ancora cercando una soluzione a questo.
brainydexter,

1
@brainydexter non è davvero sorpreso, SQL è un linguaggio orribile per implementare uno stack, perché per definizione relazionale un set non è ordinato, quindi il tuo stack non avrà alcun ordine e dovresti ordinarlo. Forse parte del tuo problema è che stai dicendo alla gente quale vuoi che sia la risposta e stai chiedendo come. Invece di dire loro qual è il problema e chiedere cosa. Anche la tua domanda SO porta la risposta a qualcosa di specifico. Prova a chiedere la soluzione che non ti verrà in mente.
xenoterracide

Risposte:


6

Se stai chiedendo quale database utilizzare, dipende davvero dalle preferenze personali e da cosa desideri. Poiché ho familiarità con MySQL, risponderò all'altra parte della domanda assumendo MySQL:

vorrai utilizzarlo INNODBperché la tua tabella sarà ad alta intensità di scrittura e per le tabelle di grandi dimensioni, il blocco delle righe di INNODB ti farà risparmiare la vita MyISAM.

Per quanto riguarda il design dei tavoli, sembra che tu abbia davvero bisogno di un solo tavolo:

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

Sono andato con una colonna 'id' arbitraria impostata su AUTO_INCREMENTperché la chiave primaria è replicata in ogni voce di ogni indice. Pertanto, eseguire una chiave primaria di (utente, nome file) potrebbe causare problemi di prestazioni se i nomi dei file sono estremamente lunghi.

La dimensione della colonna "id" dipende dalla dimensione della tabella. Smallint non firmato ti darà 65.000 righe.

L'utente e il nome del file sono varchar, perché varieranno drasticamente in lunghezza.

Il date_insertè solo un modo per ordinare i risultati in base a quando è stato inserito (utile per il vostro POP)


Stavo pensando di creare una combinazione (id, utente) come chiave primaria, poiché mi piacerebbe spingere o pop in base all'utente. Cosa ne pensi ? Inoltre, per l'operazione POP, non sarebbe meglio trovare il record per l'utente con il massimo ID?
brainydexter,

@brainydexter dev.mysql.com/doc/refman/5.0/en/innodb-rest restrizioni.html ha alcune restrizioni sull'autoincremento (riutilizzerà i valori di autoincremento "inferiore" in alcuni rari casi). perché è una possibilità che ho scelto un campo date_insert. Per quanto riguarda l'utilizzo (id, utente) come chiave primaria, non ha senso se non occupare più spazio di archiviazione. ID identifica in modo univoco la riga. solo 'user' da solo non identifica la riga, quindi potresti avere un indice non univoco su 'userID' invece di un unico (utente, nome file) se vuoi.
Derek Downey,

6

Se stai considerando un database Oracle, dovresti prendere in considerazione l'utilizzo di Accodamento avanzato con un modello di dequeue LIFO (last in first out) .

Al livello base di accodamento, un produttore accoda uno o più messaggi in una coda. Ogni messaggio viene rimescolato ed elaborato una volta da uno dei consumatori. Un messaggio rimane nella coda fino a quando un consumatore non lo dequefa o il messaggio scade. Un produttore può prevedere un ritardo prima che il messaggio sia disponibile per essere consumato e un tempo dopo il quale il messaggio scade. Allo stesso modo, un consumatore può attendere quando tenta di dequeue un messaggio se non è disponibile alcun messaggio. Un programma o un'applicazione agente può agire sia come produttore che come consumatore.


installazione classica produttore / consumatore. Grazie per le informazioni, lo terrò a mente.
brainydexter,

Spero che MySQL abbia alcune funzionalità di Adance Queue ora che Oracle "possiede" mysql ...
Derek Downey,

1
@DTest: ovviamente, c'è anche la netta possibilità che mySQL abbia ora meno probabilità di ottenere funzionalità avanzate, quindi Oracle può distinguere tra software libero e uno da pagare.
Joe,

@Joe grazie per aver rovinato il mio fine settimana con quel pensiero!
Derek Downey,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.