Database design
- video-count
- <video_id, hashed_id(location_coodinates_of_viewer), count>
- video_id: represent the unique id of the video
- hashed_id(location_coordinates_of_viewer): takes the hash of the location_coordinates(long, lat) with modulo(lets say 100). This is there to minimize the concurrent-updates(write call blocker) on a single video_id, hence we would be having at max. 100 records per video(trending ones). We could also leverage range-based hashing for the {lat, long}, hence keeping together the closer co-ordinates in a single record(this would cause some skewness, and hence write-blockers, when we have some trending video at a regional level only. So, going forward with hash-based approach seems better.
- count: the count for that particular hashed(location_coord).
- Since, this table looks pretty straightforward, we could go with key-value based database, this one guarantees single digit microsecond latency, with DDB, we have to get all the count-records for a particular video-id(at max. 100 records would be there) and then in-memory calculating the sum.
- There is one more option, that we can go with sql and use a query like select sum(count) where video_id=<id> group by video_id, since we have only 100 records, it would be a bit faster only, else we could leverage hyper-log-log to approximately give us the live-count for a video with very less margin of error.
We will also have one redis kind of DB(recent-visitors) in place, which will have TTL of 5 seconds for each record, it is having data like
- {<video_id>, <user_id>, <timestamp>}
- It indicates that for the video_id, user_id had last-watched the video at time: <timestamp>
- There will be only one record per <video_id>, <user_id>.. in this case, our <video_id> becomes the partition-key and <user_id> will become the sort-key.
- We can just fire the call like select timestamp where video_id is "" and user_id is "" to figure out the last viewed timestamp.
- We will also have one flow for analytics purpose:
- We can publish the view-event to a persistent store using some analytics service.
- Then later on, we could write spark-jobs to normalize/filter out the data and form user-preferences, trends, recomendation service/ML models.