V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
salamanderMH
V2EX  ›  数据库

分库分表的问题?

  •  
  •   salamanderMH · 2020-03-28 09:07:12 +08:00 · 2705 次点击
    这是一个创建于 1703 天前的主题,其中的信息可能已经有所发展或是发生改变。

    问题

    上次面试问了分库分表的问题,大致是有一个商家订单表,让你 分库分表( 分 100 张表),然后怎么分,请问这个是怎么分呢?

    PS:其实线上我没有做过分库分表

    第 1 条附言  ·  2020-03-28 09:48:47 +08:00
    他还问统计所有商家订单量
    20 条回复    2020-03-28 15:07:13 +08:00
    Cyen
        1
    Cyen  
       2020-03-28 09:09:03 +08:00 via iPhone
    这个应该是水平分表吧
    Akiyu
        2
    Akiyu  
       2020-03-28 09:11:09 +08:00
    这种问题可以参考现实中的案例, 就好像邮编一样
    省, 市, 区划分, 然后以编号划分, 等等
    opengps
        3
    opengps  
       2020-03-28 09:32:45 +08:00   ❤️ 1
    按年限分显然不合适,因为新订单挤在一个库,读写压力太集中,达不到分散压力提升承载力效果。
    那就根据用户 id 去路由分表吧,预留 128 个表,对用户 id 进行某种换算取余,让某个用户的订单全都进某个指定的表,查询的时候也是按照这个算法指定取数据的表即可
    sadfQED2
        5
    sadfQED2  
       2020-03-28 09:46:43 +08:00 via Android   ❤️ 1
    Uid 分表呀,这还用想么。如果有其他字段的统计或者分页需求,再冗余一份其他字段的索引表,索引表也 128 分表
    areless
        6
    areless  
       2020-03-28 10:51:56 +08:00 via Android
    id mod 100,自增主键步长 100,100 张表起始 id 1-100
    tabris17
        7
    tabris17  
       2020-03-28 10:54:51 +08:00
    按商户分,按 SKU 分,都可以的
    wysnylc
        8
    wysnylc  
       2020-03-28 11:15:17 +08:00
    如果数据量可观,第一层按时间分例如年份月份,第二层用主键取余分
    这样的好处是如果数据量暴涨,可以通过增加取余表的方式来扩充,如果第一层就直接按主键取余那么数据暴涨后的迁移只能停机
    cabing
        9
    cabing  
       2020-03-28 11:49:11 +08:00
    uid 和时间都需要分吧。只是需要区分主次,次的信息少点。
    th00000
        10
    th00000  
       2020-03-28 12:17:47 +08:00
    其实我一直有一个问题, 如果 mysql 分库分表了, 那跟直接用 nosql 数据库有什么区别?
    用 nosql 数据库更加高效且便宜。
    CoderGeek
        11
    CoderGeek  
       2020-03-28 12:22:04 +08:00
    uid mod 100
    es 做统计 mysql 分表统计没效率
    xsen
        12
    xsen  
       2020-03-28 12:35:57 +08:00
    其实对于传统 mysql 需要分库分表的,用 NewSQL 似乎更为适合些,比如 TiDB——95%以上都可以兼容 MySQL 。而且,随着数据量上去,水平加机器,扩展集群就可以
    lewis89
        13
    lewis89  
       2020-03-28 12:55:54 +08:00
    @xsen #12 NewSQL 现在用的还不多,没有流行起来,好的分库分表本质上还是要借用 CQRS 的思想,将 OLTP 跟 OLAP 隔离开来,在 OLAP 端 用消息队列在后面重建数据仓库 专门用来应对低频但是复杂的查询,在 OLTP 端用 MySQL 来支撑数据写入跟业务校验。
    yanyueio
        14
    yanyueio  
       2020-03-28 12:58:36 +08:00
    哎、老生常谈啦。(网上一大堆了,搜一下吧)

    你开个 docker,同时外挂 volume,把实验的数据放进去。

    以后每次面试带上笔记本,要问就直接把 case 拿出来给官家看。

    同时,个人也渐渐觉得,如果真的太大了,后期可考虑转型到 new sql 。
    xsen
        15
    xsen  
       2020-03-28 13:03:26 +08:00
    @lewis89 #13 对于是否要做隔离,这个我不做讨论。但是对于传统的方案,针对 OLAP 需要通过消息队列重建数据仓库的做法,那是因为 SQL (传统的)的无法满足针对大数据量的复杂查询(要么效率极低)。所以你说的方案是之前不得已而为之

    不流行也是正常,毕竟 NewSQL 也是近几年才成熟起来的
    epicSoldier
        16
    epicSoldier  
       2020-03-28 13:07:47 +08:00
    订单如果是数字的话按订单最后两位分成 100 个表
    lewis89
        17
    lewis89  
       2020-03-28 13:14:54 +08:00
    @xsen #15 现在也是,做海量数据的 还是要靠大数据那套东西,业务的归业务 分析的归分析,这是最好的办法,即使是 NewSQL 流行之后,也是会做冷热跟多副本处理的,生产的东西 跟 数据分析的东西 其价值是不一样的,对于数据量大的公司丢一些订单的影响非常大,但是对于数据分析来讲,用副本或者说非实时的数据去做分析 实际上不会有太大的影响,因为大部分行业 对数据的实时性分析 没那么高的要求。
    xsen
        18
    xsen  
       2020-03-28 13:24:33 +08:00
    @lewis89 #17 NewSQL 本质就是分布式数据库。所以结合相应的大数据方案( spark 或 flink )基本可以做到实战时的数据分析与查询。分布式本身要解决的一个问题就是,在数据量级别扩大之后,保证处理的速度

    基于 NewSQL 的方案,数据其实不用两套也是可以的——因为对海量数据有支持、还能保证查询速度
    brucefu
        19
    brucefu  
       2020-03-28 14:58:04 +08:00
    1 、通过查询条件进行分表。用 uid 查就 mod uid 分表,用订单号查就 mod 订单号。如果多个字段都有用查询,就要再加个索引表,索引表也要分表。
    2 、统计所有商家订单量这种,可以利用 redis 来异步缓存起来。数据量很大的时候,这种数据时效性就是不能完全保证的,需要定时 check 数据。单表数据量特别大的时候,别用 count 计算,用 id 推算、或分段计算。数据特别大,又不要求准确性,可以用 explain (我在程序中没用过,线下查数据时经常用)
    JJstyle
        20
    JJstyle  
       2020-03-28 15:07:13 +08:00 via iPhone
    mod 订单号是好理解,那查询、统计怎么办呢?走 es 吗?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1143 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 18:58 · PVG 02:58 · LAX 10:58 · JFK 13:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.