2013-02-28 4 views
5

저는 이것을 어떻게 표현할지는 모르겠지만 열이 대체로 교환 가능한 테이블을 구현하는 좋은 방법이 있습니까?상호 교환 가능한 열을 나타내는 법

예 : 사용자 모델이 있고 두 명의 사용자가 '친구'가되도록 허용하고 싶습니다. 분명한 것은 나에게 사용자의 키가 들어있는 두 개의 열 ('friend1'및 'friend2')이 포함 된 테이블을 만드는 것입니다. "(friend1 = user1 AND friend2 = user2) OR (friend1 = user2 AND friend2 = user1)"을 확인해야하기 때문에 "user1 and user2 friends"와 같은 말을하기가 어렵습니다. 그것은 효과가 있지만, 저 테이블에 무언가를 얻고 싶을 때마다 두 컬럼을 모두보고 있다는 것이 저에게는 어색하게 보입니다. 더 우아한 방법이 있나요?

+0

죄송 내가 틀렸다로

class User < ActiveRecord::Base has_many :followings has_many :followers, :through => :followings, :class_name => "User" has_many :followees, :through => :followings, :class_name => "User" end class Following < ActiveRecord::Base # fields: follower_id followee_id (person being followed) belongs_to :follower, :class_name => "User" belongs_to :followee, :class_name => "User" end 

같은 예를 들어

- 그것은 잘 작동하지 않을 것입니다 (쿼리 우정이 잘못 찾을 수 있습니다). 나는 내 대답을 지울거야. –

답변

3

우정 관계를 형성 할 때 중요한 선택은 그것이 양방향인지 결정하는 것입니다. 트위터는 방향성 우정과 페이스 북 우정의 양방향성을 보여주는 예입니다. 당신은 양방향 위해 최선을 다하고 것 같은데, 그래서 당신이 가지고있는이 옵션은 다음과 같습니다

1) 양 방향

select * 
from friendships 
where (friend1 = 123 and friend2 = 456) OR (friend2 = 123 and friend1 = 456) 
에게 확인

2) 항상 FRIEND1으로 낮은 USER_ID와 높은 USER_ID에 넣어 friend2이면 테스트는 한 방향 만 확인하면됩니다. 이것은 유지하기 조금 까다 롭습니다, 그래서 나는 단지 웬일인지 이유로 필요합니다. 당신이 당신의 사용자 모델을 연결하는 조인 테이블을 방법을

+1

양방향 우정은 내가 간다고 생각합니다. 고마워요. 프렌드 = USER1이) 조합 (친구 FRIEND1에서 프렌드 을 선택한 경우에도 두 번째 옵션으로 여전히 어색 쿼리 (예 :이있을 것입니다하지만. 당신이 에있는 사용자 1의 친구 목록에'(친구 에서 FRIEND1 를 선택 = user1)') – user1916823

1

이것을 구현할 수있는 방법은 다소 어색 할 수 있습니다. 아이디어는 friendshipId와 user라는 두 개의 열이있는 테이블에 "friendshipId"를 갖는 것입니다. 이제 사용자는 상호 교환이 가능합니다.

는 사용자 1 및 사용자 친구들 있는지 확인하는 방법은 다음과 같습니다, 제약

select friendshipId 
from friends 
group by friendshipId 
having sum(case when name = user1 then 1 else 0 end) > 0 and 
     sum(case when name = user2 then 1 else 0 end) > 0 

현명한 사용을 트리거, 저장 프로 시저, 친구 관계는 두 명의 사용자가 있는지 확인합니다 그 사람 자체는 친구 할 수없는, 그래서 에.

+0

이것은 데이터베이스 수준에서 가능한 가장 실질적인 방법으로 관계의 본질을 표현하는 좋은 방법입니다. 실제로 도메인과 고유 한 제약 조건과 응용 프로그램 계층의 단순한 도우미 기능을 사용하면 끈적 거리는 트리거 나 성가신 sprocs없이이 작업을 수행 할 수 있습니다. 예를 들어 friends 테이블에 'Position' 컬럼을 추가 할 수 있습니다 (> 0, <= 2,'friendshipID'와 고유합니다). 부팅하려면 필요한 경우 손으로 데이터를 삽입하는 것이 쉬운 일은 아닙니다. 아마도 'having'절이 아닌 self-join으로 friends 테이블을 쿼리 할 것입니다. – WCWedin