Muitos aplicativos exigem que os registros em suas tabelas tenham um status, como 'completo', 'rascunho', 'cancelado'. Qual é a melhor maneira de armazenar esses status? Para ilustrar o que estou chegando aqui, é um exemplo * muito curto).
Eu tenho um aplicativo de blog simples e cada post tem um status: publicado, rascunho ou pendente.
Do jeito que eu vejo, existem 2 maneiras de modelar isso no banco de dados.
- A tabela Postagem possui um campo de texto que inclui o texto de status.
- A tabela Post tem um campo de status que contém o ID de um registro na tabela PostStatus
O exemplo do Blog aqui é um exemplo muito simples. Onde uma enumeração (se suportada) pode ser suficiente. No entanto, gostaria que as respostas à pergunta levassem em conta que a lista de status pode mudar a qualquer momento, para que mais possam ser adicionadas ou removidas.
Alguém pode explicar as vantagens / desvantagens de cada um?
Felicidades!
Minha opinião inicial é que é melhor usar outra tabela e procurar o status como melhor para a normalização. Sempre fui ensinado que a normalização é boa para bancos de dados
fonte
Respostas:
Armazenar o status como um índice em outra tabela é uma complicação desnecessária. Armazene o status diretamente na tabela de maneira legível. No código do aplicativo, use constantes ou um tipo de enumeração. Isso resultará em um código de aplicativo mais simples e facilitará a depuração da camada de dados.
Isso não desnormaliza os dados, apenas altera a representação. Se o banco de dados suportar enumerações diretamente, use isso. Caso contrário, use uma restrição para restringir os valores da coluna. Você terá uma restrição de qualquer maneira: uma restrição direta nos valores da coluna ou uma restrição de chave estrangeira.
Sim, pode ser necessário apresentar o status de maneira diferente para diferentes usuários. Esse é um problema de apresentação, a ser resolvido na camada de apresentação, não na camada de persistência.
fonte
Armazenar o texto de status não é uma boa idéia da IMO, pois alguém pode decidir que "completo" deve ser chamado de "concluído" e, em seguida, você deve atualizar seu banco de dados, examinar o programa se alguém codificou o texto etc.
O que vi em muitos programas é um código numérico (1 = novo, 2 = rascunho, 3 = em validação, 4 = completo, 99 = cancelado) ou um código alfanumérico curto ("NEW", "DRA", "INV "," COM "," CAN "). O posterior torna o código (no programa ou no banco de dados) mais legível por humanos, o que geralmente é uma coisa boa. Por outro lado, os códigos numéricos facilitam a comparação "maior que" ou "menor que", por exemplo
fonte
status.draft=Draught
As três regras dos bancos de dados relacionais:
Portanto, sua pergunta responde a si mesma. Mantenha o status dentro de sua própria tabela e use GUID / UUIDs como seu ID . Os GUIDS indexados são muito rápidos e corrigem os problemas intrínsecos ao aumento de números. Com um ID, você pode fazer coisas legais, como solicitar ao DB todas as postagens concluídas usando o ID e, como você está trabalhando dentro do paradigma relacional do banco de dados, é muito rápido. Se você tiver apenas um campo, o banco de dados precisará percorrer todas as linhas e fazer uma comparação de texto, talvez com munging, e isso é muito lento.
Os nomes dos status das postagens podem mudar, mais informações sobre o status das postagens podem ser exibidas na tabela, tudo funciona se você normalizar .
Por exemplo, você pode adicionar níveis de status como informações adicionais, o que permitiria a comparação mencionada pela munição. Mas eles não dependem da chave para o posicionamento, permitindo a reorganização do nível de status sem prejudicar a integridade do banco de dados. Você também pode inserir níveis adicionais, o que é um truque se você tiver o nível associado à chave de incremento automático.
fonte
Sim, você deve ir com a opção 2, com uma tabela PostStatus.
Além de todas as vantagens mencionadas em outras respostas.
Tendo em mente que os status precisam ser adicionados ou removidos, você pode ter uma coluna "ativado" na tabela PostStatus; portanto, se o status for removido, marque a coluna "ativado" como "N", para que você possa adicione ou remova status e também os registros existentes permanecerão sem problemas.
fonte
Eu gostaria de acrescentar às respostas perspicazes que, para normalização total, uma alteração no status de uma entidade é modelada em uma entidade separada, por exemplo, denominada 'statusChange'.
Você precisaria de uma associação extra com a entidade statusChange, mas terá a possibilidade de adicionar informações extras, como o ator que está realizando a alteração, possíveis comentários sobre o motivo da alteração e uma data na qual a statusChange é executada e, possivelmente, mesmo quando torna-se eficaz.
fonte
Usar texto para status na tabela de registros provavelmente não seria uma boa ideia, pois isso pode mudar e seria difícil executar qualquer verificação de integridade dos dados ao inserir / atualizar. Se você estiver utilizando um DBMS com um tipo de dados enum, poderá usá-lo (o desempenho provavelmente não será comprometido ... dependendo).
Se o seu status precisar de metadados (descrição, criada por, nome amigável, ...), será necessário armazenar os status em uma tabela separada e ter uma chave de status na sua tabela de registros (certifique-se de usar uma chave estrangeira). O ID não precisa necessariamente ser um número, apenas o PK da tabela de status. Além disso, se os status estiverem em sua própria tabela, você poderá compartilhá-los entre os tipos de registro (tabelas), se aplicável. Eu não me preocuparia com problemas de desempenho com um JOIN na tabela de status.
Faça o que fizer, evite status mágicos (1 para ativo, 2 para excluído, ...). Isso depende de documentação e tradição, que sempre tendem a se perder em uma linha do tempo suficientemente grande. Se você estiver usando IDs numéricos, verifique se há uma associação textual em algum lugar do seu banco de dados.
fonte
Depende do objetivo do design do banco de dados.
Se você projetar o banco de dados simplesmente para suportar o aplicativo (ou seja, os objetos (código) são os principais de todos), usar uma enumeração (ou uma enumeração psuedo para classes que não as suportam) e armazenar o nome da enumeração é um boa idéia, porque você ainda controla os valores permitidos através da enum e também facilita a leitura da tabela quando é forçado a visualizar os dados brutos (o que não ocorre com frequência se o código realmente governa tudo). Mas se a enumeração estiver sinalizada. Então eu costumo armazenar o valor de enumeração (inteiro).
fonte
O status é muito importante: sempre que você obtiver informações sobre postagens, será necessário obtê-lo ou filtrará as postagens por status. Se você tiver status em outra tabela, precisará fazer junções para obter essas informações e, portanto, o desempenho será comprometido. Definitivamente você deve ter status na mesma tabela. E coloque um índice nele! Você ainda pode usar números inteiros como status ou, talvez, campo enum.
fonte
A solução correta é usar um armazenamento / fonte de eventos com CQRS ou uma blockchain. O problema com a captura de eventos em um RDB é que o RDB armazena uma captura instantânea de um único evento no tempo, e coisas como "Status / Estados" são sequências de mutações que evoluem ao longo do tempo
fonte