Eu estou olhando para armazenar uma lista classificada dentro de um banco de dados. Quero executar as seguintes operações com eficiência.
- Inserir (x) - Insere o registro x na tabela
- Excluir (x) - exclui o registro x da tabela
- Antes (x, n) - Retorne os registros 'n' que precedem o registro x na lista classificada.
- Depois (x, n) - Retorna os registros 'n' que sucedem o registro x na lista classificada.
- Primeiro (n) - Retorna os primeiros registros 'n' da lista classificada.
- Last (n) - Retorna os últimos registros 'n' da lista classificada.
- Compare (x, y) - Dados dois registros xey da tabela, encontre se x> y.
O método simples em que pude pensar é armazenar algum tipo de atributo 'rank' na tabela e consultar, classificando esse atributo. Porém, nesse método, inserir / modificar um registro com uma classificação torna-se uma operação cara. Há um método melhor?
Especificamente, estou procurando implementar a tabela usando o SimpleDB da Amazon. Mas uma resposta geral para um banco de dados relacional também deve ser útil.
Atualização no perfil de carregamento:
Como estou planejando isso para um aplicativo Web, isso depende do número de usuários que usam o aplicativo.
Se houver 100 mil usuários ativos (super otimismo: P), minha estimativa aproximada por dia será
500k seleciona, 100k insere e exclui, 500k atualizações
Eu esperava que a tabela crescesse até 500k no total.
Estou procurando otimizar as atualizações, inserir e comparar as operações. A classificação dos itens mudará constantemente e eu preciso manter a tabela atualizada.
fonte
Respostas:
Se a classificação não for completamente arbitrária, mas derivar de alguma outra propriedade (por exemplo, nome, pontuação do jogador etc.), dê uma boa olhada na resposta de Joel .
Se for uma propriedade arbitrária dos seus dados, ela deverá ser armazenada como uma coluna na sua tabela de registros. Supondo que o SimpleDB da Amazon seja semelhante ao RDBMS típico, você poderá indexar esta coluna e satisfazer rapidamente todas as suas consultas acima com a estratégia de indexação apropriada. Isso é normal para um RDBMS.
Como você espera alta atividade de inserção e atualização, mas também uma atividade de leitura relativamente alta, recomendo fazer o seguinte:
INCLUDE
classificação de registro e classificação, ou apenas o registro se você tiver agrupado na classificação) atenderiam à consulta 7.FILLFACTOR
no SQL Server). Isso é especialmente importante se você agrupar na classificação.Se você espera 100K + lê em uma tabela de tamanho 100K +, não recomendo usar a abordagem de lista vinculada. Não será bem dimensionado para esses tamanhos.
fonte
FILLFACTOR
, verá que o objetivo principal é criar esse espaço extra para registros em um índice, assim como as diferenças de classificação que descrevi criam espaço para alterações e inserções de classificação.Eu geralmente uso o método "rank" que você descreve. Em vez de mexer nas linhas de atualização quando os itens precisavam ser reordenados, muitas vezes consegui excluir todos os registros da lista e reinserir novos itens na ordem correta. Este método é claramente otimizado para recuperação.
Uma abordagem alternativa seria modelar os registros como uma lista vinculada usando uma coluna de chave estrangeira reflexiva "predecessora" na tabela:
Você pode recuperar facilmente uma lista e adicionar e remover itens com pouca sobrecarga, mas obter os registros na ordem correta será complicado. Talvez haja uma maneira inteligente de fazer isso em uma única consulta, provavelmente com muitas junções de tabelas com alias.
Uso essa última abordagem frequentemente quando estou modelando um relacionamento no estilo de árvore (categorias, pastas, conjuntos e subconjuntos). Eu geralmente tive uma função recursiva de algum tipo para reconstruir a árvore completa no meu aplicativo.
fonte
Eu acho que a coisa a fazer é armazenar a propriedade ou propriedades que são usadas para calcular a classificação e criar um índice sobre elas. Em vez de tentar forçar o banco de dados a armazenar fisicamente os dados na ordem de classificação ou usar uma lista vinculada gerenciada manualmente, por que não deixar o mecanismo de banco de dados fazer o que foi projetado?
fonte
Essas são as limitações de um não-RDBMS como o simpleDB. Os recursos que você precisa não podem ser implementados no lado do DB no simpleDB, eles precisam ser implementados no lado / aplicativo de programação.
Para um RDBMS como
SQL server
, os recursos necessários são rudimentares para o índice em cluster.Antes (x, n) - Retorne os registros 'n' que precedem o registro x na lista classificada. > Selecione os n principais resultados em que x seja menor que o valor e classifique por cláusula.
Depois (x, n) - Retorna os registros 'n' que sucedem o registro x na lista classificada. > Selecione os n principais resultados em que x é maior que o valor e ordena por cláusula.
Primeiro (n) - Retorna os primeiros registros 'n' da lista classificada. > Selecione os n principais resultados.
Last (n) - Retorna os últimos registros 'n' da lista classificada. > Selecione os melhores resultados após a ordem, por desc.
fonte
Aqui está o que eu costumava classificar novamente minha tabela do Postgres após cada inserção:
Para o meu caso de uso, o desempenho não é uma preocupação, mas a confiança de que nunca irá quebrar ou agir de maneira estranha é importante.
fonte