현재 스키마에서 볼 수있는 두 가지 문제가 있습니다. 하나는 복합 키가 효과적으로 중복되는지 확인하기 위해 테이블에서 두 필드를 확인 해야하는 문제이며, 일부 집계 데이터는 개별 테이블에 롤업되어 별도입니다. 실체 (특히 승리하지만 잠재적으로 플레이어의 등급).
첫 번째 문제의 경우 복합 키의 필드 중 하나를 원하는 OR 방식으로 처리하는 DB 간 트릭은 없지만 DB가 지원하는 경우 getPlayerTeams(player_id)
캡슐화 하는 함수 를 만들 수 있습니다 쿼리
(또한 정렬 된 플레이어 ID의 해시로 계산 된 team_thumbprint로보기를 만들 수 있으므로 같은 두 사람의 콤보는 항상 같은 지문을 갖지만 여기에는 약간 다를 수 있습니다).
정규화에 대해서는 team_result
표를 사용하여 주어진 팀의 모든 결과를 추적 하여 발생하는 결과에서 엔티티를 분리하는 것을 고려하십시오 . 조금 더 극단적 인 정규화는 또한 player_rating_hist
플레이어에 대한 모든 등급 변경을 포함 하는 테이블을 요구합니다. 현재 등급은 가장 최근 날짜를 기준으로 한 것입니다. 쉬운 조회를 위해 플레이어보기를 사용하여 최신 값을 포함 할 수도 있습니다.
제안 된 스키마 (죄송합니다)
player
id
name
created_on
updated_on
player_rating_hist
player_id (FK)
rating
rating_date
team
id
player1_id (FK)
player2_id (FK)
created_on
updated_on
game
id
team1_id (FK)
team2_id (FK)
team_game
team_id (FK)
game_id (FK)
result
score
rating_change
team_rating_hist
team_id (FK)
rating
rating_date
쿼리 :
--Results for the game, should only ever be two rows for any given game
SELECT * FROM team_game WHERE game_id = 101
--All results for a team
SELECT * FROM team_game WHERE team_id = 123456
이 구조를 사용하면 시간이 지남에 따라 시스템이 실행 된 결과로 발생하는 "콘텐츠"에서 "기본"엔티티 (플레이어 및 팀)를 분리 할 수 있으며 기본 테이블 중 하나를 현재 등급으로 지속적으로 업데이트하지 않습니다. 이러한 값은 파생 된 값이며 가장 최근의 등급, 평균 등급, COUNT
승 또는 손실 등 을 가져 와서 검색해야합니다 . 시스템이 충분히 커지면 이러한 집계 데이터를 별도의 "창고"로 추출하는 것을 고려할 수 있습니다 쉬운 분석을 위해 (동일한 DB에있는 별도의 테이블 집합 인 경우에도) 가능합니다.