Melhor maneira (livre) para armazenar dados? Como cerca de atualizações para o sistema de arquivos?

StackOverflow https://stackoverflow.com/questions/142114

  •  02-07-2019
  •  | 
  •  

Pergunta

Eu tenho uma idéia de como resolver este problema, mas eu queria saber se há algo mais fácil e mais extensível para o meu problema.

O programa que estou trabalhando tem duas formas básicas de dados: imagens e as informações associadas a essas imagens. A informação associada com as imagens previamente armazenadas em um banco de dados JET de extrema simplicidade (quatro mesas), que acabou por ser lenta e incompleta nos campos armazenados. Estamos nos movendo para uma nova implementação do armazenamento de dados. Dada a simplicidade das estruturas de dados envolvidas, eu estava pensando que um banco de dados foi um exagero.

Cada imagem terá informações de seu próprio (parâmetros de captura), fará parte de um grupo de imagens que estão inter-relacionados (retirado no mesmo período 30 minutos, por exemplo) e, em seguida, parte de um grupo maior por completo (tomada de a mesma pessoa). Agora, eu estou armazenando as pessoas em um dicionário com um identificador único. Cada pessoa tem então uma lista dos diferentes grupos de fotos, e cada grupo de imagem tem uma lista de fotos. Todas essas classes são serializado, e eu estou apenas serialização e desserialização do dicionário. coisas bastante simples. As imagens são armazenadas separadamente, de modo que o dicionário não se torne astronômico em tamanho.

O problema é: o que acontece quando eu preciso adicionar novos campos de informação? Existe uma maneira fácil de configurar essas estruturas de dados para contabilizar potenciais futuras revisões? No passado, a maneira eu lidar com este em C era criar uma estrutura seriável com lotes de bytes vazios (pelo menos um k) para futura expansão, com um dos bytes na estrutura indicando a versão. Então, quando o programa ler a struct, ele saberia que desserialização usar com base em uma instrução switch enorme (e versões antigas podia ler novos dados, porque os dados irrelevantes só iria entrar em campos que são ignorados).

O tal exist esquema em C #? Como, se eu tiver uma classe que é um grupo de Cordas e Int objetos, e então eu adicionar outro objeto String para a estrutura, como posso desserializar um objeto a partir do disco, e em seguida, adicione a string a ele? Preciso me resignar a ter várias versões das classes de dados, e uma fábrica que tem um fluxo de desserialização e alças Deserialization baseado em algumas informações versão armazenada em uma classe base? Ou é uma classe como dicionário ideal para armazenar este tipo de informação, uma vez que irá desserializar todos os campos no disco automaticamente, e se existem novos campos adicionados, eu só posso capturar exceções e substituto em branco Cordas e Ints para esses valores?

Se eu ir com a abordagem dicionário, é lá uma velocidade hit associado com arquivo de leitura / escrita, bem como tempos de recuperação parâmetro? I figura que se há apenas campos de uma classe, então a recuperação campo é instantânea, mas em um dicionário, há alguma pequena sobrecarga associada a essa classe.

Obrigado!

Foi útil?

Solução

Meu cérebro está frito no momento, então eu não tenho certeza que eu posso aconselhar a favor ou contra um banco de dados, mas se você está procurando para serialização versão agnóstica, você seria um tolo para não pelo menos verificação em Protocol Buffers .

Aqui está uma lista rápida de implementações que eu sei sobre para C # / NET:.

Outras dicas

Sqlite é o que você quer. É um rápido, banco de dados embutido, de arquivo único que tem ligações para a maioria dos idiomas.

Com relação à capacidade de extensão, você pode armazenar seus modelos com atributos padrão, e depois ter uma tabela separada para extensões de atributo para mudanças futuras.

Um ou dois anos abaixo da estrada, se o código ainda está em uso, você vai ser feliz que 1) Outros desenvolvedores não terão que aprender uma estrutura de código personalizado para manter o código, 2) Você pode exportar, vista, modificar os dados com ferramentas de banco de dados padrão (há um driver ODBC para arquivos de SQLite e várias ferramentas de consulta), e 3) você vai ser capaz de escalar até um banco de dados com alterações de código mínimo.

Apenas uma palavra pequenino de aviso, SQLLite, Protocol Buffers, mmap et al ... tudo muito bom, mas você deve protótipo e testar cada aplicação e certifique-se de que o seu não vai bater as mesmas questões perf ou diferentes pontos de estrangulamento.

A simplicidade pode ser apenas para converter para o SQL (Express) (você pode ser surpreendido com o ganho perf) e corrigir o que está faltando a partir do design de banco de dados atual. Então, se perf é ainda um problema começar a investigar essas outras tecnologias.

Há um esquema de banco de dados, para o qual eu não me lembro o nome, que pode lidar com esse tipo de situação. Você tem basicamente duas tabelas. Uma tabela armazena o nome da variável, e as outras lojas o valor da variável. Se você deseja agrupar as variáveis, em seguida, adicionar uma terceira tabela que terá uma relação um para muitos com a tabela de nome da variável. Esta configuração tem a vantagem de permitir que você continuar a adicionar variáveis ??diferentes sem ter que ficar mudando o esquema do banco de dados. Salvou meu bacon algumas vezes quando se lida com os departamentos que mudam sua mente com freqüência (como Marketing).

O único inconveniente é que a tabela valor da variável será necessário armazenar o valor real como uma coluna string (varchar ou nvarchar na verdade). Então você tem que lidar com o incômodo de converter os valores de volta para suas representações nativas. Eu atualmente manter algo como isto. A tabela variável tem atualmente cerca de 800 milhões de linhas. Ainda é bastante rápido, como eu ainda pode recuperar certas variações de valores em menos de um segundo.

Eu não sou programador C #, mas eu como a chamada mmap () e serra há um projeto de fazer tal coisa um para C #.

MMAP

arquivos estruturados são muito realização se adaptados para uma aplicação específica, mas são difíceis de gerir e um recurso de código dificilmente reutilizáveis. Uma solução melhor é uma memória de como o Virtual implementação.

  • Até 4 gigabyte de informação pode ser gerenciado.
  • O espaço pode ser otimizada para o tamanho de dados real.
  • Todos os dados podem ser vistos como uma única matriz e acessado com operações de leitura / escrita.
  • Sem necessidade de estrutura para loja, mas o uso justo e loja.
  • Pode ser armazenado em cache. É altamente reutilizáveis.

Então, vá com SqlLite pelas seguintes razões:
1. Você não precisa ler / escrever todo o banco de dados a partir do disco de cada vez
2. Muito mais fácil para adicionar ao mesmo se você não deixar espaços reservados suficientes no início
3. Mais fácil de pesquisa com base em tudo o que quiser
4. mais fácil de alterar os dados de formas para além da aplicação foi concebido

Problemas com Dicionário abordagem
1. A menos que você fez um dicionário inteligente que você precisa ler / escrever todo o banco de dados de cada vez (a menos que você projetar cuidadosamente a estrutura de dados será muito difícil manter a compatibilidade)
----- a) se você não deixou coloque suportes suficientes bye bye
2. Parece que você tem que busca linear através de todas as fotos em ordem de pesquisa em uma das Captura Atributos
3. Pode uma imagem estar em mais de um grupo? Pode uma imagem estar sob mais de uma pessoa? Duas pessoas podem estar no mesmo grupo? Com dicionários estas coisas podem se complicar ....

Com uma tabela de banco de dados, se você receber um novo atributo você pode apenas dizer Alter Table Imagem Adicionar atributo DataType. Então, enquanto você não fazer uma regra dizendo que o atributo deve ter um valor, você ainda pode carregar e salvar versões mais antigas. Ao mesmo tempo, as versões mais recentes podem usar os novos atributos.

Além disso, você não precisa salvar a imagem no banco de dados. Você pode apenas armazenar o caminho para a imagem no banco de dados. Então, quando o aplicativo precisa da imagem, basta carregá-lo a partir de um arquivo de disco. Isso mantém o tamanho do banco de dados menor. Também o extra de tempo de busca para obter o arquivo de disco provavelmente será insignificante em comparação com o tempo para carregar a imagem.

Provavelmente a sua tabela deve ser
Imagem (PictureID, GroupID ?, Caminho do arquivo, captura de parâmetro 1, Captura de parâmetros 2, etc ..)

Se você quiser mais flexibilidade que você poderia fazer uma tabela CaptureParameter (PictureID, ParameterName, ParameterValue) ... gostaria de aconselhar contra isso, porque é muito menos eficiente do que apenas colocá-los em uma tabela (para não mencionar as consultas para recuperar / procurar os parâmetros de captura seria mais complicado).

Pessoa (PersonID, Qualquer Pessoa atributos como Nome / etc.)
Group (GroupID, nome do grupo, PersonID?)
PersonGroup? (PersonID, GroupID)
PictureGroup? (GroupID, PictureID)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top