sql >> Database teknologi >  >> NoSQL >> MongoDB

MongoDB/NoSQL:Bevar dokumentændringshistorik

Godt spørgsmål, jeg undersøgte også selv dette.

Opret en ny version ved hver ændring

Jeg stødte på versionsmodulet til Mongoid-driveren til Ruby. Jeg har ikke selv brugt det, men efter hvad jeg kunne finde, tilføjer det et versionsnummer til hvert dokument. Ældre versioner er indlejret i selve dokumentet. Den største ulempe er, at hele dokumentet duplikeres ved hver ændring , hvilket vil resultere i, at en masse duplikatindhold bliver gemt, når du har med store dokumenter at gøre. Denne tilgang er dog fin, når du har at gøre med små dokumenter og/eller ikke opdaterer dokumenter særlig ofte.

Gem kun ændringer i en ny version

En anden fremgangsmåde ville være at kun gemme de ændrede felter i en ny version . Derefter kan du 'flade' din historie for at rekonstruere enhver version af dokumentet. Dette er dog ret komplekst, da du skal spore ændringer i din model og gemme opdateringer og sletninger på en måde, så din applikation kan rekonstruere det opdaterede dokument. Dette kan være vanskeligt, da du har at gøre med strukturerede dokumenter i stedet for flade SQL-tabeller.

Gem ændringer i dokumentet

Hvert felt kan også have en individuel historie. Rekonstruering af dokumenter til en given version er meget nemmere på denne måde. I din applikation behøver du ikke eksplicit at spore ændringer, men bare oprette en ny version af ejendommen, når du ændrer dens værdi. Et dokument kunne se sådan ud:

{
  _id: "4c6b9456f61f000000007ba6"
  title: [
    { version: 1, value: "Hello world" },
    { version: 6, value: "Foo" }
  ],
  body: [
    { version: 1, value: "Is this thing on?" },
    { version: 2, value: "What should I write?" },
    { version: 6, value: "This is the new body" }
  ],
  tags: [
    { version: 1, value: [ "test", "trivial" ] },
    { version: 6, value: [ "foo", "test" ] }
  ],
  comments: [
    {
      author: "joe", // Unversioned field
      body: [
        { version: 3, value: "Something cool" }
      ]
    },
    {
      author: "xxx",
      body: [
        { version: 4, value: "Spam" },
        { version: 5, deleted: true }
      ]
    },
    {
      author: "jim",
      body: [
        { version: 7, value: "Not bad" },
        { version: 8, value: "Not bad at all" }
      ]
    }
  ]
}

At markere en del af dokumentet som slettet i en version er dog stadig noget akavet. Du kunne introducere en state felt for dele, der kan slettes/gendannes fra din applikation:

{
  author: "xxx",
  body: [
    { version: 4, value: "Spam" }
  ],
  state: [
    { version: 4, deleted: false },
    { version: 5, deleted: true }
  ]
}

Med hver af disse tilgange kan du gemme en opdateret og fladtrykt version i én samling og historiedataene i en separat samling. Dette burde forbedre forespørgselstider, hvis du kun er interesseret i den seneste version af et dokument. Men når du har brug for både den seneste version og historiske data, skal du udføre to forespørgsler i stedet for én. Så valget om at bruge en enkelt samling vs. to separate samlinger bør afhænge af hvor ofte din applikation har brug for de historiske versioner .

Det meste af dette svar er bare en hjernedump af mine tanker, jeg har faktisk ikke prøvet noget af dette endnu. Når man ser tilbage på det, er den første mulighed nok den nemmeste og bedste løsning, medmindre overheaden med duplikerede data er meget væsentlig for din applikation. Den anden mulighed er ret kompleks og er sandsynligvis ikke besværet værd. Den tredje mulighed er dybest set en optimering af mulighed to og burde være nemmere at implementere, men er sandsynligvis ikke implementeringsindsatsen værd, medmindre du virkelig ikke kan gå med mulighed et.

Ser frem til feedback på dette, og andres løsninger på problemet :)



  1. MongoDB udtrækker værdier fra BasicDBObject (Java)

  2. Brug jedis hvordan man skriver til en specifik slot/node i redis cluster

  3. MongoDB samlet forespørgsel ved hjælp af PHP-driver

  4. Vælg data, hvor intervallet mellem to forskellige felter indeholder et givet tal