大型网站上亿得用户数据表怎么分表?

笔者曾经在一家游戏公司待过,有次有个需求是要查找一批所有用户的idfa 和imei 信息给运营那边去做广告投放,因为这个需求笔者看到了我们系统的用户数据,每张表大概有2百多万数据,这样的表大概有20多张。表的名称是user_aa,user_ab,user_ac ... 等等,笔者就挺好奇他们是根据什么规则去分表的,以及是如何查询的。
要解决的一些问题:
1: 用户表分表首先要解决的是用户的id 问题,不可能每个表都搞个自增字段,这样就会乱套。
(1) 首先会想到使用一个公共的库去专门生成user_id,貌似是能解决问题,但是这样会有一个缺点就是所有的注册用户都要先经过这个公共的库,高并发的情况下可能是系统的瓶颈所在。
(2) 使用uuid, 简单来说就是搞个算法生成一个不会出现重复的字符串来作为用户的标识,这样就不用专门搞个库去生成user_id 了,但是uuid并不适合做主键,一方面是它太长(导致占用的空间大),另一方面就是它是无序的(会导致大量的随机IO)。
(3) snowflake算法(主流方案)
下面笔者从网上找到一张图来展示这种算法生成的id的结构

p.png

SnowFlake所生成的ID一共分成四部分
(1) 第一位,占用1bit,其值始终是0,没有实际作用
(2)时间戳 占用41bit,精确到毫秒,总共可以容纳约140年的时间
(3)工作机器id ,占用10bit,其中高位5bit是数据中心ID(datacenterId),低位5bit是工作节点ID(workerId),做多可以容纳1024个节点。
(4)序列号 占用12bit,这个值在同一毫秒同一节点上从0开始不断累加,最多可以累加到4095。
这种算法在同一毫秒内可以生成1024 X 4096 = 4194304个id, 已经满足绝大多数并发场景了。但是它的缺点其实也是显而易见的,就是依赖系统的时间,假如某台机器的时间调回去了,那么是由可能生成相同的id的,所以需要我们去做一些处理才能保证。

2. 根据什么规则去分表?
比如一个新的用户注册进来,那应该把这个新的用户分到哪张表呢?
(1)有一种比较省事的做法是直接按照日期来,把一段时间内注册的用户全部放入一张表,超过日期的放入另外一张表,或者说是一张表数据量超过设置的量后就插入到另外一张表。这么做也很方便后面再加表,缺点就是数据集中插入了,并没有解决并发的问题。
(2) 前面我们说了如何去生成user_id,那么我们可以根据user_id 去分表,user_id 的获取:如果是新用户注册那么就生成一个新的user_id;如果是旧的用户登录呢?那我们应该要先根据用户名去查找到user_id, 然后再根据user_id去用户表里面搜索,也就是要做一张映射表,那说到映射表,有小伙伴可能会说这个映射表数据量大了不要做分表么?如果要分表怎么分? 其实我们可以使用用户名去做分表。
3. 数据拆分后怎么做查询?
这个问题一般是要查询多张表的数据,其实可以借助于一些数据库中间件或者将数据导入到es。

你可能感兴趣的:(大型网站上亿得用户数据表怎么分表?)