2013-08-06 1 views
3

나는 사용자, 계정 및 거래에 관한 정보를 저장할 작은 응용 프로그램을 개발 중입니다. 사용자는 많은 계정 (아마 10 미만)을 가지며 계정에는 많은 트랜잭션 (아마도 1000 년대)이 있습니다. 트랜잭션의 목록 이후로는 다음과 같이 포함하면 갈 수있는 방법이라고 제안 보인다 문서 도구 ...Mongodb에 퍼가기 또는 참조

{ 
"username": "joe", 
"accounts": [ 
    { 
     "name": "account1", 
     "transactions": [ 
      { 
       "date": "2013-08-06", 
       "desc": "transaction1", 
       "amount": "123.45" 
      }, 
      { 
       "date": "2013-08-07", 
       "desc": "transaction2", 
       "amount": "123.45" 
      }, 
      { 
       "date": "2013-08-08", 
       "desc": "transaction3", 
       "amount": "123.45" 
      } 
     ] 
    }, 
    { 
     "name": "account2", 
     "transactions": [ 
      { 
       "date": "2013-08-06", 
       "desc": "transaction1", 
       "amount": "123.45" 
      }, 
      { 
       "date": "2013-08-07", 
       "desc": "transaction2", 
       "amount": "123.45" 
      }, 
      { 
       "date": "2013-08-08", 
       "desc": "transaction3", 
       "amount": "123.45" 
      } 
     ] 
    } 
] 
} 

내 질문은 ... 읽기는 데이터가 단편화 될 것입니다 문서 내 아마도 1000 년대에 성장한다 성능을 저하시킵니다. 큰 규모로 성장하지 않는 사용자와 계정을 저장하는 문서를 가지고 계정을 참조하는 트랜잭션을 저장하는 별도의 컬렉션을 만드는 것이 더 낫습니다. 아니면 더 좋은 방법이 있습니까?

답변

5

이것은 갈 길이 아닙니다. 당신은 많은 거래를 가지고 있으며, 얼마나 많은 거래를 할 지 모릅니다. 대신이, 당신은 그들이 좋아하는 저장해야합니다 :

{ 
    "username": "joe", 
    "name": "account1", 
    "date": "2013-08-06", 
    "desc": "transaction1", 
    "amount": "123.45" 
}, 
{ 
    "username": "joe", 
    "name": "account1", 
    "date": "2013-08-07", 
    "desc": "transaction2", 
    "amount": "123.45" 
}, 
{ 
    "username": "joe", 
    "name": "account1", 
    "date": "2013-08-08", 
    "desc": "transaction3", 
    "amount": "123.45" 
}, 
{ 
    "username": "joe", 
    "name": "account2", 
    "date": "2013-08-06", 
    "desc": "transaction1", 
    "amount": "123.45" 
}, 
{ 
    "username": "joe", 
    "name": "account2", 
    "date": "2013-08-07", 
    "desc": "transaction2", 
    "amount": "123.45" 
}, 
{ 
    "username": "joe", 
    "name": "account2", 
    "date": "2013-08-08", 
    "desc": "transaction3", 
    "amount": "123.45" 
} 

당신이 denormalise하는 것을 두려워해서는 안 MongoDB를 같은되는 NoSQL 데이터베이스에서. 당신이 주목했듯이, 나는 사용자들을위한 별도의 콜렉션조차 신경 쓰지 않았다. 사용자가 각 거래와 함께 표시해야하는 추가 정보가있는 경우 해당 정보도 포함하는 것이 좋습니다.

당신이 검색하거나하여 선택해야하는 경우, 해당 필드 중 하나가, 다음 예를 들어, 인덱스를 생성하는 것을 잊지 마세요 :

// look up all transactions for an account 
db.transactions.ensureIndex({ username: 1, name: 1 }); 

과 :

// look up all transactions for "2013-08-06" 
db.transactions.ensureIndex({ date: 1 }); 

데이터를 복제 할 때 많은 이점이 있습니다. 위와 같은 스키마를 사용하면 최대한 많은 트랜잭션을 처리 할 수 ​​있으므로 문서가 변경되지 않으므로 분열을 일으키지 않습니다. 또한 쓰기 성능이 향상되고 다른 쿼리를 훨씬 쉽게 수행 할 수 있습니다.

대체

대안이 컬렉션의 이름/이름을 저장 단지는 트랜잭션 ID의 사용이 될 수 있습니다

계정 :

{ 
    "username": "joe", 
    "name": "account1", 
    "account_id": 42, 
} 

거래 :

{ 
    "account_id": 42, 
    "date": "2013-08-06", 
    "desc": "transaction1", 
    "amount": "123.45" 
}, 

이렇게하면 거래 문서가 더 작아 지지만 사용자 정보도 얻기 위해서는 두 가지 쿼리를 수행해야합니다.

0

ensureIndex() 함수를 사용하여 인덱스를 만들면 성능 문제가 발생할 위험을 줄일 수 있습니다. 이들을 더 일찍 추가할수록 컬렉션이 어떻게 구성되어야하는지 더 잘 이해할 수 있습니다. 데이터가되는 나는 몽고 너무 오래 사용하지 않은하지만 난 (어쨌든 아직) 문제 건너하지 않은 조각

편집 당신이 다중 객체가 범이를 사용하려는 경우, 몽고 아무튼 ' 롤백을 지원합니다. 저널링을 허용하고 트랜잭션을 내구성있게 만들려면 64 비트 버전을 사용해야합니다.

1

트랜잭션 목록이 문서 내에서 1000 자 정도로 커질 것이므로 데이터가 조각화되어 성능이 저하됩니다.

단일 계정의 경우 수십 년 동안 트랜잭션이 수천 개가 아닌 수천 개에 도달 한 경우 거의 놀랍습니다.

시간이 지남에 따라 계속 증가하는 문서에서 목격 할 조각화 수준을 추가하면 루트 문서 공간 (16meg)이 부족한 경우 심각한 문제가 발생할 수 있습니다. 실제로 하나의 문서 아래에 사람에 대한 모든 계정을 저장한다는 사실을 보면 약 2 년 동안 문서를 채울 위험이 높다고 말합니다.

이 관계를 참조 할 것입니다.

1

나는 다른 거래로 거래를 분리 할 것이다. 사용자와 트랜잭션 간의 데이터 및 업데이트 패턴이 매우 다른 것처럼 보입니다. 트랜잭션이 지속적으로 사용자에게 추가되고 항상 트랜잭션이 커지면 mongo 파일에서 트랜잭션이 많이 이동합니다. 그래서 예, 성능에 영향을줍니다 (조각화, IO 증가, mongo에 대한 추가 작업). 또한 배열 작업 성능은 문서의 큰 배열에 대해 때때로 비 정렬되므로 배열에 1000 개의 객체를 보유하는 것이 좋은 생각이 아닐 수도 있습니다.