您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 Code iProcess 课程 认证 咨询 工具 火云堂 讲座吧   成长之路  
会员   
 
   
 
  
每天15篇文章
不仅获得谋生技能
更可以追随信仰
 
     
   
 订阅
  捐助
MongoDB表的设计
 
568 次浏览     评价:  
 2018-3-19 
 
编辑推荐:
本文来自于csdn,文章大概分为八部分介绍,最后运用场景叙述。

1、Collection Sharding是否靠谱

Sharding key的一些烦恼;

单一key可能导致分布不均匀;

使用符合Sharding KEY

复合sharding key也不是万能的;

Count计算性不准确;

Balancer不够智能,时间不确定;

禁用Auto-Sharding功能不可靠(尤其是2.X版本);

线上禁用Auto-Sharding

开启库级Sharding;

固定分片;

手动分片、分表;

完全控制并取得较好结果;

2、Free Schema真的Free吗?如何应对

Free Schema意味着重复的Schema;

每个文档都需要有Schema(重复存储的代价);

Free Schema意味着ALL Schema,需要知道所有schema并且进行查询与解析;

尽量表中Schema都是固定的,将会大大简化程序复杂度;

尽可能减少字段名,数据存储压缩(字段名称都一样、压缩比高、zlib type compression、减少存储空间、减少访问压力);

3、字段名如何进行选取

FreeSchema意味着重复存储,存储空间浪费;

字段名尽量短地存储;

1.6billion(243-183=60GB);

减少字段名将会带来可读性的问题,应用层做字段的映射;

4、_id如何进行生成

collection级doc唯一标示,集合内部唯一;

文档主键,默认为12字节,24位的字符串,_id在服务器端生成;

在客户端生成合适的_id,例如IM用户可以使用unit64_t作为id;

在业务层统一生成(_id生成器,twitter snowflake保证生成唯一性);

5、索引如何设计

原理:内存处理速度比硬盘快100倍,加快索引速度;

索引类型:唯一性索引(索引项的唯一),联合索引(支持前缀查询);

返回某些字段,将这些字段都放在索引中;联合查询,支持前缀查询(前面的节点可以利用索引);返回95%的集合文档,小数据量索引建议使用索引;后台索引,background:true,不允许暂停数据库访问,可以在后台构建索引,仍然占用写锁,但是会释放给业务读写操作;MongoDB对外读写性能会下降;

索引副作用,增、删、改的开销;

索引是否合理,explain+hint命令;

6、空间地理索引是否靠谱

空间地理索引兴起;

使用gps进行查询

地理空间索引不太靠谱(可以通过搜索业务搞定)

7、Collection设计原则

RDBMS与MongoDB的对照

数据库、表/集合、行/文档;

三范式与嵌套;

存储用户及地址;

一对一原则(用户信息表,类RDBMS类型);

一对多原则(在线消息表,1:类RDBMS类型;2:MongoDB嵌套方式(单条16MB限制));

多对多原则(User与Team关系,类RDBMS(Team、User、Relation),MongoDB(User存储teamid(不包含时,可以在Team中建立索引),Team存储userid(不包含时,可在uid上创建索引)));

8、数据量较大时如何进行Sharding

Collection Sharding;

手动Sharding;

混合ID查询(商品表,在不同查询条件时将一些id打入另外一些id中);

场景分析:设计QQ即时通信业务

用户信息表(userinfo)中存储了用户id、用户名字、用户昵称、用户签名、用户信息表生成时间戳信息,用户信息表约有1亿条记录。

在线消息表存储用户之间的聊天消息,包括发送人、接收人、消息时间、消息内容等。每天消息量约200w条,消息需要保存6个月。

群组表存储了用户加入群的关系。一个群可以有很多群成员,一个用户也可以加入很多个群。群的规模约100w个,一个群的最多可以加入100个用户,一个用户最大加入100个群。

首先,对整个业务场景进行分析,从即时通信的要求我们可以看出,主要的业务集中于收发消息,从收发消息的类别又可以分为群消息与个人消息;

之后,在确定基本业务之后对数据进行大概估算,用户信息1亿条,大概需要1亿*1k(每条记录1k),约100GB存储空间;用户消息200w*60*30*1k(每条记录1k),约360GB存储空间;群组表,100w*10k(用户及群组相关信息10k),约10GB存储空间;

接下来,对业务进行分析,从逻辑上来看,用户的信息在访问上应该是相互独立的,所以用户信息的存储保证较为随机的存储即可,同时,又不会出现顺序访问的情况,所以用户信息通过简单的hash进行分片即可;另外,用户的群组信息,与用户一样,在分布及存储上是较为独立的,所以可以访问时可以保持相应的独立性即可;在实时消息方面实时消息其实是一个用户回话的过程,在存储方面需要进行一定的计算,同时会有一定的时效性需要按时间进行排序,所以此时的消息最好是采用复合的片键,并且加入时间;

最后,在数据结构设计方面,用户和群组之间是多对多的关系,所以需要在结构方面包含用户的信息,同时用户也需要包含群组的信息,此时在数据结构上将会有一定量的增加,主要是用户表需要包含群组的id,这方面增加数据量大约不超过5G所以可以忽略。此时数据结构的设计为用户包含群组id、群组包含用户id。消息还是按照之前的消息进行存储,使用接收者、发送者构建联合的sharding key,同时,对消息进行接收者、发送者、时间构建联合索引(因为在消息访问时一般都会是确定接收者与发送者的),此时群组消息的接收者将是群组,如果用户可以通过查询群组信息查看消息;

   
568 次浏览  评价: 差  订阅 捐助
相关文章

我们该如何设计数据库
数据库设计经验谈
数据库设计过程
数据库编程总结
 
相关文档

数据库性能调优技巧
数据库性能调整
数据库性能优化讲座
数据库系统性能调优系列
相关课程

高性能数据库设计与优化
高级数据库架构师
数据仓库和数据挖掘技术
Hadoop原理、部署与性能调优
 
每天2个文档/视频
扫描微信二维码订阅
订阅技术月刊
获得每月300个技术资源
 
 

关于我们 | 联系我们 | 京ICP备10020922号 京公海网安备110108001071号