mysql大数据量下如何分表与查询

问题:

当数据量达到一定规模后,我们就需要进行分表操作了。 这个时候,简单的查询就变的不再简单。 一般我们把分表的字段称为shardingkey。比如订单表使用用户id作为shardingKey,那么问题来了,如果查询的sql中没有用户id怎么办?其他维度的查询怎么办?

唯一主键

一般我们数据库的主键都是自增的,分表后最直接的问题就是主键冲突。最简单的办法就是以唯一的业务字段作为唯一的主键,比如订单号就是全局唯一的。

  • 常见的分布式生成唯一ID的方式:雪花算法Snowflake,还有一些开源的工具,滴滴的Tinyid,美团的leaf。

分表

确定好我们的主键后,就需要根据我们现在的流量大小与增量来考虑分表的大小了。

举个例子,现在我们日单量是10万单,预估一年后可以达到日100万单,根据业务属性,一般我们就支持查询半年内的订单,超过半年的订单需要做归档处理。

那么以日订单100万半年的数量级来看,不分表的话我们订单量将达到100万X180=1.8亿,以这个数据量级部分表的话肯定单表是扛不住的,就算你能扛RT的时间你也根本无法接受吧。根据经验单表几百万的数量对于数据库是没什么压力的,那么只要分256张表就足够了,1.8亿/256≈70万,如果为了保险起见,也可以分到512张表。那么考虑一下,如果业务量再增长10倍达到1000万单每天,分表1024就是比较合适的选择。

  • 逻辑图


    image.png

C端查询

  • 首先是带shardingKey的查询,这个hash后可以直接定位到相对的表。
  • 不带shardingKey的查询,可以在构建shardingKey的过程中,根据常用的字段取模(比如构建订单号中有10位是用户的id号)。这样,在查询与分页查询中,根据这10位用户id就可以定位订单,满足常用的C端查询。

其他端的查询

针对B端的非shardingkey查询,有两个办法来解决。

  • 双写

双写就是下单两份落两份,c端与B端各自保存一份,C端与B端用订单号,用户号查询,,B端用B端的ID作为shardingkey就好了。这种情况下,我们可以采用异步的方式去做B端的表,轻微的延迟不是问题。

image.png

  • 离线数仓或者ES查询
    离线数仓或者ES查询,不管是用读binlog还是MQ消息的形式,将数据同步给数仓或者ES就好了,对于他们支持的数量级,对于各种查询条件就不是问题了,同样可能会有延迟。
    image.png

而针对管理后台的查询,比如运营、业务、产品需要看数据,他们天然需要复杂的查询条件,同样走ES或者数仓都可以做得到。

你可能感兴趣的:(mysql大数据量下如何分表与查询)