O requisito é: Os usuários devem ser capazes de definir a estrutura do documento que desejam armazenar.
Por exemplo, um usuário pode decidir armazenar um extrato bancário com a seguinte estrutura:
- data_post (data)
- detalhes (texto)
- débito (número)
- crédito (número)
- data_valor (data)
- referência (texto)
em seguida, selecione um arquivo para carregar no banco de dados.
Outro usuário ou o mesmo usuário também pode carregar um documento diferente com uma estrutura diferente.
Se conhecermos todas as diferentes estruturas de documentos disponíveis, podemos criar todas as tabelas do banco de dados, mas o sistema deve ser tal que o usuário possa carregar qualquer tipo de documento, e definir suas próprias estruturas.
Estou procurando uma maneira de salvar todas as linhas dos documentos em uma única tabela, se possível. Ou devo criar dinamicamente uma nova tabela quando o usuário definir uma nova estrutura de documento para carregar? É este o melhor caminho?
Nenhum. Não há design de banco de dados para o que você descreve. Dizer que ele precisa ser capaz de armazenar tudo e qualquer coisa significa que não há como estruturá-lo.
Opções
O que você pode fazer é criar dinamicamente a tabela com base na definição do documento fornecida pelo usuário. Você solicitaria os nomes e tipos de cada coluna do documento. Então você pode gerar uma
CREATE TABLE
instrução (em qualquer linguagem de programação de sua escolha) que crie essa tabela como parte do processo. Provavelmente seria melhor ter umaUserTables
tabela de mapeamento interna para armazenar a chave do usuário e o nome das tabelas que eles criaram, para que você possa referenciar facilmente essa lista no aplicativo. Dependendo do sistema de banco de dados, você pode utilizar esquemas para segregar usuários em seus próprios esquemas. Isso melhoraria a organização e o controle de segurança.Alternativamente, você pode tentar usar o antipadrão EAV . Nesse design, uma única tabela normalmente possui 3 colunas: a chave da entidade (modelo/o que seria tabela), o nome do atributo (nome da coluna), o valor (desse atributo/coluna). Embora atraente à primeira vista e atenda à sua ideia de armazenar tudo em uma única tabela, há muitas desvantagens em usar esse antipadrão. Algumas das desvantagens incluem a perda dos tipos de dados, a perda da aplicação da integridade dos dados, a falta de aplicação do relacionamento, a baixa escalabilidade e o baixo desempenho da consulta, etc. Existem poucos cenários em que o EAV faz sentido e, mesmo no seu caso, eu diria que a opção 1 é a melhor escolha.
Armazene-os como XML ou JSON. (Seja isso significa usar a coluna XML/JSON/NVARCHAR no banco de dados SQL ou usar a solução NoSQL.)
É claro que isso tornará a consulta pelo conteúdo do documento um tanto complicada. Mas se for simplesmente uma maneira de despejar seus dados e recuperá-los, esta seria uma solução válida.
Se você precisar trabalhar extensivamente com o conteúdo dos documentos, isso pode não ser uma boa ideia.