2013-03-10 2 views
0

이제는 분명하게 보이는 패턴을 발견합니다. 이에 대한 의견이 필요합니다.관계형 모델에서 OneToMany 관계의 성능을위한 일반적인 설계 원칙

관계형 모델에서 테이블 1에서 테이블 2로 일대 다 관계가 있다고 가정합니다. 예를 들어 테이블 1은 사용자 테이블 일 수 있고 테이블 2는 모든 사용자 로그인을 기록하는 로그인 테이블 일 수 있습니다. 한 명의 사용자가 여러 번 로그인 할 수 있습니다. 사용자가 주어지면 해당 사용자가 모든 로그인을 찾을 수 있습니다.

첫 번째 아이디어는 로그인 테이블에만 로그인을 저장하는 것입니다. 이것은 하나의 디자인입니다.

그러나 사용자가 특정 로그인 (예 : 마지막 로그인)에 관심이있는 경우 사용자 테이블 자체에 마지막 로그인 시간을 캐시하는 것이 "일반적으로 좋은 생각"입니다. 맞습니까?

디자인 2는 분명히 중복됩니다. 조인을 수행 한 다음 이전 로그인을 제외한 모든 항목을 삭제하면 항상 마지막 로그인 시간을 찾을 수 있습니다.

한 사용자는 괜찮을 것입니다. 그러나 모든 사용자에게 마지막으로 로그인 한 시간을 SQL 쿼리로 찾으려면 디자인 1에서 불필요한 결과를 필터링하는 조인과 하위 쿼리가 필요합니다.

하지만 우리의 유스 케이스를 고려하면 사용자 테이블 자체에 마지막 로그인 시간을 저장하면 가입을 줄일 수 있습니다. 그게 맞습니까?

스키마를 디자인 할 때 볼 수있는 일반적인 패턴입니까?

+0

현재 세션 ID를 자주 추적하는 데 사용됩니다. – Aiias

+0

방금 ​​예를 들어 이것을 사용했는데, 나는 일반적인 설계 원칙을 많은 설계 원칙으로 언급하고 있습니다. 또한이 커뮤니티 Wiki에 질문을 올리고 싶습니다. –

+0

디자인 단계에서 성능 측면을 평가하고 있습니다. [조기 최적화는 모든 악의 근원입니다] (http://en.wikipedia.org/wiki/Premature_optimization#When_to_optimize) –

답변

0

일반적인 실수 인 TABLE 및 RELATION의 개념을 혼동스럽게합니다. 개념 모델 (사용자 & 로그인)에 두 개의 관계가 있지만 실제로 클러스터되지 않은 색인은 여러 개의 관계를 결합하는 속도를 높이기위한 추가 테이블 일 뿐이므로 실제 모델에서는 두 개 이상의 테이블이 필요합니다.

사용자에 대한 FK 관계를 지원하는 로그인에 INDEX (UserID, LoginTime)가 있으면 클러스터되지 않은 색인이 사용자에 대한 최신 로그인을 찾는 쿼리를 처리합니다. 이 기본 모델을 통해 알려진, 측정 가능한 심각한 성능 문제가 확인 된 경우에만 (모든 비정규와 마찬가지로) 비정규 화 된 테이블에 대해 다른 모든 읽기 및 쓰기 작업에 대한 성능 저하가 발생하므로 비정규화할 것으로 보입니다.

+0

흠 ... 흥미 롭습니다 ... 요점을 놓치고 있습니다 ...하지만 모든 사용자의 최근 로그인을 쿼리 할 때 나는 아래와 같은 쿼리를 생성합니다 : 'SELECT user.id, login.login_time FROM USER 사용자, LOGIN 로그인 WHERE user.id = login.user_id AND login.login_time> = (LOGIN에서 login_time을 선택하십시오. 여기서 user_id = user.id)'. 그 맞습니까? 클러스터되지 않은 인덱스는이 쿼리의 속도를 어떻게 올릴 것입니까? 이 인덱스가있는 경우 다음 쿼리가 더 빠릅니까? 'U.id, L1.login_time을 USER U1, LOGIN L1, LOGIN L2 WHERE U1.id = L1.user_id 및 U1.id = L2.user_id 및 L1.login_time> = L2.login_time'에서 선택하십시오. –

+0

이러한 쿼리에는 몇 가지 문제가 있다고 생각됩니다. 문제를 해결하는 방법을 찾아야합니다. 이 조인이 '클러스터되지 않은 인덱스'를 사용하는 것이 효율적이라면 hbm2ddl을 사용할 때 hibernate에서 이러한 인덱스를 생성하고 JPQL이보다 효율적인 SQL 쿼리로 변환되도록해야합니다. 어떤 경우에는 중복 열을 만드는 것만으로 최종 데이터 분석 속도가 훨씬 빨라지는 것을 보았습니다. 관련 클러스터되지 않은 색인을 만들지는 않았지만. –

+0

u.UserID, UserName, UserName에 의해 u.UserId = l.UserID 그룹의 u "Join UserName, u.UserID, LastLoginTime = Max (LoginTIme)"쿼리가 클러스터되지 않은 인덱스에 의해 덮여 질 것입니다. –

관련 문제