Du kan enten designe et skema, hvor du kan referere til eller indlejre dokumenter. Lad os se på den første mulighed for indlejrede dokumenter. Med din ovenstående ansøgning kan du muligvis gemme oplysningerne i et dokument som følger:
// db.table1 schema
{
"_id": 3, // table1_id
"is_active": true,
"created": ISODate("2015-04-07T16:00:30.798Z"),
"lang": [
{
"name": "foo",
"surname": "bar",
"address": "xxx"
},
{
"name": "abc",
"surname": "def",
"address": "xyz"
}
]
}
I eksempelskemaet ovenfor ville du i det væsentlige have indlejret table1_lang
oplysninger i hoved-table1
dokument. Dette design har sine fordele, en af dem er datalokalitet. Da MongoDB gemmer data sammenhængende på disken, sikrer det, at alle de data, du har brug for, i ét dokument, at de roterende diske vil tage kortere tid at søge til et bestemt sted på disken. Hvis din applikation ofte får adgang til table1
oplysninger sammen med table1_lang
data, så vil du næsten helt sikkert gå den indlejrede rute. Den anden fordel med indlejrede dokumenter er atomiciteten og isolationen i at skrive data. For at illustrere dette, lad os sige, at du vil fjerne et dokument, som har en lang-tast "name" med værdien "foo", dette kan gøres med en enkelt (atomisk) operation:
db.table.remove({"lang.name": "foo"});
For flere detaljer om datamodellering i MongoDB, læs venligst dokumenterne Introduktion til datamodellering , specifikt Model En-til-mange relationer med indlejrede dokumenter
Den anden designmulighed er at henvise til dokumenter, hvor du følger et normaliseret skema. For eksempel:
// db.table1 schema
{
"_id": 3
"is_active": true
"created": ISODate("2015-04-07T16:00:30.798Z")
}
// db.table1_lang schema
/*
1
*/
{
"_id": 1,
"table1_id": 3,
"name": "foo",
"surname": "bar",
"address": "xxx"
}
/*
2
*/
{
"_id": 2,
"table1_id": 3,
"name": "abc",
"surname": "def",
"address": "xyz"
}
Ovenstående tilgang giver øget fleksibilitet i udførelse af forespørgsler. For eksempel for at hente alle underordnede table1_lang
dokumenter for hovedenheden table1
med id 3 vil være ligetil, skal du blot oprette en forespørgsel mod samlingen table1_lang
:
db.table1_lang.find({"table1_id": 3});
Ovenstående normaliserede skema ved hjælp af dokumentreferencetilgang har også en fordel, når du har en-til-mange relationer med meget uforudsigelig aritet. Hvis du har hundredvis eller tusindvis af table_lang
dokumenter pr. give table
enhed, har indlejring så mange tilbageslag, hvad angår rumlige begrænsninger, fordi jo større dokumentet er, jo mere RAM bruger det, og MongoDB-dokumenter har en hård størrelsesgrænse på 16 MB.
Den generelle tommelfingerregel er, at hvis din applikations forespørgselsmønster er velkendt, og der kun er adgang til data på én måde, fungerer en indlejret tilgang godt. Hvis din applikation forespørger data på mange måder, eller du ikke er i stand til at forudse dataforespørgselsmønstrene, vil en mere normaliseret dokumentreferencemodel være passende i sådanne tilfælde.
Ref:
MongoDB Applied Design Patterns:Practical Use Cases with the Leading NoSQL Database af Rick Copeland a>