一、业务背景
电子书籍的阅读,用户可以添加读书计划,也可以加入到自己的书架里。在检索的时候,支持按年龄段和类别等条件来查询书籍列表。
二、数模设计
一本书归属于某类目(也是某个业务类型),一个类目可以配置多个属性,一个属性配置多个选项。相应地,一本书拥有多个属性及多个选项。一本书可以来源于Kara,也可能来源于其他。
一个用户可以把一本书加入到自己的书架,也可以对它进行创建读书计划。
统计功能,统计每本书的阅读人数、加入书架数、阅读时长、加入计划的人数、完成计划的人数。
灰度用户名单,内部测试用户,可以查看到“灰度”的书本。因为一本书在导入或新增的时候,显示状态默认是隐藏,也即对外不可见。只有验证无误后,才把显示状态更新为正常,此时用户才能够看得到这本书。同理,类目的属性也是默认为隐藏状态,后面手动去修改为正常状态。
![](https://img.haomeiwen.com/i4353488/03253b19d0dd5176.png)
三、总体设计
引入bizId--业务ID,用于区分不同的展示平台,表示不同的业务。
3.1、属性property及选项item
- 年龄段:1-3岁,4-6岁,7岁以上
- 类别:科学,历史,人文......
重要的字段有: - visible (对外部用户是否可见):0-不可见,1-可见
- weight(排序)
- code(编码,又分为propertyCode和itemCode)
- name(名称,又分为propertyName和itemName)
3.2、书本的来源
- kara
3.3、类目
- 110业务(阅读业务)
- 111业务(电子书城)
3.4、书本
重要字段有:
- bookId
- visible (对外部用户是否可见):0-不可见,1-可见
- categoryId
- bizId
- originId
- paymentType(付费类型):0-免费,1-现金,3-积分
- price(单价)
- type (书本类型):0-电子书,1-纸质书
- customProperties(自定义属性,示例[{"key":"teacherIds","value":"27954,29071"}]),用来扩展存储其他的和书本无关的,和不同的业务有关的信息
- weight(权重,用于排序)
基本属性
- code (书本编号),唯一值,判断书本是否为同一本书。
- name(书本名称)
- desc(描述)
- author(作者)
- press (出版社)
- cover(封面)
- linkUrl(书本链接)
- wordNum(书本字数)
- readCost(阅读耗时)
3.5、书本统计
重要的字段有:
- bookId
- version
3.6、灰度用户名单
重要的字段有:
- userId
- mobile
- bizId
3.7、书本的属性及选项
- bookId
- propertyCode
- itemCode
四、CQRS
上面讲述的数模关系,主要是增删改,如果是要应对复杂的查询需求,我们更倾向于使用CQRS的思想,对mysql关系型数据库的表和数据进行重构,异步同步数据到ES索引里。
这里采用事件驱动的方式,具体实现交由google guava等框架。
在书本录入的时候,我们会利用mysql的事务机制,保证mysql表里的数据一致,然后发布一个异步事件(书本新增),而后在事件订阅者中,更新es索引。
同样,在书本编辑或删除的时候,也会发布一个异步事件,只不过事件类型不同。
有一点需要注意的是,书本的属性选项值,需要重构到es索引的字段private Set<String> itemValues;
五、灰度的测试
上文有重点讲到,需要对属性选项表和书本表,增加一个对外可见性字段,查询接口中,当userId是属于灰度用户名单,就查询全部,否则只查询对外可见。
六、事件梳理
- 阅读计划的状态变更
- 书架的放入、移除
- 书本的录入、编辑、删除
七、业务指标梳理
- 在线用户(按最近的上报来判断是否在线)
- 排行榜,分析书的阅读次数、人数、时长
- 计划完成情况,分析多少人按时完成,多少未完成,完成的数量,未完成的数量
- 跟踪书架上的书,分析多少人在加入书架,分析多少书被加入到书架,反之,移除情况的分析。
网友评论