기사의 현재 위치는 행이 아니라 컬럼
배차는 지금 가능한 모든 기사의 최신 위치를 지금 알아야 합니다. 몇 초마다 ride_tracking 에 행을 쌓으면 배차 질의마다 기사별 최신 행을 찾아야 합니다. 제자리에서 덮어쓰는 컬럼 둘이면 평범한 인덱스 스캔이 됩니다. 이력을 잃는 것도 아닙니다 — ride_tracking 이 운행 중에만 남기는데, 경로가 필요한 때는 그때뿐입니다.
드라이버 및 차량 관리, 실시간 운행 생애 주기 추적, GPS 경로 로깅, 동적 탄력 요금제, 요금 추정, 결제 처리, 상호 평점 시스템, 드라이버 수익 관리, 프로모션 및 고객 지원 티켓 관리를 특징으로 하는 우버 스타일의 승차 공유 플랫폼용 프로덕션급 데이터베이스 스키마입니다.
한 계정이 승객이면서 기사일 수 있어서 users 가 둘을 다 담고, driver_profiles 는 운전할 때만 성립하는 것 — 면허, 상태, 평점, 그리고 현재 위치 — 만 담습니다. 마지막 두 컬럼이 특이합니다. current_latitude·current_longitude 는 계속 덮어써지며, 그래서 추적 테이블이 아니라 기사 행에 있습니다.
운행은 시간이 지나며 채워지는 행입니다. requested_at·accepted_at·started_at·completed_at·cancelled_at 이 상태 이력이 아니라 각각의 시각이라, 한 행에서 생애주기가 읽히고 "기사가 수락까지 얼마나 걸렸나" 가 뺄셈이 됩니다.
돈은 세 번 적히고 셋은 서로 다른 숫자입니다. rides 에는 산정되고 청구된 요금, payments 에는 승객이 실제로 낸 금액, driver_earnings 에는 기사의 총액·수수료·순액이 있습니다. 합치면 차액이 어디로 갔는지 답할 수 없게 됩니다.
배차는 지금 가능한 모든 기사의 최신 위치를 지금 알아야 합니다. 몇 초마다 ride_tracking 에 행을 쌓으면 배차 질의마다 기사별 최신 행을 찾아야 합니다. 제자리에서 덮어쓰는 컬럼 둘이면 평범한 인덱스 스캔이 됩니다. 이력을 잃는 것도 아닙니다 — ride_tracking 이 운행 중에만 남기는데, 경로가 필요한 때는 그때뿐입니다.
status 는 지금 어디인지를, 다섯 개의 시각은 어떻게 왔는지를 말합니다. 상태 이력 테이블도 같은 질문에 답하지만 조인과 정렬이 필요합니다. 이렇게 두면 수락 시간·운행 시간·취소율 같은 지표가 전부 컬럼 둘의 뺄셈이 됩니다. 한계는 같은 상태에 두 번 들어갈 수 없다는 것인데, 운행에서는 그게 오히려 맞습니다.
base_fare·total_fare·surge_multiplier 를 ride_types 에서 다시 구하지 않고 운행에 복사합니다. 요율은 바뀌고 할증은 순간적입니다. 자기 가격을 재현하지 못하는 운행은 고객에게 설명할 수 없는 운행입니다. ride_types 는 현재의 요금표이지 과거의 요금표가 아닙니다.
promotions.uses_count 는 max_uses 를 보는 싼 검사이고, promo_usages 는 누가 어느 운행에서 무엇을 썼는지를 적습니다. 이것이 없으면 "1인 1회" 를 강제할 수 없고 분쟁이 생긴 할인을 추적할 수 없습니다. 카운터는 빠른 길, 행이 진실입니다.