Antipatterns pour travailler avec des bases de données

Bonjour, Habr! Je vous présente la traduction de mon article «Database: Anti-Patterns» .

Si vous stockez des données, il s'agit d'un élément essentiel de votre application. Vous pouvez facilement et rapidement corriger un bug sur un nouveau site de rencontres afin que l'agriculteur Joe du nord du Texas puisse enfin lire le dernier message de son correspondant et découvrir qu'elle aime les hommes chauves. Mais Dieu nous garde de perdre ou de ruiner les données des utilisateurs.

image
Silicon Valley, saison 2, épisode 8 .

Cependant, de nombreux développeurs ne comprennent pas pleinement cette simple vérité. Je ne suis pas programmeur professionnel depuis de nombreuses années, mais j'ai déjà vu beaucoup, beaucoup d'erreurs commises par des personnes travaillant avec la base de données.

Voici juste ceux qui me viennent immédiatement à l'esprit.

Manque de sauvegardes


image

"Faire des sauvegardes" est l'une de ces règles (comme "ne travaillez pas sous la racine" ou "attachez vos ceintures") que beaucoup d'entre nous approuvent mais ne les respectent pas, en espérant que de mauvaises choses arrivent aux autres et pas à nous.

Soit dit en passant, si vous ne testez pas la récupération à partir de sauvegardes, vous pouvez supposer que vous ne disposez d'aucune sauvegarde. Apprenez des erreurs des autres :
En d'autres termes, sur les cinq technologies de sauvegarde, personne ne fonctionne de manière fiable ou n'est pas configuré. Au final, nous avons restauré les données de la sauvegarde effectuée il y a 6 heures.
Nous avons perdu les données de la base de données en 6 heures (problèmes, demandes de fusion, utilisateurs, commentaires, extraits, etc.) avec GitLab.com.

NoSQL


Il arrive que vos utilisateurs aient trop de contenu pour adultes et qu'ils le regardent trop souvent. Le volume de données est trop important ou la charge est trop élevée pour être gérée par la base de données relationnelle. C'est le cas lorsque les technologies NoSQL entrent en jeu. Les géants du logiciel comme Google connaissent bien cette situation.

Mais vous n'êtes pas Google . Quelques centaines de gigaoctets ne sont pas des «mégadonnées», mais 1 000 commentaires par jour ne sont pas des «charges élevées». PostgreSQL est probablement suffisant pour vos données. Voir: il prend même en charge JSON et peut l'indexer .

Allez, voulez-vous sérieusement sacrifier une structure fiable pour des fonctionnalités dont vous n'avez pas besoin et - avouons-le - ne seront jamais nécessaires? Vous ne deviendrez pas le nouveau Google - vous avez juste un gâchis dans la base de données.

Schéma trop lâche


C'est plus pertinent pour NoSQL, mais les utilisateurs de SGBD relationnels oublient souvent ou sont trop paresseux pour créer toutes les restrictions nécessaires. En raison d'une erreur dans le code d'application, il NULLpeut être enregistré là où une valeur significative est attendue, ou un lien vers une entrée manquante peut être créé. Par la suite, vous remarquez cela et corrigez le code, mais vous ne savez pas comment corriger les données.

Clés primaires naturelles


Imaginez que nous voulons stocker des utilisateurs, chacun d'eux devant avoir un e-mail unique. La solution la plus évidente consiste à créer une table useravec une colonne email, qui sera également la clé primaire.

Malheureusement, la clé naturelle peut devenir inacceptable en tant que principale lorsque les exigences changent (et elles changent constamment). Aujourd'hui, cela PRIMARY KEY(email)fonctionne, et demain, nous décidons d'ajouter l'inscription via Facebook et de rendre le courrier électronique facultatif. Quoi de mieux: générer des adresses uniques et ajouter un indicateur indiquant un e-mail fictif, ou changer la clé primaire, toutes les clés étrangères qui se réfèrent à user, etc., etc.? Nous n'aurions pas à choisir le moindre des maux si nous utilisions simplement une clé primaire de substitution.

Logique dans le stockage


Je n'aime pas ça pour deux raisons:

  1. Le code d'application est généralement beaucoup plus facile à mettre à jour qu'un schéma de base de données.
  2. Tous ces PL SQL me rappellent Pascal, et ils sont tout aussi moches.

Scripts de migration spécifiques à l'environnement


Je sais que parfois il n'y a pas de choix, mais en général, il vaut mieux essayer de s'assurer que tous les environnements (dev, test, prod, etc.) sont aussi similaires que possible. Plus la différence entre les environnements est grande, plus il est probable de commettre une erreur et de la trouver uniquement sur la prod.

Habituellement, même les scripts DML peuvent être universels. Différents schémas, le plus souvent, sont du mal pur.

Par conséquent, lorsque je vois des étiquettes spécifiques à l'environnement dans les scripts de base de données, je veux tuer.

Scripts de migration tolérants


IF NOT EXISTSet des choses similaires dans DDL ne sont pas nécessaires si dans tous les environnements des schémas identiques, mais peuvent masquer les erreurs. Si quelque chose d'inattendu se produit pendant la mise à jour de la base de données, je préfère en savoir plus et le réparer le plus tôt possible, plutôt que de me creuser la tête une semaine plus tard, comment réparer le désordre.

Mises à jour non atomiques


Supposons que vous exécutiez l'ensemble de modifications sur une base de production et que la migration n'ait pas réussi. Vous corrigez quelque chose et souhaitez réessayer. Est-ce que ça marchera? Que faire si certaines opérations d'ensemble de modifications sont validées, tandis que d'autres ne le sont pas?

Vous remarquerez peut-être qu'il s'agit en fait d'une histoire dont les changements devraient être idempotents , et vous aurez raison.

Malheureusement, de nombreux développeurs pensent à l'idempotence, à l'utilisation IF NOT EXISTSou à quelque chose comme ça. Dans la section précédente, j'ai expliqué pourquoi c'est mal.

Au lieu de cela, faites un ensemble de modifications atomique . Ensuite, en cas d'erreur, les modifications apportées seront annulées et vous n'aurez aucun problème avec l'application ultérieure de cet ensemble de modifications.

Mais soyez prudent lorsque vous comptez sur des transactions. Par exemple,la prise en charge des expressions DDL dans les transactions MySQL est sombre et pleine d'horreurs , donc je crée toujours un ensemble de modifications distinct pour chaque expression DDL lorsque j'écris des scripts Liquibase pour MySQL.

Quels antipatterns avez-vous vus?

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


All Articles