本人是mongoDB新手,看过了官网上关于嵌入式非规范化数据库的介绍,但是面对实例的时候仍然是一头雾水.(官网上面的实例只有两三个collection,感觉比实际应用简单太多)
每年一个赛季,一个联赛对应多只队伍,每个队伍有多名队员.队员属性有身高体重所属球队球衣号码场上位置(队员有可能转会,但某一特定时间只属于一个球队).联赛有常规赛,季后赛之分,每场比赛有主/客队,需要记录下每个上场队员的得分/篮板/助攻/盖帽/抢断以及每一个事件的时间戳.每场比赛对应多个新闻报道文章
典型应用场景:
最新10场比赛的主/客队得分,胜负
所有球队的积分排名
所有球队在本赛季的平均得分/篮板/助攻/盖帽/抢断 前10名排行榜
所有球员在本赛季的平均得分/篮板/助攻/盖帽/抢断 前10名排行榜
某场比赛中主客队球队本场比赛的得分篮板助攻命中率等
某场比赛中主客队球员在本场比赛的得分篮板助攻命中率等
所有球员在某个赛季中的各项数据排行
某个球员在各个赛季中的平均各项数据(转会过的球员有可能在不同球队)
可否给出一完整的数据模型结构设计,万分感谢!
一些想不明白的问题:
是否应该把球员嵌入到球队中?如何处理转会问题?
是否应该把每场比赛的数据嵌入到每场比赛中?如果是,又如何关联球员与每一次得分/..事件的关系?
在哪里非规范化数据,感觉不管怎么设计,在汇总球队,或者球员的历史数据的时候,和做排名的时候,都要扫描整个数据库,这不科学吧...
在哪里做索引可以显著的提高性能?
这个应用场景到底合适不合适用nosql.................
大的原则是根据 Access Pattern 来设计,幸运的是我们已经有典型应用场景了。
球队-球员的一对多关系,嵌入或者分开都可以,主要是看这两个数据是不是经常在一起使用。一起用的例子:SegmentFault的问题和答案,也是一对多,但是经常一起显示。如果不一定,也可以分开,然后在球队里加入球员的名字,_id,效力时间等基本信息,这样的 denormalization 就需要更新的时候多更新一个地方了。但是由于这个信息的更新(比如转会)频率很低,读非常多,所以还是值得的。
统计。如果重新计算球员的历史数据,不论用什么数据库存,都需要遍历整个数据库,对吧?这就又是一个读写之前的权衡了。显然数据更新相较查询少了很多,缓存下统计数据是有意义的。再者,有些统计数据是不变的,比如给定赛季一个队伍的数据。更新的时候,可以实时更新,也可以缓存下一些中间结果,比如平均值来自总数和次数,帮助计算。或者,每场结束后、每天更新一次都是可能的办法。
每场比赛的数据与比赛有关,也与球员有关,但是它经常跟某一个同样查询么?如果不是,而只为统计服务,放到单独的 collection 里也挺好。
索引能帮你更快地找到数据,但是不能帮你减少结果数据集。数据模型设计出来,选索引就是很自然的事情了。