2010-07-22 4 views
0

짧은 데이터베이스 스키마 :도움말

    많은 카드
  • 카드 (author_id, GAME_ID, 내용, created_at)
  • game_views이 있습니다 (ID)
  • 게임 (current_player_id) //
  • 사용자 (GAME_ID, USER_ID) // 쇼 게임 사용자가

내가 사용자을위한 게임을 찾을 필요가 본 적이있는 그 규칙을 모두 충족 : (내 생각 created_at에 의해 순서) 사용자 게임에서 마지막 카드의

  • 저자 (게임이 지금 누구에 의해 연주하지 않음)

    1. 게임의 current_player NULL이 아니다
    2. 게임은 사용자

    내가 PostgreSQL의를 사용하여 볼되지 않았습니다.

  • 답변

    0

    이것이 가장 확실한 해결책이라고 생각합니다. 적절한 인덱스를 사용하면 게임의 수를 수백만 개로 늘리면 성능은 합리적이지만 잘 확장되지 않습니다. 그런 경우 성능을 향상시키는 한 가지 방법은 마지막 card_id를 게임 레벨에 저장하는 것입니다.

    select game_id 
    FROM game g 
    WHERE g.current_player is null 
    AND not exists (select 0 from game_view gv 
          where gv.user_id = v_my_user_id and gv.game_id = g.game_id) 
    AND not exists (select 0 from 
        (select author_id from cards c where c.game_id = g.game_id order 
        by created_at LIMIT 1) 
        t1 where t1.author_id = v_my_user_id) 
    
    0

    이 코드는 SQL Server를 염두에두고 작성했지만 Postgres에서 작동해야합니다. 그렇지 않은 경우, 차이는 최소한 afaik이어야합니다.

    이 솔루션은 효과가 있습니다 (저는 Postgres를 여기에 설치하지 않았습니다).하지만 큰 데이터 세트를 위해이 솔루션을 최적화하고 싶을 수도 있습니다. 인덱스, 통계 등을 사용합니다 (보통).

    SELECT DISTINCT games.game_id FROM games INNER JOIN cards ON games.game_id = cards.game_id WHERE games.current_player_id is NULL and games.game_id in (SELECT DISTINCT game_id FROM GAME_VIEWS WHERE user_id != 666) and cards.author_id != 666 GROUP BY games.game_id ORDER BY cards.created_at DESC 
    

    "666"은 실제 ID로 다시 교환하십시오. 도움이 되었기를 바랍니다.

    +0

    미안하지만, 내가 원하는 것을 오해 한 것 같습니다. 한 번에 모든 규칙을 충족하는 게임을 찾고 싶습니다. – yukas

    +0

    아, 그래. Lemme 편집. –