2011-09-14 3 views
3

나는 구글이 MySQL을 사용하지 않는 것을 확실히 알고 있지만, 내 경우에는 내가 MySQL을 사용 프로젝트에서 작업 일어날 서클에 매우 유사 기능이 있습니다Google 플러스 서클의 데이터베이스 구조?

  1. 사용자가 많은 원
  2. 에 속할 수를
  3. 사용자는 추가/
  4. 게시물 공개하거나 서클에 공유 할 수/개별 사용자 원에서 제거 할 수 있습니다 게시물이 원에 공유하고, 새로운 사용자가 다음이 사용자가 또한 할 수있는이 원에 추가 된 경우
  5. 게시물을 봅니다.
  6. 게시물이 서클과 공유되고 사용자가이 서클에서 삭제 된 경우 다음을 수행합니다. 그/그녀는 그/그녀가 게시물 b에서 대답하면 게시물을 볼 수 있습니다. 더 이상 게시물을 볼 수 없습니다.

위의 요구 사항을 통해 알 수 있듯이 데이터베이스에는 많은 부분이 있습니다. 만약 내가 정말로 서클과 개인 사용자 모두에게 공유한다면, 아마 2 개의 One2Many 테이블이 필요할 것이다. 맨 처음에 각 서클의 사용자 목록을 가져 와서 개별 사용자에게만 공유하면 나중에 사용자가이 서클을 편집 할 때 문제가 발생합니다. 현재

, 내 GET이 주위에 해킹 내가 단지 동그라미 1 사용자가 작성하는 각 개별 사용자에 대한 원에만, 심지어 공유하는 것입니다.

그래서 내 현재 데이터베이스 테이블은 조금 같이 :

circle_to_user :

id 
circle_id 
user_id 
friend_id 

게시물 :

id 
user_id 
is_public 

post_to_circle

리튬을 조회하려면 난 그냥 세부 정보를 많이주고 싶어,

$q = Doctrine_Query::create() 
      ->addSelect('s.*') 
      ->addSelect('u.id, u.first_name, u.last_name, u.username, u.avatar') 
      ->from('UserStatus s') 
      ->leftJoin('s.User u') 
      ->orderBy('s.created_at DESC'); 

     $userId = sfContext::getInstance()->getUser()->getUserId(); 
     if ($userId == $viewUserId) { 
      $q->orWhere('s.user_id = ?', $userId); 
      $q->orWhere('s.user_id IN (SELECT DISTINCT cu1.friend_id FROM CircleUser cu1 WHERE cu1.user_id = ?) AND s.is_public = ?', array($userId, true)); 
      $q->orWhere('s.id IN (SELECT DISTINCT(us2.id) 
                 FROM 
                   UserStatus us2 INNER JOIN us2.UserStatusCircles usc2 ON usc2.user_status_id = us2.id 
                   INNER JOIN usc2.Circle c2 ON c2.id = usc2.circle_id 
                   INNER JOIN c2.CircleUsers cu2 ON cu2.circle_id = c2.id AND cu2.friend_id = ?)', $userId); 
     } else { 
      $q->orWhere('s.user_id = ? AND s.is_public = ?', array($viewUserId, true)); 
      $q->orWhere('s.id IN (SELECT DISTINCT(us1.id) 
                 FROM 
                   UserStatus us1 INNER JOIN us1.UserStatusCircles usc1 ON usc1.user_status_id = us1.id AND us1.user_id = ? 
                   INNER JOIN usc1.Circle c1 ON c1.id = usc1.circle_id 
                   INNER JOIN c1.CircleUsers cu1 ON cu1.circle_id = c1.id AND cu1.friend_id = ?)', array($viewUserId, $userId)); 
      $q->orWhere('s.id IN (SELECT DISTINCT(us2.id) 
                 FROM 
                   UserStatus us2 INNER JOIN us2.UserStatusCircles usc2 ON usc2.user_status_id = us2.id AND us2.user_id = ? 
                   INNER JOIN usc2.Circle c2 ON c2.id = usc2.circle_id 
                   INNER JOIN c2.CircleUsers cu2 ON cu2.circle_id = c2.id AND cu2.friend_id = ?)', array($userId, $viewUserId)); 
     } 

내가 위의 정보가 너무 길지 희망 : 사용자가 볼 수있는 게시물의 일이 쿼리가 다소 복잡하고 조인 여러 구성되어 있습니다. 내 질문은 다음과 같습니다.

  1. 위의 요구 사항을 고려할 때 구현이 만족 스럽습니까? 아니면 개선을 위해 변경해야 할 것이 있습니까?
  2. 이 유형의 특정 데이터베이스 디자인 문제에 관한 기사를 검색하고 싶지만 많이 찾지 못했습니다.이 유형의 데이터베이스 디자인에 대한 전문 용어가 있습니까
  3. 다른 유형의 데이터베이스를 사용하는 것과 같은 다른 방법을 제안 하시겠습니까? 또는 탄성을 가진 searchengine으로 게시물을 색인화하고 mysql을 사용하는 대신 검색을 처리하게 할 수 있습니까? 당신이 따라 답을 알려 제발하기 쉽도록하기 위해 나는이 질문을 변경해야합니다 아무것도 찾을 경우

는이 시점까지 읽어 주셔서 감사합니다.

+0

이 문제를 해결 한 적이 있습니까? 비슷한 문제가 있습니다. –

+0

최종 해결책은 실제로 생각했던 성능면에서 최적화되지 않았습니다. 아마 우리는 다시 생각해야합니다. 데이터 구조 (또는 왜 우리가 그렇게해야하는지). – mr1031011

답변

1

귀하의 단일 사용자 서클이 멋진 시도처럼 들리는 동안 어떻게 나간 것을 구별 할 것입니까?소식이 서클과 공유 된 것을 볼 때 그 서클이 진정한 사람인지 또는 한 명의 사용자인지 어떻게 알 수 있습니까? 왜냐하면 당신이 인터페이스에서 다르게 표시하기를 원한다고 생각하기 때문입니다. db에서 가짜 동그라미를 가져올 때 사용자가 편집 할 수 없도록해야한다는 것을 알고 있어야 할 것입니다.

사용자와의 연결을 피할 수있게 되더라도 이제는 특수 서클 케이스를 처리해야합니다. 여러 개의 서클에 게시물을 연결하고 여러 사용자에게 개별적으로 연결되는 2 x 1 * 테이블로 이동한다고 말하고 싶습니다.

당신이 당신의 의도를 검토하고 특별한 경우를 추가 할 수있는 '친구'관계를 제쳐두고 떠날 것을 권합니다. 공개적이거나 공개 된 모든 게시물 가져 오기 내 사용자와 공유하거나, 내가 속한 서클과 공유하거나, 내가 답장 한 소식입니다. 그것은 너무 복잡하지 않습니다. 저는 생각하지 않습니다. 여러분은 처음이나 뭐든지 목록을 가져올 필요가 없습니다.

(여러 JOIN은 두드러진 문제가 아닙니다. 더 중요한 것은 여러 가지 하위 쿼리가 있습니다. 일반적으로 나쁜 소식입니다. 대부분의 경우 일반 조인으로 다시 작업 할 수 있으며 일반적으로 더 깨끗하게 처리 할 수 ​​있습니다) .

0

이런 종류의 문제는 관계형 모델로 해결되지 않는다. Google은 데이터 저장소를 사용하며 bigtable, cassandra 및 hadoop에 상응한다.

0

나는 또한 동일한 문제가 있지만 나는 당신이 내가 이미 다룬/제안 된 게시판에 두 개의 테이블을 만들지 말고 그 대신에 with/circle_id이라는 게시 테이블에 열을 추가 할 것을 제안 할 수 있습니다. 그리고 나 또한 내가/또는 그 이상의 기본 원 항목을 추가 당신을 말하고 싶어 (특히 PublicAll Friends/CirclesCircles 테이블. 는 이제 포스트 픽업 쿼리는 다음과 같이 될 것입니다.

$id=$_SESSION["loged_in_user_id"];  
    $sql="SELECT * FROM `posts` as p,`circles` as c WHERE c.circle_create_id=$id and (p.with=c.id or p.with=1)";//p.with columns contain circle id and as i tell first entry will be public 
$sql_fier=mysqli_query($sql); 
/*-------I think you know how to manipulate fetched data---------*/ 

사회에 나를 연결 네트워크 http://www.funnenjoy.com (로그인/로그인 필요)