Mysql
 sql >> Base de données >  >> RDS >> Mysql

PlanetScale &Vitess :intégrité référentielle avec les anciennes bases de données partagées

J'adore la technologie sans serveur. Je joue et crée de nombreuses applications sans serveur différentes pour expérimenter d'autres technologies intéressantes. Au sein de l'immense cluster de technologies que j'utilise/expérimente, PlanetScale était la base de données que j'utilisais principalement pour mes projets parallèles personnels, car il n'y avait pas d'autre "bonne" option prise en charge par Prisma ORM .

PlanetScale est une plate-forme sans serveur MySQL qui vend simplement Vitess, un système de clustering de bases de données pour la mise à l'échelle horizontale de MySQL. Ils n'ont pas écrit leur propre base de données - ils y ont peut-être contribué, mais ils ne l'ont pas écrite. À partir de la documentation Vitess :

Vitess a été créé en 2010 pour résoudre les problèmes d'évolutivité de MySQL auxquels l'équipe de YouTube a été confrontée.

Dans cet article, nous nous efforcerons de comprendre la structure de ces bases de données partitionnées héritées non ACID, pourquoi elles sont incapables de prendre en charge quelque chose d'aussi crucial que l'intégrité référentielle et pourquoi nous devrions éviter de les utiliser dans nos applications. Cet article concerne davantage la technologie de Vitess, bien que j'aie inclus PlanetScale dans le titre car, comme je l'ai mentionné ci-dessus, il ne s'agit que de vendre Vitess (avec quelques outils) en tant que service et ils ont gagné du terrain dans les mois suivants en tant que une base de données sans serveur "fiable".

Contexte

Ma question initiale était pourquoi il est dit qu'il est impossible de mettre à l'échelle une base de données PlanetScale avec une intégrité référentielle, car dans leur documentation, il est indiqué que :

La façon dont FOREIGN KEY contraintes sont implémentées dans MySQL (ou plutôt dans le moteur de stockage InnoDB) interfère avec les opérations DDL en ligne. Apprenez-en plus dans cet article de blog Vitess.

Limité à la portée d'un seul serveur MySQL, FOREIGN KEY les contraintes sont impossibles à maintenir une fois que vos données augmentent et sont réparties sur plusieurs serveurs de base de données. Cela se produit généralement lorsque vous introduisez un partitionnement/sharding fonctionnel et/ou un partitionnement horizontal.

Cela m'a amené à penser :faites FOREIGN KEY contraintes affectent l'évolutivité en général ? et si oui, comment ?

Je pense qu'il est important de réaliser que les jointures de table SQL sont assez coûteuses, mais à ma connaissance, cela n'a pas été beaucoup affecté par l'intégrité référentielle? Maintenant, si nous faisons quelque chose comme l'analyse de données, nous n'avons évidemment pas besoin d'intégrité référentielle car nous voudrions simplement vider nos données dans une seule table, mais PlanetScale et Vitess se vantent d'être utilisés par de grandes applications Web tels que YouTube.

Cela m'a amené à être confus quant à la raison pour laquelle ils laisseraient tomber la FOREIGN KEY contrainte car les bases de données telles que CockroachDB et Spanner conservent toujours l'intégrité référentielle tout en étant évolutives.

Qu'est-ce que l'intégrité référentielle et pourquoi est-elle importante ?

Commençons par les bases, au cas où vous seriez nouveau. Je suppose que la plupart des gens qui lisent ce post ont une bonne idée de ce dont ils parlent, mais je vais expliquer comme une formalité. En termes simples, une FOREIGN KEY la contrainte est une clé de base de données que nous pouvons utiliser pour créer des relations entre deux tables différentes en référençant une colonne ou un ensemble de colonnes. L'intégrité référentielle fait simplement référence à l'état de la base de données dans lequel toutes les valeurs de toutes les clés sont valides.

 Pourquoi est-ce important ?

Maintenant que nous avons une petite idée de ce qu'ils sont, passons à la deuxième partie :pourquoi sont-ils importants ?

L'intégrité référentielle est importante car elle vous empêche d'introduire de nouvelles erreurs dans votre base de données. Il s'agit d'une fonctionnalité souvent fournie par les bases de données relationnelles empêchant les utilisateurs ou les applications d'entrer des données incohérentes dans la base de données. Cela conduit à une meilleure qualité des données, à un développement plus rapide, à beaucoup moins de bogues et à la cohérence de votre application.

Pourquoi Vitess ne l'a-t-il pas ?

Ainsi, pour comprendre pourquoi Vitess n'est pas en mesure de prendre en charge l'intégrité référentielle, nous devons nous plonger dans l'architecture de la base de données. Vitess est une base de données SQL non-ACID partitionnée, et non une véritable base de données ACID SQL distribuée.

Maintenant, vous devez vous demander quels sont ces termes. Laissez-moi vous les détailler :ACID est l'acronyme d'Atomicité, de Cohérence, d'Isolation et de Durabilité.

Ici, l'atomicité fait référence à une action qui se termine ou échoue entièrement - pas d'achèvement partiel d'une transaction. La cohérence fait référence à la transaction laissant la base de données dans un état valide. L'isolation signifie simplement que deux transactions sont exécutées sans aucune interférence l'une avec l'autre, et la durabilité signifie que les modifications de la transaction sont enregistrées.

Une partition est une partition horizontale de données dans une base de données, et chaque partition est conservée sur une instance de serveur de base de données distincte pour répartir la charge. Ainsi, lorsque nous parlons d'une base de données fragmentée, nous parlons de quelque chose comme ça. Maintenant, comme je l'ai dit plus tôt, Vitess est une base de données SQL fragmentée non ACID, ce qui signifie essentiellement qu'elle NE garantit PAS les propriétés ACID des transactions.

Pourquoi le laisser tomber ?

Eh bien, le problème commence lorsque vous avez une base de données MySQL avec un schéma bien défini, et votre service devient populaire avec le problème de trop de lectures frappant la base de données. Ce que la plupart des gens font ici, c'est qu'ils commencent à mettre en cache les requêtes fréquemment exécutées, mais les lectures ne sont plus ACIDiques.

En plus d'un trop grand nombre de lectures, le fait d'avoir un nombre excessif d'écritures dans votre base de données est un problème sérieux auquel beaucoup pourraient être confrontés. Disons que nous sommes prêts à mettre le feu à nos poches - nous pouvons évoluer verticalement, en ajoutant plus de RAM, un processeur à 16 cœurs et des charges de disques SSD très rapides.

Nous avons bien sûr toujours le problème des jointures de tables SQL de plus en plus complexes, vous commencez donc à dénormaliser pour éviter les jointures entre les tables.

J'ai donné une conférence au Prisma Meetup il y a quelque temps, où j'ai expliqué les principes fondamentaux de la conception d'une base de données relationnelle. Un sujet que j'ai abordé ici était la dénormalisation, si vous êtes intéressé, assurez-vous de vérifier cela.

Mais la dénormalisation est essentiellement le processus par lequel vous ajoutez des données redondantes aux tables de votre base de données, ce qui améliore les performances sur le coût de l'espace disque car vous n'utilisez plus la puissance du processeur pour les jointures. Bien que la dénormalisation améliore la vitesse de lecture, il est important de réaliser qu'elle ralentit les écritures.

Néanmoins, malgré tout cela, notre base de données est toujours lente, nous déplaçons donc les calculs de la base de données sur le client, par exemple en générant un UUID ou en attribuant une date.

Même après tout cela, les requêtes seront toujours lentes - nous gardons donc le résultat des données les plus interrogées prêt dans un processus connu sous le nom de matérialisation de la base de données. Maintenant, les lectures peuvent être plus rapides, mais les écritures ralentissent de jour en jour. La seule situation logique maintenant est de supprimer les index secondaires.

Donc, à ce stade, notre base de données a

  • Pas de propriétés ACID en raison de la mise en cache
  • Pas de schéma normalisé
  • Aucun déclencheur
  • Aucun calcul de base de données
  • Aucun index secondaire

Cela a ouvert la voie aux bases de données Vitess et NoSQL, car les entreprises avaient des problèmes pour faire évoluer leur base de données. La façon dont il a été conçu, ils n'étaient pas en mesure de maintenir la cohérence des données, une propriété ACID, lorsque les transactions s'étendaient sur plusieurs fragments différents. L'intégrité référentielle est une question de cohérence lorsque les données s'étendent sur plusieurs partitions, il est donc logique qu'elles ne soient pas en mesure de bien la prendre en charge.

Nous pouvons approfondir la structure des bases de données NoSQL sans FOREIGN KEY contrainte et les problèmes auxquels nous serons confrontés en adoptant ce modèle, mais c'est le sujet d'un autre article.

Ce n'est pas seulement Vitess, c'est une pratique courante pour les bases de données partitionnées d'éviter l'intégrité référentielle car il n'y a tout simplement pas d'autre choix. En ce qui concerne le modèle ACID, leur documentation indique qu'ils garantissent l'atomicité mais pas l'isolement, et vont même jusqu'à dire :

Garantir l'isolement ACID est très controversé et a des coûts élevés. Le fournir par défaut aurait rendu Vitess impraticable pour les cas d'utilisation les plus courants.

Parlons brièvement de ce qu'est ACID Isolation. Il existe quatre niveaux (selon les normes SQL-92), y compris la sérialisabilité, la lecture validée, la lecture non validée et les lectures répétables. Cela étant dit, il existe plus de niveaux d'isolement, tels que l'isolement Snapshot qui n'est pas un standard SQL bien qu'utilisé par plusieurs bases de données telles que Firebase ou MongoDB. Si cela vous intéresse davantage, je vous recommande de lire cet article. Pour être bref, je ne vais pas passer en revue ce que chaque niveau d'isolement fait/signifie, mais si vous souhaitez en savoir plus à ce sujet, consultez cette page de la documentation MySQL.

L'isolation ACID fait référence aux transactions de base de données ACIDic, ce qui est important car elles garantissent que les opérations se comportent comme les développeurs s'y attendent. Je ne suis pas sûr de ce qu'ils veulent dire lorsqu'ils disent "Garantir l'isolement ACID est très controversé et a des coûts élevés", mais s'ils veulent dire que garantir l'isolement ACID a des coûts élevés pour n'importe quel produit , ils ont tort. Plusieurs bases de données distribuées compatibles ACID ont le plus haut niveau d'isolation (transactions sérialisables) tout en restant performantes avec des vitesses de lecture/écriture rapides. Cependant, dans le contexte de Vitess, ils n'ont pas tort car les transactions sur plusieurs fragments ne peuvent atteindre aucun niveau d'isolement.

Conclusion

Avec tout cela, vous devez vous demander :pourquoi quelqu'un voudrait-il utiliser PlanetScale ou Vitess ? Eh bien, je me demande la même chose. Avec de nombreuses entreprises et sites Web, la raison en est qu'ils ont choisi Vitess alors qu'il n'y avait pas de meilleures options. Si vous allez au début de l'article, notez comment il a été créé en 2010. Maintenant que nous pouvons profiter d'une base de données évolutive conforme à ACID avec une intégrité référentielle, il serait dans notre intérêt de passer à ces nouvelles bases de données, et je 'ai déjà commencé à le faire ! La technologie évolue rapidement et la mise à jour de votre base de données est un élément crucial de toute application.