2011-09-12 6 views
2

데이터베이스에 MongoDB를 사용하고 있습니다. 현재 작업중인 쿼리에서 내 스키마의 결함이 있음을 알 수 있습니다. 아래는 내 컬렉션의 관련 레이아웃입니다. 게임은 체스이기 때문에 games.players는 2 명의 플레이어로 구성됩니다. SQL 데이터베이스에서 Mongo 다중 쿼리 또는 데이터베이스 정규화

All msgs for games which a user is in which is newer than a given timestamp. 

, 내 쿼리가 유사 것이다 :

users {_id, username, ...} 
games {_id, players[], ...} 
msgs {_id, username, gameid, time, msg} 

내가 필요로하는 데이터는

SELECT * FROM msgs WHERE time>=$time AND gameid IN 
    (SELECT _id FROM games WHERE players=$username); 

그러나, 몽고는 관계형 데이터베이스 아니다 따라서 하위 쿼리 나 조인을 지원하지 않습니다. 가능한 해결책은 두 가지입니다. 성능면에서 효율적이고 효율성면에서 무엇이 좋을까요? 사용자가에서, 다음에 $를 사용한다

  1. 여러 쿼리
    • 선택 게임은에 의해 msgs.gameid와 일치합니다.
    • 기타?
  2. 정상화
    • 확인 users.games는 사용자의 모든 게임이 포함되어 있습니다. msgs.players에
    • 복사 games.players을 msgs.gameid
    • 등으로,

답변

0

자신을 "정상화"할 수 있습니다. 그가 회원으로있는 게임을 나열하는 배열을 사용자에게 추가합니다.

사용자 {_id, 사용자 이름, 게임 = {GAME1, game2, GAME3}}

지금 당신은 시간> 시간 $와 {games._id 사용자 "에"MSG를에 질의를 할 수 있습니다. 게임}

각 사용자별로 게임 목록을 관리해야합니다.

+0

그럴 수는 있지만 users.games가 선형 적으로 커짐을 의미합니다. 당신은 나를 반대로 생각하게 만들었고 games.players를 msgs에 복사했습니다. 그런 다음 시간과 사용자가 일치합니다. – Justin

+0

을 제외하고는 사용자 당 사용자 당 하나의 레코드 만 있습니다. Msgs는 msg마다 문서를 가지고 있으므로 대처 game.player는 각 msg에 많은 하위 객체를 배치합니다 (많은 데이터가 추가됨). 메시지가 전송 된 후 게임 회원이 변경 될 수 있습니다. "사용자"안에 "게임"을 저장하는 것은 게임 내에서 플레이어를 저장하지 않아도된다는 것을 의미합니다. 사용자 내부의 "게임"필드를 인덱싱 할 수 있습니다. –

+0

좋아, 내가 분명히 했어야, games.player는 체스 게임을위한 것이기 때문에 크기 2의 상수이다. 이것이 당신의 추천을 바꿀까요? 귀하의 방법은 조인이 없기 때문에 2 개의 쿼리가 필요하다고 생각하지만, 제 1 번만 필요합니다. – Justin

2

저는 MongoDB에 대한 상대적으로 초보자입니다. 그러나 나는 자주 두 접근법의 조합을 사용하여 자신을 찾습니다. 어떤 것 - 예 : 사용자 이름 - 자주 표시되는 쿼리를 단순화하기 위해 복제되지만 정보를 표시하는 것 이상의 작업을 수행해야 할 때마다 필자는 필요한 모든 문서를 모으기 위해 $ 2를 사용하여 여러 개의 쿼리를 작성합니다. 주어진 작업에 대해 작업 할 수 있습니다.

관련 문제