MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

MongoDB/NoSQL:przechowywanie historii zmian dokumentów

Dobre pytanie, sam też się tym zajmowałem.

Utwórz nową wersję po każdej zmianie

Natknąłem się na moduł Versioning sterownika Mongoid dla Rubiego. Sam go nie używałem, ale z tego, co udało mi się znaleźć, dodaje numer wersji do każdego dokumentu. Starsze wersje są osadzone w samym dokumencie. Główną wadą jest to, że cały dokument jest duplikowany przy każdej zmianie , co spowoduje, że w przypadku dużych dokumentów będzie przechowywanych wiele zduplikowanych treści. Takie podejście jest jednak dobre, gdy masz do czynienia z dokumentami o małych rozmiarach i/lub nie aktualizujesz dokumentów zbyt często.

Przechowuj zmiany tylko w nowej wersji

Innym podejściem byłoby przechowywanie tylko zmienionych pól w nowej wersji . Następnie możesz „spłaszczyć” swoją historię, aby zrekonstruować dowolną wersję dokumentu. Jest to jednak dość skomplikowane, ponieważ musisz śledzić zmiany w swoim modelu oraz przechowywać aktualizacje i usunięcia w taki sposób, aby Twoja aplikacja mogła zrekonstruować aktualny dokument. Może to być trudne, ponieważ masz do czynienia z ustrukturyzowanymi dokumentami, a nie płaskimi tabelami SQL.

Zapisz zmiany w dokumencie

Każde pole może mieć również indywidualną historię. W ten sposób odtworzenie dokumentów do danej wersji jest znacznie prostsze. W swojej aplikacji nie musisz jawnie śledzić zmian, ale po prostu utwórz nową wersję właściwości, gdy zmienisz jej wartość. Dokument może wyglądać mniej więcej tak:

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

Oznaczenie części dokumentu jako usuniętej w wersji jest jednak nadal dość niezręczne. Możesz wprowadzić state pole dla części, które można usunąć/przywrócić z aplikacji:

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

W każdym z tych podejść można przechowywać aktualną i spłaszczoną wersję w jednym zbiorze, a dane historyczne w osobnym zbiorze. Powinno to skrócić czas wykonywania zapytań, jeśli interesuje Cię tylko najnowsza wersja dokumentu. Ale gdy potrzebujesz zarówno najnowszej wersji, jak i danych historycznych, musisz wykonać dwa zapytania zamiast jednego. Zatem wybór użycia jednej kolekcji zamiast dwóch oddzielnych kolekcji powinien zależeć od jak często Twoja aplikacja potrzebuje wersji historycznych .

Większość z tych odpowiedzi to tylko zrzut moich myśli, właściwie jeszcze tego nie próbowałem. Patrząc wstecz, pierwsza opcja jest prawdopodobnie najłatwiejszym i najlepszym rozwiązaniem, chyba że narzut zduplikowanych danych jest bardzo istotny dla Twojej aplikacji. Druga opcja jest dość złożona i prawdopodobnie nie jest warta wysiłku. Trzecia opcja jest zasadniczo optymalizacją opcji drugiej i powinna być łatwiejsza do wdrożenia, ale prawdopodobnie nie jest warta wysiłku implementacyjnego, chyba że naprawdę nie możesz skorzystać z opcji pierwszej.

Nie możemy się doczekać opinii na temat tego i innych rozwiązań problemu :)



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Połącz laravel jenssegers z klastrem atlasu mongodb

  2. Jak wysłać zapytanie do MongoDB, aby sprawdzić, czy element istnieje?

  3. Przechowywanie małych (poniżej 1 MB) plików za pomocą MongoDB w NodeJS BEZ GridFS

  4. Mongoose Model.find nie jest funkcją?

  5. Które API Pythona powinno być używane z Mongo DB i Django