Como implementar um banco de dados / tabela como uma pilha

11

Eu tenho uma máquina de estado que precisa enviar / enviar alguns nomes de arquivos para diferentes usuários. Tradicionalmente, eu usava pilhas como opção de estrutura de dados, mas isso precisa ser feito usando um banco de dados, pois não tenho como manter a estrutura de dados entre as solicitações da Web recebidas.

Eu queria saber o que seria uma boa maneira de implementar a funcionalidade de pilha usando bancos de dados?

Eu preciso apoiar:

  • push (fileName, user): envia um fileName para o usuário
  • pop (usuário): exibe o nome do arquivo mais alto para o usuário

EDIT :

Estou criando uma ideia para prototipar e, portanto, estou usando o sqlite3 com python.

Obrigado!

brainydexter
fonte
você espera que o mesmo usuário tenha várias conexões simultâneas? que volumes? qual motor Db também por favor?
gbn 23/02
@gbn Eventualmente, o mesmo usuário pode ter conexões simultâneas. Mas, por agora, estou prototipagem uma idéia e eu assumo única conexão por usuário
brainydexter
@brainydexter Gostaria muito de saber o que você está tentando fazer. Tenho a sensação de que você pode estar criando a solução errada para o seu problema. Você pode nos contar seu problema e pedir a melhor maneira de resolvê-lo. Implementar uma pilha como uma tabela de banco de dados parece uma má ideia.
Xenoterracide
@xenoterracide: A intenção geral do que estou tentando fazer no SO: stackoverflow.com/questions/5145051/… A pilha não funcionou completamente, por isso ainda estou procurando uma solução para isso.
28611 brainydexter
1
@brainydexter não está realmente surpreso, o SQL é uma linguagem horrível para implementar uma pilha, porque, por definição relacional, um conjunto não é ordenado, portanto sua pilha não terá ordem e você terá que classificá-la. Talvez parte do seu problema seja dizer às pessoas o que você quer que seja a resposta e perguntar como. Em vez de lhes dizer qual é o problema e perguntar o que. Até a sua pergunta SO leva a resposta a algo específico. Tente pedir a solução em que você não vai pensar.
Xenoterracide

Respostas:

6

Se você está perguntando sobre qual banco de dados usar, isso realmente depende da preferência pessoal e do que você deseja dele. Como eu estou familiarizado apenas com o MySQL, responderei a outra parte da pergunta assumindo o MySQL:

você desejará usá-lo INNODBporque sua tabela precisará de gravação intensiva e, para tabelas grandes, o bloqueio de linhas do INNODB será um salva-vidas MyISAM.

Quanto ao design da tabela, parece que você realmente precisa apenas de uma tabela:

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

Fui com uma coluna 'id' arbitrária definida como AUTO_INCREMENTporque a chave primária é replicada em todas as entradas de todos os índices. Portanto, executar uma chave primária de (usuário, nome do arquivo) pode causar problemas de desempenho se os nomes dos arquivos forem extremamente longos.

O tamanho da coluna 'id' depende do tamanho da sua tabela. Smallint não assinado fornecerá 65k linhas.

Usuário e nomes de arquivos são varchar, porque eles variam drasticamente em tamanho, suponho.

O date_inserté apenas uma maneira de ordenar os resultados com base em quando ela foi inserida (útil para o seu POP)

Derek Downey
fonte
Eu estava pensando em fazer a combinação (id, usuário) como a chave primária, pois gostaria de pressionar ou pop com base no usuário. O que você acha ? Além disso, para a operação POP, não seria melhor encontrar o registro para o usuário com o ID máximo?
23611 brainydexter
O @brainydexter dev.mysql.com/doc/refman/5.0/en/innodb-restrictions.html tem algumas restrições ao incremento automático (ele reutiliza valores de incremento automático 'mais baixos' em certos casos raros). porque é uma possibilidade, eu fui com um campo date_insert. Quanto ao uso (id, usuário) como chave primária, não faz sentido, exceto ocupar mais armazenamento. O ID identifica exclusivamente a linha. apenas 'usuário' por si só não identifica a linha; portanto, você pode ter um índice não exclusivo em 'userID' em vez de um único (usuário, nome do arquivo), se desejar.
Derek Downey
6

Se você estiver considerando um banco de dados Oracle, considere usar o serviço de enfileiramento avançado com um padrão de desenfileiramento LIFO (último a entrar, primeiro a sair) .

No nível mais básico de enfileiramento, um produtor enfileira uma ou mais mensagens em uma fila. Cada mensagem é desenfileirada e processada uma vez por um dos consumidores. Uma mensagem permanece na fila até que um consumidor a desenfileire ou a mensagem expire. Um produtor pode estipular um atraso antes que a mensagem esteja disponível para ser consumida e um período após o qual a mensagem expira. Da mesma forma, um consumidor pode esperar ao tentar desenfileirar uma mensagem se nenhuma mensagem estiver disponível. Um programa ou aplicativo de agente pode atuar tanto como produtor quanto como consumidor.

Leigh Riffel
fonte
configuração clássica de produtor / consumidor. Obrigado pela informação, vou manter isso em mente.
24711 brainydexter
Esperemos que o MySQL vai ter algumas funcionalidades Adance Queue agora que a Oracle "possui" mysql ...
Derek Downey
1
@DTest: é claro, também existe a possibilidade distinta de que agora o mySQL tem menos chances de obter recursos avançados, para que a Oracle possa diferenciar entre software livre e um software pelo qual você deve pagar.
25411 Joe
@ Joe obrigado por estragar meu fim de semana com esse pensamento!
Derek Downey