2011-12-14 5 views
3

내 음악 디자인을위한 스키마 디자인에 문제가 있다고 생각한다.MongoDB 스키마 설계. 내가 원하는 것을 얻을 수 없다.

나는 3 개의 콜렉션이 있습니다 : Artists, TracksAlbums입니다. 3 클래스 : artists에서 artists, albumstracks

문서 :

  [_id] => MongoId Object 
      (
       [$id] => 4ee5bbfd615c219a07000000 
      ) 
     [freeze] => false, 
     [genres] => Array, 
     [hits] => 0, 
     [name] => Sarya Al Sawas, 
     [pictures] => Array, 

문서 albums에서 :

 [_id] => MongoId Object 
      (
       [$id] => 4ee88308615c218128000000 
      ) 

     [name] => Sabia 
     [slug] => wafiq-habib-ft-sarya-al-sawas-sabia 
     [year] => 1999 
     [genres] => Array, 
     [pictures] => Array, 
     [artists] => Array 
      (
       [0] => MongoId Object 
        (
         [$id] => 4ee34a3b615c21b624010000 
        ) 

       [1] => MongoId Object 
        (
         [$id] => 4ee5bbfd615c219a07000000 
        ) 

      ) 

문서

  [_id] => MongoId Object 
      (
       [$id] => 4ee8a056615c21542a000000 
      ) 

     [name] => Bid Ashok 
     [slug] => wafiq-habib-ft-sarya-al-sawas-bid-ashok 
     [genres] => Array, 
     [file] => /m/tracks/t.4ee8a05540c624.04707814.mp3, 
     [freeze] => false, 
     [hits] => 0, 
     [duration] => 303, 
     [albums] => Array 
      (
       [0] => MongoId Object 
        (
         [$id] => 4ee5cbc3615c216509000000 
        ) 

      ) 

     [artists] => Array 
      (
       [0] => MongoId Object 
        (
         [$id] => 4ee5bbfd615c219a07000000 
        ) 

       [1] => MongoId Object 
        (
         [$id] => 4ee34a3b615c21b624010000 
        ) 

      ) 
tracks

먼저 좋은 스키마 디자인이 무엇입니까 ?? many to many relationships 때문에이 스키마를 설계했습니다. 가끔 트랙에 2 명의 아티스트가 있고 앨범에 2 명의 아티스트가 있습니다.

어쨌든 특정 트랙에 첨부 된 앨범을 쿼리하는 데 문제가 있습니다.

$cursors = array(
    'albums' => $this->albums->find(array('artists' => $artist->_id))->sort(array('_id' => -1)), 
    'tracks' => $this->tracks->find(array('artists' => $artist->_id))->sort(array('_id' => -1)), 
    'clips' => $this->clips->find(array('artists' => $artist->_id))->sort(array('_id' => -1)) 
); 
foreach($cursors as $key => $cursor) { 
    foreach($cursor as $obj) { 
     $obj['name'] = ($this->lang->get() != 'ar' ? $obj['translated']['name'] : $obj['name']); 
     $obj['by'] = $this->artists()->get($obj['artists'])->toString('ft'); 
     ${$key}[] = $obj; 
    } 
} 
  • 내가 모든 트랙에 루프가 필요합니다

    내가

    1. 내가 모든 아티스트의 앨범을 얻을 필요가 아티스트 페이지에서 그리고 난 이렇게 이렇게 추적 말할 수 그들의 앨범 이름을 얻으면이 아티스트는 3000 트랙을 가지고 있다고 말할 수 있습니다. 매우 느릴 것이라고 생각합니다 ....

    내 질문은 : 그 좋은 스키마 디자인?

  • 답변

    3

    글쎄, 이것은 매우 관계적인 문제이며, 이러한 문제에 대해 비 관계형 데이터베이스를 사용하는 것은 약간의 노력이 필요합니다. 일반적으로 스키마 디자인이 좋다고 생각합니다.

    N 개의 오브젝트에 대해 N + 1 개의 쿼리를 작성해야하기 때문에 설명하는 내용을 "N + 1 문제"라고합니다. 귀하의 경우에는 더 복잡하지만 아이디어를 얻은 것 같습니다. .

    일부 치료 :

    • 당신은 예를 찾기 위해 $in 연산자를 사용할 수 있습니다 특정 아티스트의 모든 트랙 : 예술가의 배열이 큰 성장 경우

      db.tracks.find({"artists" : { $in : [artist_id_1, artist_id_2, ...] } }); 
      

      이 작동하지 않지만, 수백, 어쩌면 수천은 잘 작동합니다. artists이 색인 생성되었는지 확인하십시오.

    • 매우 자주 필요한 일부 정보를 비정규화할 수 있습니다. 예를 들어, 트랙 목록을 매우 자주 보여줄 수 있으므로 아티스트의 이름을 모든 트랙에 복사하는 것이 좋습니다. 비정규 화는 주로 최종 사용자의 관점에서 무엇을 달성하려고하는지에 달려 있습니다.어쨌든 UI가 개요에 더 많이 표시되지 않기 때문에 각 아티스트의 이름을 전체로 저장하는 대신 처음 50 자만 저장하는 것이 좋습니다.

      실제로 앨범의 아티스트 ID (트랙을 통해 가져올 수 있으므로 중복 됨)와 같은 일부 데이터는 이미 비정규 화되어 있습니다. 이렇게하면 쿼리가 쉬워 지지만 더 많은 쓰기가 발생합니다. 업데이트는 시스템을 통해 전파되어야하므로 추악합니다.

    • 어떤 경우에는 서버가 아닌 클라이언트 (!)에서 '가입'하는 것이 바람직 할 수 있습니다. 이것은 실제로 당신의 문제에 잘 맞지 않지만 주목할만한 것입니다 : 친구 목록이 있다고 가정 해보십시오. 이제 각 친구의 이름을 표시 할 때마다 그 이름을 찾아야합니다. 대신 룩업 테이블 ids/friends를 제공 할 수 있으며 서버는 ID 만 제공합니다. 일부 JavaScript는 id를 클라이언트 캐시의 실제 이름으로 바꿀 수 있습니다. 내가 그들에게있을 필요가 있기 때문에 내가 예술가로 다시 앨범을 연결하는 이유 @mnemosyn

    +0

    덕분에 난 항상 해달라고 때때로 트랙을 얻으려면 내가 유일한 앨범 원하는, 그리고 퍼팅의 생각입니다 아티스트의 이름이 트랙 문서에 직접 표시되는 것은 좋은 아이디어입니다. 잘 작동했는데 다른 사람이 더 좋은 아이디어를 얻었는지 확인하고 싶습니다 .... – Pinokyo

    +0

    감사합니다. 왜냐하면 나는 비정규화할 것입니다. 아티스트와 앨범 및 트랙의 이름과 세부 정보는 내 관리자가 오타로 변경되므로 항상 작성하지는 않습니다 .... – Pinokyo

    관련 문제