Antipadrões para trabalhar com bancos de dados

Olá Habr! Apresento a você a tradução do meu artigo “Database: Anti-Patterns” .

Se você armazenar dados, essa é uma parte crítica do seu aplicativo. Você pode facilmente e rapidamente corrigir uma correção de bug em um novo site de namoro, para que o fazendeiro Joe, do norte do Texas, possa finalmente ler a última mensagem de seu amigo e descobrir que ela gosta de homens carecas. Mas Deus não permita que você perca ou estrague os dados do usuário.

imagem
Vale do Silício, Temporada 2, Episódio 8 .

No entanto, muitos desenvolvedores não entendem completamente essa verdade simples. Não sou programador profissional há muitos anos, mas já vi muitos, muitos erros cometidos por pessoas que trabalham com o banco de dados.

Aqui estão apenas aqueles que vêm à mente imediatamente.

Falta de backups


imagem

"Fazer backups" é uma dessas regras (como "não trabalhe na raiz" ou "aperte os cintos de segurança") com as quais muitos de nós concordam, mas não os seguem, esperando que coisas ruins aconteçam aos outros e não a nós.

A propósito, se você não está testando a recuperação de backups, pode assumir que não possui nenhum backup. Aprenda com os erros dos outros :
Em outras palavras, das cinco tecnologias de backup, ninguém trabalha de maneira confiável ou não está configurado. No final, restauramos os dados do backup feito 6 horas atrás.
Perdemos os dados do banco de dados em 6 horas (problemas, solicitações de mesclagem, usuários, comentários, trechos etc.) com o GitLab.com.

NoSQL


Os usuários têm muito conteúdo adulto e o assistem com muita frequência.A quantidade de dados é muito grande ou a carga é alta demais para o banco de dados relacional. Este é o caso quando as tecnologias NoSQL entram em jogo. Gigantes de software como o Google estão familiarizados com isso em primeira mão.

Mas você não é o Google . Algumas centenas de gigabytes não são "big data", mas 1000 comentários por dia não são "alta carga". Provavelmente o PostgreSQL é suficiente para seus dados. Veja: ele suporta JSON e pode indexá-lo .

Vamos, você quer mesmo sacrificar uma estrutura confiável por recursos que você não precisa e, convenhamos, nunca será necessário? Você não se tornará o novo Google - você apenas tem uma bagunça no banco de dados.

Esquema muito frouxo


Isso é mais relevante para o NoSQL, mas os usuários de DBMSs relacionais geralmente esquecem ou têm preguiça de criar todas as restrições necessárias. Devido a um erro no código do aplicativo, ele NULLpode ser salvo onde um valor significativo é esperado ou um link para uma entrada ausente pode ser criado. Posteriormente, você percebe isso e corrige o código, mas não tem idéia de como corrigir os dados.

Chaves primárias naturais


Imagine que queremos armazenar usuários, cada um dos quais deve ter um email exclusivo. A solução mais óbvia é criar uma tabela usercom uma coluna email, que também será a chave primária.

Infelizmente, a chave natural pode se tornar inaceitável como primária quando os requisitos mudam (e eles mudam constantemente). Hoje PRIMARY KEY(email)funciona e amanhã decidimos adicionar o registro via Facebook e tornar o e-mail opcional. Qual é o melhor: gerar endereços exclusivos e adicionar um sinalizador indicando um e-mail fictício ou alterar a chave primária, todas as chaves estrangeiras que se referem a useretc., etc.? Não teríamos que escolher o menor dos males se simplesmente usássemos uma chave primária substituta.

Lógica no armazenamento


Não gosto disso por dois motivos:

  1. O código do aplicativo geralmente é muito mais fácil de atualizar do que um esquema de banco de dados.
  2. Todos esses SQL PLs me lembram Pascal, e são igualmente feios.

Scripts de migração específicos do ambiente


Sei que às vezes não há escolha, mas, em geral, é melhor tentar garantir que todos os ambientes (dev, test, prod, etc.) sejam os mais semelhantes possíveis. Quanto maior a diferença entre os ambientes, maior a probabilidade de cometer um erro e encontrá-lo apenas no produto.

Geralmente, mesmo os scripts DML podem ser universais. Esquemas diferentes, na maioria das vezes, são pura maldade.

Portanto, quando vejo rótulos específicos do ambiente nos scripts liquibase, quero matar.

Scripts de migração tolerante


IF NOT EXISTSe coisas semelhantes no DDL não são necessárias se em todos os ambientes esquemas idênticos, mas podem mascarar erros. Se algo inesperado acontecer durante a atualização do banco de dados, eu prefiro descobrir e corrigi-lo o mais rápido possível, em vez de quebrar a cabeça uma semana depois, como consertar a bagunça.

Atualizações não atômicas


Suponha que você execute o changeset em uma base de produção e a migração não tenha sido bem-sucedida. Você está consertando algo e deseja tentar novamente. será que vai dar certo? E se algumas operações de conjunto de alterações forem confirmadas, enquanto outras não?

Você pode perceber que essa é realmente uma história que o changeset deve ser idempotente e você estará certo.

Infelizmente, muitos desenvolvedores, pensando em idempotência, usam IF NOT EXISTSou algo assim. Na seção anterior, expliquei por que isso é ruim.

Em vez disso, torne o conjunto de alterações atômico . Em caso de erro, as alterações feitas serão revertidas e você não terá problemas com o aplicativo subsequente deste conjunto de alterações.

Mas tenha cuidado ao contar com transações. Por exemplo,o suporte para expressões DDL nas transações do MySQL é sombrio e cheio de horrores ; portanto, sempre crio um conjunto de alterações separado para cada expressão DDL quando escrevo scripts Liquibase para MySQL.

Quais antipadrões você já viu?

Source: https://habr.com/ru/post/undefined/


All Articles