这是我做一个项目,现在用系统设计的思路来分析一下。
Scenario:
- 用户登录,登出
- 系统根据用户的地理位置,给用户显示附近的event
- 用户Like一些event
- 用户查看以前like过的 event
- 系统根据用户的历史记录向用户推荐他可能like的event
Service:
- Search Service
search(location, event type) - History Service
history(user_id) - Recommendation service
recommendation(user_id, location)
Data model
- User Table
user id, name, password - Event Table
event id, name, discription, location, time, rating, address, url, geohash - Like History Table
event id, user id, maybe timestamp - Category Table
event id, category
Working solution
用户登录之后,要用户的location, 通过用户的browser 要location, 要不到的话就从用户的ip address要用户的location. 然后转换成geohash,然后拿着这个geohash信息去找ticketmaster要附近的event。 event来了之后我先存在数据库里,然后再返回给前端一些json.
History比较简单不写了
推荐: 根据用户的id,去查他所有favorite的event, 然后统计Category出现的次数,从高到低排序,然后拿着用户的地理位置和category,去找ticketmaster要这些category的event。在拿到这些event里面我按先按category排序,再按距离排序,再filter掉那些用户已经like过的,然后返回给前端一堆JSON.
如何记录用户的登录状态:Session Key.
前端的流程: 先把用户direct到登录界面。 用户登录以后,向浏览器要用户的location, 要不到location的话就从ip地址要location, 然后通过ajax call发送请求给后端要这个location附近的event. 然后处理返回值,通过javascript修改页面。
当用户点了history之后,就通过ajax call向后端要用户的以前like过的event. 然后根据返回值更新页面。
当用户点了recommendation 之后, 就通过ajax call向后端要推荐。然后根据返回值更新页面。
Storage:
SQL,因为主要都是结构化的信息,所以SQL肯定可以做。用No SQL也可以。
Scale:
对用户table,Like History Table按用户id sharding
对event table 也可以根据event的地理位置分组 也可以根据event id sharding,略有区别,我喜欢按地理位置sharding的idea
为了避免多次call ticketmaster API, 可以记录一下对每一个geohash上次查询时间。先看这个geohash是多久之前查的,如果刚查过就直接从数据库里找就行了。
需要加一个table Last Query: geohash, timestamp
可以加cache。