릴스를 게시물과 따로 둔다
합쳐도 될 만큼 닮았습니다 — 둘 다 캡션과 좋아요 수가 붙은 사용자의 미디어입니다. 그런데 릴스에는 재생 수가 있고 세로 비율이 고정이며 캐러셀도 위치도 없습니다. 게시물은 정반대입니다. 합치면 타입 플래그에 따라 절반이 null 인 테이블이 되고, 모든 피드 질의가 그 플래그를 걸러야 합니다. 나눠 두면 둘을 함께 보여 주는 드문 화면에서만 union 이 듭니다.
사용자 프로필, 다중 미디어가 포함된 사진 및 동영상 게시물, 시청자 추적이 가능한 인스타그램 스토리, 릴스 숏폼 동영상, 댓글 스레드, 좋아요, 해시태그 검색, 팔로우 관계, 친한 친구 목록, 스레드 기반 다이렉트 메시지 및 하이라이트 컬렉션을 특징으로 하는 인스타그램 스타일의 시각적 소셜 플랫폼용 전체 데이터베이스 스키마입니다.
이 스키마는 계정을 users 와 profiles 로 나눕니다. users 는 들여보내는 데 필요한 것 — 자격 증명, 전화번호, is_private — 을 담고, profiles 는 남에게 보이는 것과 팔로워·팔로잉·게시물 수를 담습니다. 수를 세지 않고 저장하는 이유는 프로필을 볼 때마다 읽히지만 바뀌는 일은 훨씬 드물기 때문입니다.
콘텐츠는 한 테이블이 아닙니다. posts 는 그리드, stories 는 하루 뒤 만료, reels 는 posts 의 플래그가 아니라 자기 테이블입니다. 공유하는 것이 거의 없어서 나눴습니다 — 스토리에는 만료와 시청자 목록이 있고, 릴스에는 재생 수가 있고, 게시물에는 캐러셀과 위치가 있습니다.
팔로우 그래프는 is_pending 을 가진 방향성 테이블 하나입니다. 공개 계정을 팔로우하면 승인된 상태로 생기고, 비공개 계정이면 승인 전까지 대기 상태로 남습니다. 둘이 같은 행이라 요청과 관계가 어긋날 일이 없습니다.
합쳐도 될 만큼 닮았습니다 — 둘 다 캡션과 좋아요 수가 붙은 사용자의 미디어입니다. 그런데 릴스에는 재생 수가 있고 세로 비율이 고정이며 캐러셀도 위치도 없습니다. 게시물은 정반대입니다. 합치면 타입 플래그에 따라 절반이 null 인 테이블이 되고, 모든 피드 질의가 그 플래그를 걸러야 합니다. 나눠 두면 둘을 함께 보여 주는 드문 화면에서만 union 이 듭니다.
follower_count, post_count, like_count, comment_count 는 전부 계산할 수 있는 값입니다. 저장하는 이유는 프로필 한 장이 넷을 읽고 하나도 쓰지 않기 때문입니다. 수백만 행짜리 팔로우 테이블을 세는 질의를 화면 뜰 때마다 돌릴 수는 없습니다. 대가는 카운터와 실제 행이 어긋나는 것이고, 주기적으로 맞춰 주는 편이 매번 정확한 것보다 쌉니다.
story_views 는 몇 명이 봤는지가 아니라 누가 봤는지를 적습니다. 주인에게 시청자 목록을 보여 주기 때문입니다. 카운터였다면 다른 질문에 답하는 셈이고, 이 테이블은 스토리가 만료되면 같이 지울 수 있어서 무한히 자라지도 않습니다.
비공개 계정 팔로우 요청을 따로 테이블로 두고 승인 시 옮길 수도 있습니다. is_pending 으로 두면 승인이 삭제+삽입이 아니라 갱신 한 번이고, 거절은 어느 쪽이든 삭제입니다. "이 사람이 나를 팔로우하나" 도 두 곳을 보지 않고 한 번에 끝납니다.