sql >> Database >  >> NoSQL >> MongoDB

MongoDB (noSQL) wanneer verzamelingen moeten worden gesplitst

Zoals al geschreven, zijn er geen regels zoals de tweede normaalvorm voor SQL.

Er zijn echter enkele best practices en veelvoorkomende valkuilen met betrekking tot optimalisatie voor MongoDB die ik hier zal opsommen.

Overmatig gebruik van inbedding

De BSON-limiet

In tegenstelling tot wat vaak wordt gedacht, is er niets mis met verwijzingen. Stel dat u een bibliotheek met boeken heeft en dat u de verhuur wilt volgen. Je zou kunnen beginnen met een model als dit

{
  // 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"
    }
  ]
}

Hoewel er verschillende problemen zijn met dit model, is de belangrijkste niet duidelijk - er zal een beperkt aantal verhuur zijn vanwege het feit dat BSON-documenten een maximale grootte van 16 MB hebben.

Het documentmigratieprobleem

Het andere probleem met het opslaan van huur in een array zou zijn dat dit relatief frequente documentmigraties zou veroorzaken, wat een vrij kostbare operatie is. BSON-documenten worden nooit gepartitioneerd en gemaakt met wat extra ruimte die vooraf is toegewezen en die wordt gebruikt wanneer ze groeien. Deze extra ruimte wordt opvulling genoemd. Wanneer de opvulling wordt overschreden, wordt het document verplaatst naar een andere locatie in de gegevensbestanden en wordt nieuwe opvulruimte toegewezen. Dus frequente toevoegingen van gegevens leiden tot frequente documentmigraties. Daarom is het de beste gewoonte om frequente updates te voorkomen die de omvang van het document vergroten en in plaats daarvan referenties te gebruiken.

Dus voor het voorbeeld zouden we ons enkele model veranderen en een tweede maken. Eerst het model voor het boek

{
  _id: "9783453031456",
  title:"Schismatrix",
  author: "Bruce Sterling"
}

Het tweede model voor de verhuur zou er zo uitzien

{
  _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")
}

Dezelfde benadering kan natuurlijk worden gebruikt voor auteur of huurder.

Het probleem met overnormalisatie

Laten we even terugkijken. Een ontwikkelaar zou de betrokken entiteiten in een businesscase identificeren, hun eigenschappen en relaties definiëren, de bijbehorende entiteitsklassen schrijven, zijn hoofd een paar uur tegen de muur bonzen om de drievoudige binnen-buiten-boven-en-buiten JOIN werkend te krijgen voor de use case en ze leefden nog lang en gelukkig. Dus waarom zou u NoSQL in het algemeen en MongoDB in het bijzonder gebruiken? Want niemand leefde nog lang en gelukkig. Deze benadering schaalt verschrikkelijk en bijna uitsluitend is de enige manier om te schalen verticaal.

Maar het belangrijkste verschil met NoSQL is dat u uw gegevens modelleert op basis van de vragen die u moet beantwoorden.

Dat gezegd hebbende, laten we eens kijken naar een typische n:m-relatie en de relatie tussen auteurs en boeken als voorbeeld nemen. In SQL zou u 3 tabellen hebben:twee voor uw entiteiten (boeken en auteurs ) en één voor de relatie (Wie is de auteur van welk boek? ). Natuurlijk kunt u die tabellen nemen en hun equivalente verzamelingen maken. Maar aangezien er geen JOIN's zijn in MongoDB, hebt u drie zoekopdrachten nodig (een voor de eerste entiteit, een voor de relaties en een voor de gerelateerde entiteiten) om de gerelateerde documenten van een entiteit te vinden. Dit zou niet logisch zijn, aangezien de benadering met drie tabellen voor n:m-relaties specifiek is uitgevonden om de strikte schema's die SQL-databases afdwingen te overwinnen. Aangezien MongoDB een flexibel schema heeft, zou de eerste vraag zijn waar de relatie moet worden opgeslagen, waarbij de problemen behouden blijven als gevolg van overmatig gebruik van inbedding in gedachten. Aangezien een auteur in de komende jaren misschien heel wat boeken zal schrijven, maar het auteurschap van een boek zelden of helemaal niet verandert, is het antwoord eenvoudig:we slaan de auteurs op als referentie naar de auteurs in de boekengegevens

{
  _id: "9783453526723",
  title: "The Difference Engine",
  authors: ["idOfBruceSterling","idOfWilliamGibson"]
}

En nu kunnen we de auteurs van dat boek vinden door twee zoekopdrachten uit te voeren:

var book = db.books.findOne({title:"The Difference Engine"})
var authors = db.authors.find({_id: {$in: book.authors})

Ik hoop dat het bovenstaande u helpt te beslissen wanneer u uw collecties daadwerkelijk moet "splitsen" en dat u de meest voorkomende valkuilen kunt omzeilen.

Conclusie

Wat betreft uw vragen, hier zijn mijn antwoorden

  1. Zoals eerder geschreven:Nee , maar als u de technische beperkingen in gedachten houdt, krijgt u een idee wanneer dit zinvol kan zijn.
  2. Het is niet slecht - zolang het maar past bij uw gebruiksscenario('s) . Als je een bepaalde categorie en zijn _id . hebt , is het gemakkelijk om de gerelateerde producten te vinden. Wanneer u het product laadt, kunt u gemakkelijk de categorieën krijgen waartoe het behoort, zelfs efficiënt, als _id wordt standaard geïndexeerd.
  3. Ik heb nog geen use-case gevonden die niet met MongoDB kan, hoewel sommige dingen met MongoDB wat ingewikkelder kunnen worden. Wat je moet doen, is de som van je functionele en niet-functionele vereisten nemen en controleren of de voordelen opwegen tegen de nadelen. Mijn vuistregel:als een van "schaalbaarheid" of "hoge beschikbaarheid/automatische failover" op uw lijst met vereisten staat, is MongoDB meer dan een kijkje waard.



  1. MongoError:databasenamen mogen het teken ' ' niet bevatten bij gebruik van mongoosejs om verbinding te maken met mlab

  2. Hoe vind je de grootte van het specifieke document in MonogoDB Collection?

  3. Django - Hoe asynchrone takenwachtrij te gebruiken met selderij en redis

  4. groepeer MongoDB-verzameling per maand en totale inkomsten voor churn / inkomstengrafiek