[MONGODB] MongoDB를 / NoSQL에가 : 문서 변경 내역을 유지
MONGODBMongoDB를 / NoSQL에가 : 문서 변경 내역을 유지
데이터베이스 응용 프로그램에 매우 일반적인 요구 사항은 데이터베이스에 하나 이상의 특정 개체에 대한 변경 사항을 추적하는 것입니다. 나는이라는 행 버전, 로그 테이블이나 역사 테이블 (나는 확실히 그것을 다른 이름이 있습니다 해요) 들었습니다. RDBMS와에 접근하는 방법에는 여러 가지가 있습니다 - 당신은 (로그의 이상) 단일 테이블에 모든 소스 테이블의 모든 변경 사항을 작성하거나 각 소스 테이블에 대해 별도의 기록 테이블을 가질 수 있습니다. 당신은 또한 응용 프로그램 코드 나 데이터베이스 트리거를 통해 로그를 관리하거나 할 수있는 옵션이 있습니다.
저도 같은 문제에 대한 해결책이없는 NoSQL / 문서 데이터베이스 (특히 MongoDB를)에서 어떻게 보이는지를 통해 생각하려고하고, 어떻게 균일 한 방법으로 해결 될 수 있어요. 이 문서의 버전 번호를 생성하고이를 덮어 결코 단순하게겠습니까? 문서는 "실제"대를위한 별도의 컬렉션을 "기록"만들기? 어떻게 이런 일이 쿼리 및 성능에 영향을 미칠까요?
어쨌든,이되는 NoSQL 데이터베이스와 일반적인 시나리오이며, 만약 그렇다면, 일반적인 솔루션은 무엇입니까?
해결법
-
==============================
1.나뿐만 아니라이 나 자신을 찾고 있었다 좋은 질문입니다.
나뿐만 아니라이 나 자신을 찾고 있었다 좋은 질문입니다.
루비의 Mongoid 드라이버의 버전 관리 모듈을 가로 질러왔다. 내가 직접 사용하지 않은,하지만 난 찾을 수있는 것과, 각 문서에 버전 번호를 추가합니다. 이전 버전은 문서 자체에 포함됩니다. 가장 큰 단점은 전체 문서는 당신이 큰 문서를 처리 할 때 중복 콘텐츠를 많이 저장되는 결과 각 변화에 중복된다는 점이다. 이 방법은 괜찮 생각하면 작은 크기의 문서와 당신이있는 거 거래 및 / 또는 매우 자주 문서를 업데이트하지 않습니다.
또 다른 방법은 새로운 버전에서만 변경된 필드를 저장하는 것입니다. 그럼 당신은 문서의 모든 버전을 재구성하기 위해 역사를 '평평하게'할 수 있습니다. 당신이 당신의 응용 프로그램이 최신 문서를 재구성 할 수있는 방식으로 모델 및 저장 업데이트 및 삭제의 변화를 추적 할 필요가 이것은, 다소 복잡하지만입니다. 당신이 구조화 된 문서보다는 평면 SQL 테이블을 상대하고 이것은, 까다로운 일이 될 수 있습니다.
각 필드는 또한 개인의 역사를 가지고 있습니다. 주어진 버전으로 문서를 재구성하는 것은 훨씬 쉽게이 방법입니다. 응용 프로그램에서 명시 적으로 변경 사항을 추적해야하지만 당신은 그 값을 변경할 때 바로 재산의 새 버전을 작성하지 않습니다. 문서는 다음과 같이 보일 수 있습니다 :
{ _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" } ] } ] }
버전에서 삭제 된 문서의 일부를 표시하면 여전히하지만 다소 어색하다. 당신은 삭제 / 응용 프로그램에서 복원 할 수있는 부분에 대한 상태 필드가 들어갈 수 있습니다 :
{ author: "xxx", body: [ { version: 4, value: "Spam" } ], state: [ { version: 4, deleted: false }, { version: 5, deleted: true } ] }
이들 각각은 최신을 저장하고 하나 개의 수집 및 별도의 컬렉션의 이력 데이터 버전을 평평하게 할 수 있습니다 접근으로. 당신은 단지 문서의 최신 버전에 관심이 있다면이 번 쿼리를 개선해야한다. 최신 버전 및 히스토리 데이터 모두를 필요로 할 때, 당신은 오히려 하나보다, 두 개의 쿼리를 수행해야합니다. 응용 프로그램이 역사적 버전을 필요로하는 빈도에 의존해야 두 개의 컬렉션을 대 하나의 컬렉션을 사용의 선택에 따라서.
이 답변의 대부분은 내 생각의 단지 뇌 덤프, 나는 실제로 아직이 중 하나를 시도하지 않았습니다. 중복 데이터의 오버 헤드 응용 프로그램에 매우 중요하지 않는 한 다시 보면, 첫 번째 옵션은 아마도 가장 쉽고 가장 좋은 솔루션입니다. 두 번째 옵션은 매우 복잡하고 아마 노력이 가치가 없습니다. 세 번째 옵션은 기본적으로 두 번째 옵션의 최적화하고 구현하기 쉽게해야하지만, 당신이 정말로 옵션 하나를 갈 수 없다면 아마 구현 노력을 가치가되지 않습니다.
이에 대한 피드백을 기대하고, 문제에 대한 다른 사람의 솔루션 :
-
==============================
2.우리는 부분적으로 우리의 사이트에 구현하고 우리는 별도의 문서 "(및 별도의 데이터베이스)에서 '스토어 개정을 사용합니다. 우리는 차이점을 반환하는 사용자 정의 함수를 작성하고 우리는 그것을 저장합니다. 열심히하지 및 자동 복구 할 수 있습니다.
우리는 부분적으로 우리의 사이트에 구현하고 우리는 별도의 문서 "(및 별도의 데이터베이스)에서 '스토어 개정을 사용합니다. 우리는 차이점을 반환하는 사용자 정의 함수를 작성하고 우리는 그것을 저장합니다. 열심히하지 및 자동 복구 할 수 있습니다.
-
==============================
3.왜 스토어에 변화는 문서 내에서 변경?
왜 스토어에 변화는 문서 내에서 변경?
대신 각 키 쌍에 대해 버전을 저장하는 문서에 현재 키 쌍은 항상 가장 최근의 상태와 변화의 '로그'역사를 배열 내에 저장되어 나타냅니다. 만 생성 이후 변경된 그 키는 로그에 항목이있을 것이다.
{ _id: "4c6b9456f61f000000007ba6" title: "Bar", body: "Is this thing on?", tags: [ "test", "trivial" ], comments: [ { key: 1, author: "joe", body: "Something cool" }, { key: 2, author: "xxx", body: "Spam", deleted: true }, { key: 3, author: "jim", body: "Not bad at all" } ], history: [ { who: "joe", when: 20160101, what: { title: "Foo", body: "What should I write?" } }, { who: "jim", when: 20160105, what: { tags: ["test", "test2"], comments: { key: 3, body: "Not baaad at all" } } ] }
-
==============================
4.하나는 현재없는 NoSQL 데이터베이스와 역사적되는 NoSQL 데이터베이스를 가질 수 있습니다. 야간 ETL에 달렸다 매일있을 것입니다. 이 ETL은 타임 스탬프 모든 값을 기록, 그래서 대신 값은 항상 튜플 (버전 필드)입니다. 그 과정에서 공간을 절약 현재 값을 만든 변화가 있었다 경우에만 새 값을 기록합니다. 예를 들어,이 기록되는 NoSQL 데이터베이스 JSON 파일과 같이 볼 수있다 :
하나는 현재없는 NoSQL 데이터베이스와 역사적되는 NoSQL 데이터베이스를 가질 수 있습니다. 야간 ETL에 달렸다 매일있을 것입니다. 이 ETL은 타임 스탬프 모든 값을 기록, 그래서 대신 값은 항상 튜플 (버전 필드)입니다. 그 과정에서 공간을 절약 현재 값을 만든 변화가 있었다 경우에만 새 값을 기록합니다. 예를 들어,이 기록되는 NoSQL 데이터베이스 JSON 파일과 같이 볼 수있다 :
{ _id: "4c6b9456f61f000000007ba6" title: [ { date: 20160101, value: "Hello world" }, { date: 20160202, value: "Foo" } ], body: [ { date: 20160101, value: "Is this thing on?" }, { date: 20160102, value: "What should I write?" }, { date: 20160202, value: "This is the new body" } ], tags: [ { date: 20160101, value: [ "test", "trivial" ] }, { date: 20160102, value: [ "foo", "test" ] } ], comments: [ { author: "joe", // Unversioned field body: [ { date: 20160301, value: "Something cool" } ] }, { author: "xxx", body: [ { date: 20160101, value: "Spam" }, { date: 20160102, deleted: true } ] }, { author: "jim", body: [ { date: 20160101, value: "Not bad" }, { date: 20160102, value: "Not bad at all" } ] } ] }
-
==============================
5.파이썬의 사용자 (물론 최대 파이썬 3 이상)의 경우, pymongo의 컬렉션 객체의 확장이다 HistoricalCollection이 있습니다.
파이썬의 사용자 (물론 최대 파이썬 3 이상)의 경우, pymongo의 컬렉션 객체의 확장이다 HistoricalCollection이 있습니다.
워드 프로세서에서 예 :
from historical_collection.historical import HistoricalCollection from pymongo import MongoClient class Users(HistoricalCollection): PK_FIELDS = ['username', ] # <<= This is the only requirement # ... users = Users(database=db) users.patch_one({"username": "darth_later", "email": "darthlater@example.com"}) users.patch_one({"username": "darth_later", "email": "darthlater@example.com", "laser_sword_color": "red"}) list(users.revisions({"username": "darth_later"})) # [{'_id': ObjectId('5d98c3385d8edadaf0bb845b'), # 'username': 'darth_later', # 'email': 'darthlater@example.com', # '_revision_metadata': None}, # {'_id': ObjectId('5d98c3385d8edadaf0bb845b'), # 'username': 'darth_later', # 'email': 'darthlater@example.com', # '_revision_metadata': None, # 'laser_sword_color': 'red'}]
전체 공개, 내가 패키지 저자. :)
from https://stackoverflow.com/questions/3507624/mongodb-nosql-keeping-document-change-history by cc-by-sa and MIT license
'MONGODB' 카테고리의 다른 글
[MONGODB] 어떻게 윈도우에서 MongoDB를 시작합니까? (0) | 2019.12.16 |
---|---|
[MONGODB] 배열 필드는 고유 값 또는 MongoDB의 다른 배열이 포함 된 경우 확인하는 방법? (0) | 2019.12.16 |
[MONGODB] C #을 중첩 된 개체의 수를 계산 (0) | 2019.12.15 |
[MONGODB] 요소를 통과하는 부분 (...)를 사용할 수 없습니다 (0) | 2019.12.15 |
[MONGODB] 어떻게하여 MongoDB에서 배열에서 항목의 인스턴스를 당겨? (0) | 2019.12.15 |