Som allerede skrevet er der ingen regler som den anden normale form for SQL.
Der er dog nogle bedste praksisser og almindelige faldgruber relateret til optimering til MongoDB, som jeg vil liste her.
Overbrug af indlejring
BSON-grænsen
I modsætning til hvad man tror, er der intet galt med referencer. Antag, at du har et bibliotek med bøger, og du vil spore lejemålene. Du kan begynde med en model som denne
{
// We use ISBN for its uniqueness
_id: "9783453031456"
title: "Schismatrix",
author: "Bruce Sterling",
rentals: [
{
name:"Markus Mahlberg,
start:"2015-05-05T03:22:00Z",
due:"2015-05-12T12:00:00Z"
}
]
}
Selvom der er flere problemer med denne model, er det vigtigste ikke indlysende – der vil være et begrænset antal lejemål på grund af det faktum, at BSON-dokumenter har en størrelsesgrænse på 16MB.
Problemet med dokumentmigrering
Det andet problem med at gemme lejemål i et array ville være, at dette ville forårsage relativt hyppige dokumentmigreringer, hvilket er en temmelig dyr operation. BSON-dokumenter opdeles aldrig og oprettes med noget ekstra plads, der er allokeret på forhånd, når de vokser. Denne ekstra plads kaldes polstring. Når udfyldningen overskrides, flyttes dokumentet til en anden placering i datafilerne, og ny udfyldningsplads tildeles. Så hyppige tilføjelser af data forårsager hyppige dokumentmigreringer. Derfor er det bedste praksis at forhindre hyppige opdateringer, der øger størrelsen af dokumentet og bruge referencer i stedet.
Så for eksemplet ville vi ændre vores enkelte model og oprette en anden. Først modellen til bogen
{
_id: "9783453031456",
title:"Schismatrix",
author: "Bruce Sterling"
}
Den anden model til udlejningen ville se sådan ud
{
_id: new ObjectId(),
book: "9783453031456",
rentee: "Markus Mahlberg",
start: ISODate("2015-05-05T03:22:00Z"),
due: ISODate("2015-05-05T12:00:00Z"),
returned: ISODate("2015-05-05T11:59:59.999Z")
}
Den samme tilgang kunne selvfølgelig bruges til forfatter eller lejer.
Problemet med overnormalisering
Lad os se lidt tilbage. En udvikler vil identificere de enheder, der er involveret i en business case, definere deres egenskaber og relationer, skrive de tilsvarende enhedsklasser, banke hovedet mod væggen i et par timer for at få det tredobbelte indre-ydre-over-og-udover JOIN-arbejde, der kræves til brug og alle levede lykkeligt til deres dages ende. Så hvorfor bruge NoSQL generelt og MongoDB i særdeleshed? For ingen levede lykkeligt til deres dages ende. Denne tilgang skalerer forfærdeligt og næsten udelukkende den eneste måde at skalere på er lodret.
Men den største forskel ved NoSQL er, at du modellerer dine data efter de spørgsmål, du har brug for at få besvaret.
Når det er sagt, lad os se på en typisk n:m-relation og tage forholdet fra forfattere til bøger som vores eksempel. I SQL vil du have 3 tabeller:to for dine enheder (bøger og forfattere ) og en for relationen (Hvem er forfatteren til hvilken bog? ). Selvfølgelig kunne du tage disse tabeller og oprette deres tilsvarende samlinger. Men da der ikke er JOINs i MongoDB, har du brug for tre forespørgsler (en for den første enhed, en for dens relationer og en for de relaterede enheder) for at finde de relaterede dokumenter for en enhed. Dette ville ikke give mening, da metoden med tre tabeller for n:m-relationer blev specifikt opfundet for at overvinde de strenge skemaer, som SQL-databaser håndhæver. Da MongoDB har et fleksibelt skema, ville det første spørgsmål være, hvor relationen skal opbevares, og problemerne bevares. som følge af overforbrug af indlejring i tankerne. Da en forfatter måske skriver en del bøger i de kommende år, men forfatterskabet af en bog sjældent, hvis overhovedet, ændres, er svaret enkelt:Vi gemmer forfatterne som en reference til forfatterne i bøgernes data
{
_id: "9783453526723",
title: "The Difference Engine",
authors: ["idOfBruceSterling","idOfWilliamGibson"]
}
Og nu kan vi finde forfatterne til den bog ved at lave to forespørgsler:
var book = db.books.findOne({title:"The Difference Engine"})
var authors = db.authors.find({_id: {$in: book.authors})
Jeg håber, at ovenstående hjælper dig med at beslutte, hvornår du rent faktisk skal "opdele" dine samlinger og komme uden om de mest almindelige faldgruber.
Konklusion
Med hensyn til dine spørgsmål, her er mine svar
- Som skrevet før:Nej , men at holde de tekniske begrænsninger i tankerne burde give dig en idé om, hvornår det kunne give mening.
- Det er ikke dårligt – så længe det passer til din(e) use case(r) . Hvis du har en given kategori og dens
_id
, er det nemt at finde de relaterede produkter. Når du indlæser produktet, kan du nemt få de kategorier, det tilhører, selv effektivt, som_id
er indekseret som standard. - Jeg har endnu ikke fundet en use case, som ikke kan udføres med MongoDB, selvom nogle ting kan blive lidt mere komplicerede med MongoDB. Hvad du bør gøre imho er at tage summen af dine funktionelle og ikke-funktionelle krav og kontrollere, om fordelene opvejer ulemperne. Min tommelfingerregel:Hvis en af "skalerbarhed" eller "høj tilgængelighed/automatisk failover" er på din liste over krav, er MongoDB mere værd end et kig.