V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
black11black
V2EX  ›  Java

Mysql,千万级大表的分区如何设计?

  •  
  •   black11black · Jun 5, 2020 · 5640 views
    This topic created in 2152 days ago, the information mentioned may be changed or developed.

    如题,最近有一个业务需求是需要存储全国各地的历史天气数据,精确到县级市(大约三千个左右)。粗略估算了一下,就算只存 20 年的历史数据,行数也要有千万级了,这种情况下该如何设计呢?

    表的字段设计应该就是一列 ID (主键自增)、地名、日期(地名和日期合成唯一索引)、天气代号,这样四列。但是现在有一个问题就是,并不是所有地区的数据都能获取完全,比如北京上海这种地方可以获取到很久以前的天气,但是很多县级市只能获取到最近几年的数据,所以对于每个地方而言,需要存储的长度是不相等的。这就导致没办法直接按时间划分,比如每五年的数据分一个区,如果这么干的话会导致各分区大小差别很大。我经验比较浅薄,不知道这种时候该怎么设计了,有带佬指点一下吗

    ===============

    当然还有一些比较取巧的办法,比如天气通常都是连续的,只存每一段天气的开头和结尾日期的话存储端的压力会小很多,但是这样会增加业务端的复杂的,除非存储端搞不定,否则目前暂时不想这么做。

    25 replies    2020-06-07 08:41:01 +08:00
    reself
        1
    reself  
       Jun 5, 2020
    分库分表,稍微具体描述点的话,可以垂直切分或(和)水平切分。

    水平切分的话,根据业务集中度可以平均切分或(和)热点切分,热点可以按访问量、按访问的地理差异、按网络延迟等。

    垂直切分的话,其实类似于读写分离,将写少读多和写多读少的拆开,拆的时候可以是业务级、表级甚至字段级。
    binux
        2
    binux  
       Jun 5, 2020 via Android   ❤️ 2
    千万很大吗?
    shiny
        3
    shiny  
    PRO
       Jun 5, 2020
    线上 MySQL 单表三千万记录,也没什么问题
    escapemars
        4
    escapemars  
       Jun 5, 2020
    大表的存储不是问题,问题是如何查询。所以核心是你的业务需要怎么使用这些数据,比如说直接地名和日期做查询,那我觉得走索引以后不用分库分表都可以搞定。如果要做其他的查询,比如说只安装日期查,那就按照日期做水平分库,只按照地名查,那就按照地名做水平分库。
    lordofhollows
        5
    lordofhollows  
       Jun 5, 2020
    想太多了,20 年数据才千万,哪用得着什么妙招
    dbskcnc
        6
    dbskcnc  
       Jun 5, 2020
    做表分区就可以了,根据业务需要确定分区方式,列不确定加个 Json 字段
    optional
        7
    optional  
       Jun 5, 2020 via iPhone
    不用分区,加内存保证放得下索引就行。
    qloog
        8
    qloog  
       Jun 5, 2020
    一般情况下分表就可以了,常用的分表:根据 id 取模就搞定了,90%的场景都合适。
    roundgis
        9
    roundgis  
       Jun 5, 2020 via Android
    單表過億都沒問題
    kiracyan
        10
    kiracyan  
       Jun 5, 2020
    可以做归档机制,涉及归档数据的时候单独处理
    qiayue
        11
    qiayue  
    PRO
       Jun 5, 2020
    一个城市一张表,数据互不干扰
    UserNameisNull
        12
    UserNameisNull  
       Jun 5, 2020
    我之前单表 1.5 亿数据,没分表,🤣
    sayhello1991
        13
    sayhello1991  
       Jun 5, 2020
    注意你的历史天气数据是不会变的, 想想空间就很大了
    yukiloh
        14
    yukiloh  
       Jun 5, 2020
    以前听说三千万以上是瓶颈,欸,原来上 e 都没关系吗
    glancer
        15
    glancer  
       Jun 5, 2020
    tidb 也很香吧?
    kanepan19
        16
    kanepan19  
       Jun 5, 2020   ❤️ 1
    @yukiloh 三千万 是因为到这个体量, 不好维护, 比如加索引、加字段、迁移等。
    只要索引合适,查询还是没问题的。
    dog82
        17
    dog82  
       Jun 5, 2020
    如果只有 3kw 的数据,不分区也行。——仅仅主键查询的话。
    hash 分区不行吗?
    escapemars
        18
    escapemars  
       Jun 5, 2020
    @sayhello1991 对,不会变的历史天气数据的特点是只增加不修改,完全没必要用 mysql,用 clickhouse,分库分表啥都不用考虑,无脑存,随便一台垃圾配置的机器单表几十亿数据查起来都轻轻松松的。
    594duck
        19
    594duck  
       Jun 6, 2020 via iPhone
    你的历史数据不会改变而且是增量的可以走时间序列数据库。比如 influxdb 。

    如果一定要是 mysql 。按照你的描述没几列。完全支撑得住。千万数据还可以。

    而且你的数据是可以拆分的按年份按城市来做归档表就好。

    加一层 redis cache 也可以。这个优化好做。现在服务器不值钱,redis 在虚拟机就可以了不要放 docker


    也可以直接走阿里的 drds (必要性不大)
    69partner
        20
    69partner  
       Jun 6, 2020
    @594duck 为什么 redis 不能放 docker
    louislivi
        21
    louislivi  
       Jun 6, 2020
    千万还好,上亿级就确实需要好好设计架构一下了
    594duck
        22
    594duck  
       Jun 6, 2020 via iPhone
    @69partner 他这要求肯定是有自己服务器的企业了。没必要用 docker 。数据量 redis cluster 5 分区,每分区 30G 足够了。而且就算是 redis 数据也是长久存储的,要什么 docker 直接 vm 跑着就好了。

    对了虚拟化用 vmware 家的省心。
    sagaxu
        23
    sagaxu  
       Jun 6, 2020
    我是穿越回 2000 了吗? 1000 万也算大表了吗?现在是 2020 年,10 个字段单表 1 亿行也不算大。
    线上单表 2 亿,加字段加索引并不会锁表。迁移的话,10 张 1000 万的表,比 1 张 1 亿的表更麻烦。
    Coolha
        24
    Coolha  
       Jun 6, 2020
    千万没必要吧...只有设计好索引,不影响使用的
    opengps
        25
    opengps  
       Jun 7, 2020 via Android
    合理的设计就没有上限,每次看到这类话题我都秀一下我的这篇文章 https://www.opengps.cn/Blog/View.aspx?id=284&from=v2ex
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5190 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 437ms · UTC 09:41 · PVG 17:41 · LAX 02:41 · JFK 05:41
    ♥ Do have faith in what you're doing.