Jag älskar serverlös teknik. Jag leker och gör massor av olika serverlösa applikationer för att experimentera med annan cool teknik. Inom det enorma kluster av teknologier jag använder/experimenterar med, var PlanetScale databasen som jag främst använde för mina personliga sidoprojekt, eftersom det inte fanns något annat "bra" alternativ som Prisma ORM stödde .
PlanetScale är en MySQL-serverlös plattform som helt enkelt säljer Vitess, ett databasklustersystem för horisontell skalning av MySQL. De skrev ingen egen databas – möjligen bidragit till den, men de skrev den inte. Från Vitess dokumentation:
Vitess skapades 2010 för att lösa MySQL-skalbarhetsutmaningarna som teamet på YouTube stod inför.
I den här artikeln kommer vi att gå mot att förstå strukturen för dessa icke-ACID-legacy sharded-databaser, varför de inte kan stödja något så avgörande som referensintegritet, och varför vi bör undvika att använda dem i våra applikationer. Den här artikeln handlar mer om Vitess teknologi, även om jag har tagit med PlanetScale i titeln eftersom det, som jag nämnde ovan, bara säljer Vitess (med lite verktyg) som en tjänst och de har fått dragkraft under de följande månaderna som varande en "pålitlig" serverlös databas.
Bakgrund
Min första fråga var varför det står att det är omöjligt att skala en PlanetScale-databas med referensintegritet eftersom det i deras dokumentation står att:
Sättet
FOREIGN KEY
begränsningar är implementerade i MySQL (eller snarare i InnoDB-lagringsmotorn) stör Online DDL-operationer. Läs mer i det här Vitess-blogginlägget.Begränsad till en enda MySQL-server,
FOREIGN KEY
begränsningar är omöjliga att underhålla när din data växer och är uppdelad på flera databasservrar. Detta händer vanligtvis när du introducerar funktionell partitionering/sharding och/eller horisontell sharding.
Detta fick mig att tänka:gör FOREIGN KEY
begränsningar påverkar skalbarheten i allmänhet? och i så fall hur?
Jag tror att det är viktigt att inse att SQL-tabellanslutningar är ganska kostsamma, men såvitt jag vet påverkades det inte mycket av referensintegritet? Nu, om vi gör något som dataanalys, så har vi uppenbarligen inte ett behov av referensintegritet eftersom vi bara skulle vilja dumpa vår data i en enda tabell, men PlanetScale och Vitess skryter med att användas av stora webbapplikationer som YouTube.
Detta fick mig att bli förvirrad över varför de skulle släppa FOREIGN KEY
begränsning eftersom databaser som CockroachDB och Spanner fortfarande upprätthåller referensintegritet samtidigt som de är skalbara.
Vad är referensintegritet och varför är det viktigt?
Låt oss börja med grunderna, om du är ny. Jag antar att de flesta som läser det här inlägget har en bra uppfattning om vad de pratar om, men jag ska förklara det som en formalitet. Med enkla ord, en FOREIGN KEY
constraint är en databasnyckel som vi kan använda för att skapa relationer mellan två olika tabeller genom att referera till en kolumn eller en uppsättning kolumner. Referensintegritet hänvisar helt enkelt till tillståndet för databasen där alla värden för alla nycklar är giltiga.
Varför är det viktigt?
Nu när vi har lite av en idé om vad de är, låt oss hoppa till den andra delen:varför är de viktiga?
Referensintegritet är viktigt eftersom det hindrar dig från att introducera nya fel i din databas. Det är en funktion som ofta tillhandahålls av relationsdatabaser som förhindrar användare eller applikationer från att mata in inkonsekventa data i databasen. Detta leder till förbättrad datakvalitet, snabbare utveckling, mycket färre buggar och konsekvens i hela din applikation.
Varför har inte Vitess det?
Så för att förstå varför Vitess inte kan stödja referensintegritet måste vi ta ett dyk in i databasens arkitektur. Vitess är en fragmenterad icke-ACID SQL-databas, inte en sann distribuerad ACID SQL-databas.
Nu måste du undra vad dessa termer är. Låt mig dela upp dem åt dig:ACID är en akronym av Atomicity, Consistency, Isolation and Durability.
Här hänvisar atomicitet till en handling som antingen fullbordar eller misslyckas helt - inget partiellt slutförande av en transaktion. Konsistens hänvisar till att transaktionen lämnar databasen i ett giltigt tillstånd. Isolering innebär helt enkelt att två transaktioner utförs utan störningar med varandra, och hållbarhet innebär att ändringarna av transaktionen sparas.
En shard är en horisontell partition av data i en databas, och varje shard hålls på en separat databasserverinstans för att sprida belastningen. Så när vi hänvisar till en databas som är fragmenterad, pratar vi om något sånt här. Nu som jag sa tidigare, är Vitess en fragmenterad icke-ACID SQL-databas, vilket i princip betyder att den INTE garanterar ACID-egenskaper för transaktioner.
Varför släppa det?
Tja, problemet börjar när du har en MySQL-databas med ett väldefinierat schema, och din tjänst blir populär med problemet med att för många läsningar träffar databasen. Vad de flesta gör här är att de börjar cachelagra ofta körda frågor, men läsningarna är inte längre sura.
Tillsammans med för många läsningar är det ett allvarligt problem som många kan ställas inför att skriva till din databas för mycket. Låt oss säga att vi är redo att sätta eld på våra fickor - vi kan skala vertikalt, lägga till mer RAM, en 16-kärnig processor och massor av riktigt snabba solid-state-enheter.
Vi har naturligtvis fortfarande problemet med att SQL-tabellanslutningar ökar i komplexitet, så du börjar avnormalisera för att undvika sammanfogningar mellan tabeller.
Jag höll ett föredrag på Prisma Meetup för ett tag sedan, där jag förklarade grunderna för att designa en relationsdatabas. Ett ämne jag tog upp här var denormalisering, om du är intresserad, se till att kolla in det här.
Men denormalisering är i grunden den process där du lägger till redundant data till tabeller i din databas, vilket förbättrar prestandan på kostnaden för diskutrymme eftersom du inte längre använder CPU-kraft för joins. Även om denormalisering förbättrar läshastigheten, är det viktigt att inse att det gör skrivningar långsammare.
Trots allt detta är vår databas fortfarande långsam, så vi flyttar databasberäkningar till klienten, till exempel genererar ett UUID eller tilldelar ett datum.
Även efter allt detta kommer frågorna fortfarande att vara långsamma - så vi håller resultatet av de mest efterfrågade uppgifterna redo i en process som kallas databasmaterialisering. Nu kan läsningen gå snabbare, men skrivningen blir långsammare för varje dag. Den enda logiska situationen nu är att släppa sekundära index.
Så vid det här laget har vår databas
- Inga ACID-egenskaper på grund av cachning
- Inget normaliserat schema
- Inga utlösare
- Inga databasberäkningar
- Inga sekundära index
Detta banade väg för Vitess- och NoSQL-databaser, eftersom företag hade problem med att skala sin databas. Som det var designat kunde de inte upprätthålla datakonsistens, en ACID-egenskap, när transaktioner sträckte sig över flera olika skärvor. Referensintegritet handlar om konsistens när data sträcker sig över flera skärvor, därför är det logiskt att de inte kan stödja det väl.
Vi kan gå djupt in i strukturen för NoSQL-databaser utan FOREIGN KEY
begränsningar och problem som vi kommer att möta med att anta den modellen, men det är ämnet för ett annat inlägg.
Det är inte bara Vitess, det har varit en standardpraxis för fragmenterade databaser för att undvika referensintegritet eftersom det helt enkelt inte finns något annat val. När det gäller ACID-modellen säger deras dokumentation att de garanterar atomicitet men inte isolering, och går till och med så långt som att säga:
Att garantera ACID-isolering är mycket omtvistat och har höga kostnader. Att tillhandahålla det som standard skulle ha gjort Vitess opraktiskt för de vanligaste användningsfallen.
Låt oss kort prata om vad ACID Isolering är. Det finns fyra nivåer för det (enligt SQL-92-standarderna), inklusive serialiserbarhet, läs committed, read uncommitted och repeterbara läsningar. Med det sagt, det finns fler nivåer av isolering, till exempel Snapshot-isolering som inte är en SQL-standard även om den används av flera databaser som Firebase eller MongoDB. Om du är mer intresserad av detta rekommenderar jag att du läser det här inlägget. För att hålla det kort, jag tänker inte gå igenom vad varje nivå av isolering gör/betyder, men om du vill läsa mer om det, kolla in den här sidan från MySQL-dokumentationen.
ACID-isolering hänvisar till att databastransaktionerna är ACIDiska, vilket är viktigt eftersom de garanterar att operationer beter sig som utvecklarna förväntar sig. Jag är osäker på vad de menar när de säger "Att garantera syraisolering är mycket kontroversiellt och har höga kostnader", men om de menar att garantera syraisolering har höga kostnader för alla produkter , de har fel. Flera distribuerade ACID-kompatibla databaser har den högsta nivån av isolering (serialiserbara transaktioner) samtidigt som de presterar med höga läs-/skrivhastigheter. I samband med Vitess har de dock inte fel eftersom transaktioner med flera skärvor inte kan uppfylla någon nivå av isolering.
Slutsats
Med allt detta måste du undra:varför skulle någon vilja använda PlanetScale eller Vitess? Tja, jag undrar detsamma. Med många företag och webbplatser var anledningen att de valde Vitess tillbaka när det inte fanns några bättre alternativ. Om du går till början av artikeln, lägg märke till hur den skapades redan 2010. Nu när vi kan njuta av en ACID-kompatibel skalbar databas med referensintegritet, skulle det vara i vårt bästa intresse att gå över till dessa nya databaser, och jag har redan börjat göra det! Tekniken förändras snabbt, och att hålla din databas uppdaterad är en avgörande komponent i alla applikationer.