좋아요와 싫어요는 한 테이블
사용자×영상 한 행에 is_like 를 두면 (user_id, video_id) 유니크 제약이 "한 번만" 을 강제합니다. 테이블 둘이면 좋아요와 싫어요를 동시에 누르는 것을 막으려고 테이블을 넘나드는 검사가 필요하고, 카운터 둘이면 각자 어긋납니다. 의견을 바꾸는 것은 불리언 하나의 갱신입니다.
사용자 계정, 크리에이터 채널, 메타데이터가 포함된 동영상 카탈로그, 플레이리스트, 스레드 방식의 댓글 시스템, 좋아요/싫어요, 구독 관리, 시청 기록, 알림, 채널 수익 창출, 광고 삽입 관리 및 커뮤니티 게시물 기능을 다루는 유튜브 스타일의 동영상 스트리밍 플랫폼용 전체 데이터베이스 스키마입니다.
계정과 채널을 나눴습니다. users 는 로그인하는 주체이자 무엇을 봤는지의 주인이고, channels 는 올리는 주체입니다. 나눠 두었기에 한 계정이 채널 여러 개를 가질 수 있고, watch_history 와 likes 는 사람에게, videos 와 monetization 은 채널에 붙습니다.
특이한 것은 watch_history 입니다. 조회 로그가 아니라 — 그 숫자는 영상에 있습니다 — 시청자×영상마다 한 행이고 last_position_seconds 를 들고 있습니다. 이어보기 기능이 이것입니다. 쌓이는 것이 아니라 보는 동안 갱신되는 행입니다.
좋아요와 싫어요는 테이블 둘이나 카운터 둘이 아니라 is_like 플래그를 가진 한 테이블입니다. 사용자×영상마다 한 행이라 마음이 바뀌면 갱신, 취소하면 삭제이고, "한 사람은 한 번만" 이 코드가 아니라 유니크 제약이 됩니다.
사용자×영상 한 행에 is_like 를 두면 (user_id, video_id) 유니크 제약이 "한 번만" 을 강제합니다. 테이블 둘이면 좋아요와 싫어요를 동시에 누르는 것을 막으려고 테이블을 넘나드는 검사가 필요하고, 카운터 둘이면 각자 어긋납니다. 의견을 바꾸는 것은 불리언 하나의 갱신입니다.
조회 로그는 append-only 로 거대해지고, "어디까지 봤지" 에 답하려면 여러 행 중 마지막을 읽어야 합니다. 시청자×영상 한 행을 제자리에서 갱신하면 이어보기가 조회 한 번입니다. 대가는 세션별 기록을 잃는 것인데, 그것은 다른 기능이고 필요하면 이 테이블을 고칠 게 아니라 별도 테이블로 둡니다.
모든 영상 페이지가 채널의 구독자 수를 보여 주므로 subscriber_count·video_count·view_count 를 channels 에 저장합니다. 계산하려면 페이지를 열 때마다 subscriptions 를 세야 합니다. 저장된 카운터가 늘 그렇듯 원본 테이블이 진실이고 숫자는 주기적으로 맞춰야 합니다.
업로드·처리·공개·비공개를 status 가 담습니다. 영상은 볼 수 있기 전부터 존재하기 때문입니다. published_at 을 따로 둬서 예약 공개가 상태 기계가 아니라 시각이 되고, 공개했다가 일부 공개로 돌렸다가 다시 공개해도 원래 날짜를 잃지 않습니다.