zoukankan      html  css  js  c++  java
  • 工作笔记----数据库分表

    1. 背景
      用于存储用户签到数据表中的数据量超过1500万条,在进行查询时相对缓慢决定对其进行分表。

    2. 步骤

      a. 分析业务场景
      该表的使用者为签到用户和运营人员。
      签到用户进行签到时在表中记录的相关信息:uid、时间、ip等。签到用户侧对数据库使用的基本特点是:单条记录写入,访问量大,服务要求高可用。
      运营人员在前端通过uid查询用户的签到信息,业务场景如:用户投诉某天的签到没有统计。运营人员侧需求的基本特点是:大量的批量分页查询需求,或许需要增加多种查询方式。

      b. 明确属性查询范围
      该表的属性查询内容主要为uid,即运营人员查询用户的uid。
      c. 方案设计:
      采用水平分表的方式,按照时间或uid进行分表。
      按照时间:比如半年
      优势:1.扩容简单,只需按照时间增加表即可;2. 查询的数据为近期数据,只需在一个表中按照近期时间查询即可;3.切分策略简单;4.需要修改部分写入和查询的代码:写入操作需要按照时间更新,查询操作需要根据查询数据量进行多表查询。
      劣势:1.请求量不均,总是在新表写入数据;2.当需要查询用户所有签到数据时需要访问所有表,时间慢;3.数据量不均,新增的表数据量会非常少。
      因为劣势2不选择此方案,有1000多个用户签到时间超过600天,证明存在一直签到的用户,那么若按时间分配查询他们的会比较慢。查询逻辑会多写一部分代码。请求量和数据量均比较小,此两项可以不考虑
      按照uid:
      哈希法
      优势:1. 数据量均衡;2.请求量均衡。
      劣势:1.扩容麻烦,若增加新表则需重新哈希,可能会导致数据迁移;2. 写入操作需要更新按照uid哈希结果进行写入,查询操作需要按照uid哈希结果进行查询。若增加新表则需修改代码。
      选择此方案:对3取余扩容会在两年后进行,无论采用什么方案都会修改代码
      范围法
      优势:1.策略简单;2.扩容简单。
      劣势:1.数据量不均;2.不方便增加新用户,现在才4万左右,若增加新用户可能需要增加新表。

      最终结果:哈希法(对3取余)
      采用此方案的原因:
      数据分布均匀,表中数据对3取余后,各个字表中数据量分布均匀,数据增长量分布均匀,按照目前的增长速度大概两年后每个字表中的数据达到1000万。
      mysql> select count(distinct uid),count(uid) from user_*** where uid % 3 = 0 and create_time > 1532238674000 and create_time < 1533189074000;
      +---------------------+------------+
      | count(distinct uid) | count(uid) |
      +---------------------+------------+
      | 14105 | 66926 |
      +---------------------+------------+
      1 row in set (14.55 sec)

    mysql> select count(distinct uid),count(uid) from user_*** where uid % 3 = 1 and create_time > 1532238674000 and create_time < 1533189074000;
    +---------------------+------------+
    | count(distinct uid) | count(uid) |
    +---------------------+------------+
    | 13994 | 66237 |
    +---------------------+------------+
    1 row in set (14.46 sec)

    mysql> select count(distinct uid),count(uid) from user_*** where uid % 3 = 2 and create_time > 1532238674000 and create_time < 1533189074000;
    +---------------------+------------+
    | count(distinct uid) | count(uid) |
    +---------------------+------------+
    | 13964 | 66300 |
    +---------------------+------------+
    1 row in set (17.93 sec)

    mysql> select count(distinct uid),count(uid) from user_*** where uid % 3 = 0;
    +---------------------+------------+
    | count(distinct uid) | count(uid) |
    +---------------------+------------+
    | 346305 | 5288253 |
    +---------------------+------------+

    mysql> select count(distinct uid),count(uid) from user_*** where uid % 3 = 1;
    +---------------------+------------+
    | count(distinct uid) | count(uid) |
    +---------------------+------------+
    | 345785 | 5324079 |
    +---------------------+------------+

    mysql> select count(distinct uid),count(uid) from user_*** where uid % 3 = 2;
    +---------------------+------------+
    | count(distinct uid) | count(uid) |
    +---------------------+------------+
    | 346966 | 5328743 |
    +---------------------+------------+

    d. 执行方案
        (1)在保证用户正常使用的前提下,对数据库进行分表。需要在维持旧表的同时,让数据双写,同时写入新表和旧表,此时让数据往新表导入。
  • 相关阅读:
    JavaScript:原生模拟$.ajax以及jsonp
    Nodejs之路:非I/O的异步API
    Nodejs之路:异步I/O的过程
    同步、异步、阻塞、非阻塞
    spring mvc在普通类中获取HttpServletRequest对象
    Nginx反向代理实现Tomcat多个应用80端口访问
    IIS 7.5配置PHP站点
    程序员与禅师
    MVC一些需要注意的问题
    强制卸载VS2013
  • 原文地址:https://www.cnblogs.com/tf-Y/p/9408536.html
Copyright © 2011-2022 走看看