2012-01-18 4 views
2

내 사용자가 우정을 서로 연결할 수있는 테이블을 만들고 싶습니다. 동시에이 테이블은 여러 다른 테이블 간의 일대 다 관계가 될 수있는 작업과 연계하여 작동합니다.mysql DB에 우호 협회를 저장하는 올바른 방법은 무엇입니까

지금 나는이

MEMBER_ID 같은 것을 생각하고,

MEMBER_ID가 통화를 사용자의 열, friend_id는 그들이 친구의 컬럼 될 것 활성, 날짜, friend_id 묶으려는 시도는 0 = 보류 중, 1 = 활성, 토글 중 하나 일 수 있습니다. 날짜는 해당 행의 마지막 활동이 기록 된 날짜 일뿐입니다.

내 혼란은 내가 일반적으로 member_id를 쿼리 한 다음 관련 friend_id의 나머지 쿼리를 기반으로 올바른 사람들에게 데이터를 표시하는 것입니다. 그래서이 논리를 염두에두면 요청 당 2 개의 행을 가져야한다고 생각합니다. 하나는 요청하고 그 요청에 friend_id 요청한 member_id 테이블에 삽입 한 다음 하나는 그 반대는 그래서 매번 그에 따라 쿼리 할 수 ​​있습니다. 따라서 본질적으로이 특정 테이블에 요청 된 모든 하나의 작업에 대한 이중 디 핑과 같은 방식으로 작동하도록 2 개의 동작을 만들어야합니다. 최적화가 이루어질 때까지는 내게 의미가 없습니다. 그래서 내 모든 질문에이 같은 관계에 대한 데이터를 처리하는 적절한 방법은 무엇입니까? 아니면 실제로 이것을 다루는 접근 방식에 대해 진지하게 생각하고 있습니까?

+0

첫 번째 모델은 완벽하게 작동합니다. 두 번째 부분은 두 방향을 모두 찾았으므로 여기에는 이미 많은 해답이 있습니다. 짧은 버전 : 약간의 fancyfull 및 귀하의 선택 쿼리를 구축하면 두 방향을 쉽게 얻을. –

답변

6

우정이 인 경우 항상 개일 경우 간단한 쿼리를 위해 데이터 중복성 (즉, 양방향으로 행이 있음)을 선택하거나 약간 더 복잡한 쿼리로 생활하는 법을 배울 수 있습니다. 다른 이유가 없으면 개인적으로 데이터 중복을 피할 것입니다. 공간과 성능을 낭비하는 것이 아니라 강제 할 때 조심해야합니다. 간단한 CHECK는 다른 행을 참조 할 수 없으며 DBMS 트리거는 돌연변이 테이블로 할 수있는 일이 제한 될 수 있습니다.

쉬운 방법 우정 당 하나의 행 수 있도록 항상 (를 시행하는 제약 CHECK (member_id < friend_id)을)를 member_id 낮은 값과 friend_id에서 높은 값을 삽입하는 것입니다. - 당신은 쿼리 할 때 다음, 당신은 두 방향에서 검색을해야합니다 예를 들어, (person_id로 식별) 지정된 사람의 모든 친구를 찾는 것은 같은 것을 보일 것이다 :이 계획에

SELECT * 
FROM 
    person 
WHERE 
    id <> :person_id 
    AND (
     id IN (
      SELECT friend_id 
      FROM friendship 
      WHERE member_id = :person_id 
     ) 
     OR 
     id IN (
      SELECT member_id 
      FROM friendship 
      WHERE friend_id = :person_id 
     ) 
    ) 

BTW을, 당신 member_idfriend_id의 이름을 friend1_idfriend2_id으로 변경하고 싶습니다.

+0

참고 : 위의 코드에서 IN 키워드를 사용하는 것은 MySQL에서 최적화되지 않았으므로 좋지 않습니다. 큰 테이블에서는 느린 결과가 발생할 수 있습니다. – maliayas

+0

@maliayas 예, MySQL은 하위 쿼리를 최적화하지 않는 경향이 있습니다. 이 특별한 경우의 실제 문제인지 여부는 실제 양의 데이터에 대한 측정을 수행해야만 결정할 수 있습니다. 나의 성능은 여기에 성능 문제가 없어야한다는 것이지만, 내가 틀렸다면 MySQL의 결함 (예 : JOIN)을 피할 수있는 동일한 쿼리를 본질적으로 표현할 수있는 다른 방법이있다. –

1

Beautiful - 테이블에는 아무런 문제가 없습니다. ALSO

: 내가이 기수는 "많은 한"경우 확인 또는 "많은 많은"아니에요 :

http://en.wikipedia.org/wiki/Cardinality_%28data_modeling%29

Q : 내가 쿼리 할 수 ​​있었다 나는 쿼리 일반적인 방식 MEMBER_ID를 위해 다음 따라 적절한 사람

A를 데이터를 표시하는 관련 friend_id의 오프 쿼리의 나머지 기초 : 솔직히, 나는이 표시되지 않습니다 "회원에게 친구"또는 "친구에게 회원"으로 질문하는 문제 (또는 다른 조합 (예 : 친구를 공유하는 친구). 다시, 그것은 좋아 보인다.

users 
user_id, name, ... 

friendship 
user_id, friend_id, .... 

select u.name as user, u2.name as friend from users u 
    inner join friendship f on f.user_id = u.user_id 
    inner join users u2 on u2.user_id = f.friend_id 

나는이 그냥 예를 들어 쿼리를 넣어, 당신은 무엇을 매우 유사하다 생각 :

0

는 도우미 테이블과 같이 소개합니다.

+0

관계의 양측이 추가 된 경우 중복되는 항목이 될 수 있습니다. – Kenaniah

+0

열의 이름이 실제로 표시되는 것은 아닙니다. 양방향 관계가 추가 된 경우 두 행이 의미가 있습니다. –

+0

두 개의 행 출력은 조인 구조를 복잡하게 만들며, 그렇지 않으면 조인 된 데이터에 중복을 초래할 수 있으므로 별개의 집합을 반환하기 위해 GROUP BY를 추가해야합니다. – Kenaniah

5

두 가지 방법이 그것을보고 :

WHERE ((friend_id = x AND member_id = y) OR (friend_id = y AND member_id = x)) 

은 단순히 관계의 한 측면을 진술하여 조회 할 수있다. 양측이 추가되면,이 메소드는 중복 행을 리턴하지 않고도 작동합니다. 쿼리가

WHERE friend_id = x AND member_id = y 

으로 구성되도록 관계의 양쪽을 추가 반대로

뿐만 아니라, 쿼리 작성하기 쉽고, 또한 (더 나은 DB의 성능을 의미) 계획하기 쉬워집니다.

내 투표는 후자의 옵션입니다.

관련 문제