mysql面试-分库分表

一、mysql分库分表查询,不带分表键,且只是看第三页

1、全量查在通过内存分页
因为不清楚按照时间排序之后的第三页数据到底是如何分布在数据库上的,所以必须每个库都返回3页数据,所得到的6页数据在服务层进行内存排序,得到全局视野,再取第3页数据。

缺点:有性能瓶颈,如果查询偏移量过大的分页会导致数据库获取数据性能低下

2、业务折中
禁止跳页查询,不提供“直接跳到指定页面”的功能,只提供下一页的功能。极大的降低技术方案的复杂度。第一页的选取方法和全局视野法一样,但是点击下一页时记住上一页最后一条数据的作为第二次查询条件。

3、数据汇总
添加一张汇总表,属性中必有id属性,注意这张表存放的数据是所有分表的数据,但是胜在属性列少,只有提供索引的几个属性列,然后我们获取了id之后就可以去对应的表中查询了

4、union all
分表的数据通过sql中的union all查询出来在进行分页

5、使用merge存储引擎
其实这个和第三点很相似。只不过这个汇总的操作,不需要认为的去做,存储引擎会帮我们做

缺点:这里范围比较窄,只能使用merge和Myisam引擎

6、MYSQL的分区表

二、水平分表后的路由问题

1、范围路由
即以分片键的某一段落到对应的数据库,不同分段分散到不同的数据库表中,比如:1到100万落到DB_0,100万到200万落到DB_1…以此类推划分id对应数据库。
优点:可以随着数据的增加平滑的扩充新的表。 缺点:可能存在数据分布不均匀,而且有热点访问问题。

2、hash取模
选择某个列(或几个列的组合)的值进行hash运算,然后根据运算结果分散到不同的数据库中。
优点:表数据分布比较均匀。 缺点:初始表数据量不好选取,扩充新的表数据需要重新分布

3、配置路由
使用独立的表(或者配置文件等)记录路由配置信息。
优点:使用起来简单灵活,扩充表时只需要迁移指定的数据,然后修改路由表。缺点:必须多查询一次,影响整体性能,路由表本身太多影响系统整体性能,还有如果扩展表数据分布不平衡。

三、join操作问题

数据分散在不同的数据库中,无法join查询

1.通过业务代码进行join查询,然后结果合并
2.使用Databus

四、分库分表-访问数据源的中间件

1、TDDL:整个淘宝数据库体系里面具有非常重要的一个中间件产品,在公司内部具有广泛的使用
2、sharding-sphere:他们均提供标准化的数据分片、读写分离、柔性事务和数据治理功能

五、分库分表的设计思路:

5.1、表的数量设计

首先根据自身的业务量和增量来考虑分表的大小
举个例子,现在我们日单量是10万单,预估一年后可以达到日100万单,根据业务属性,一般我们就支持查询半年内的订单,超过半年的订单需要做归档处理。
那么以日订单100万半年的数量级来看,不分表的话我们订单量将达到100万X180=1.8亿,以这个数据量级部分表的话肯定单表是扛不住的。单边最大500w来算,半年归档一次,5000w除以180天等于2.8w,也就是单表一天的量最多2.8w,如果要每日100w那就是100w除以2.8w 大概需要36张表,也就是6*6=6库6表差不多。

5.2、问题

1、C端查询问题
速度一定要快,性能一定要好,一定要带分库分表键进线查询。也就是shardingkey

2、其他端查询问题
方案1:双写,双写就是下单的数据落两份,C端和B端的各自保存一份,C端用你可以用单号、用户ID做shardingkey都行,B端就用商家卖家的ID作为shardingkey就好了。有些同学会说了,你双写不影响性能吗?因为对于B端来说轻微的延迟是可以接受的,所以可以采取异步的方式去落B端订单

方案2:另外一个方案就是走离线数仓或者ES查询,比如订单数据落库之后,可以通过binlog还是MQ消息的形式,把数据同步到数仓或者ES,

五、ShardingJDBC分库分表扩容

1、扩容按什么倍数扩容
2、扩容怎么让原来的key达到先前落的表,使用hashCode取模的方式肯定是不可以的。
3、自定义分片key生成策略,如何自定义
mysql面试-分库分表_第1张图片

4、当数据库买了或者达到一定的阈值,扩容的时候,怎么解决数据分配不均衡。有个定时任务跑所有表的数量,根据统计的结果计算好每个表的权重

5、每个库的每个表的权重调整策略,其实这个有点类似于ABtest分流一样。

6、分库分表键的分片策略是什么,有什么问题
方案1、范围分片,最开始我打算分段分片,即以分片键的某一段落到对应的数据库,比如:1到100万落到DB_0,100万到200万落到DB_1…以此类推划分id对应数据库,会有一个问题,数据库热点写入问题。
方案2、自定义分片key生成策略

请看:https://juejin.cn/post/6844904142578647053

5.1 按权重取随机数

1 权重40 0到40
2 权重30 40到70
3 权重10 70到80
4 权重20 80到100
再从100里面取随机数

5.2 abtest分流

1、首先支持配置,允许修改A和B的权重。
2、原来的数据已经AB分流之后,返回的就是历史分好的,新的数据使用最新的AB权重进行分流
3、且如果开关关闭,所以流量都指到单测上面去。

六、分布式事务

1、2pc(缺点是什么)
2、3pc(缺点是什么)
3、事务补充

七、mysql存储引擎区别

Innodb和Myisam的区别和实现
1、myisam是默认表类型不是事物安全的;innodb支持事物。
2、myisam不支持外键;Innodb支持外键。
3、myisam支持表级锁(不支持高并发,以读为主);innodb支持行锁(共享锁,排它锁,意向锁),粒度更小,但是在执行不能确定扫描范围的sql语句时,innodb同样会锁全表。
4、执行大量select,myisam是最好的选择;执行大量的update和insert最好用innodb。
5、myisam在磁盘上存储上有三个文件.frm(存储表定义) .myd(存储表数据) .myi(存储表索引);innodb磁盘上存储的是表空间数据文件和日志文件,innodb表大小只受限于操作系统大小。
6、myisam使用非聚集索引,索引和数据分开,只缓存索引;innodb使用聚集索引,索引和数据存在一个文件。
7、myisam保存表具体行数;innodb不保存。
8、delete from table时,innodb不会重新简历表,而会一行一行的删除。
9、Innodb用的是聚餐索引,myisam用的是辅助索引
聚集索引表示叶子节点存储了整张表的数据,非聚集索引为存储了主键id,需要再次回表查询一次

八、其他知识补充

1、单表最大存储量

MySQL本身并没有对单表最大记录数进行限制,业界流传是500万行。超过500万行就要考虑分表分库了。阿里巴巴《Java 开发手册》提出单表行数超过500万行或者单表容量超过2GB,才推荐进行分库分表。

单个数据库最大并发量
推荐:32个库,每个库32个表,那么总共是1024张表。这个分法,第一,基本上国内的互联网肯定都是够用了,第二,无论是并发支撑还是数据量支撑都没问题。
每个库正常承载的写入并发量是1000,那么32个库就可以承载32 * 1000 = 32000的写并发,如果每个库承载1500的写并发,32 * 1500 = 48000 的写并发,接近 5 万每秒的写入并发,前面再加一个MQ,削峰,每秒写入MQ 8万条数据,每秒消费 5 万条数据。

2、mysql分区

一、分区的作用
分区是将一个表的数据按照某种方式,比如按照时间上的月份,分成多个较小的,更容易管理的部分,但是逻辑上仍是一个表。
个人理解起来,分区跟性能没有必然关系,分区更多的是从管理的角度出发的。

二、MySQL分区表对分区字段的限制
分区的字段,必须是表上所有的唯一索引(或者主键索引)包含的字段的子集,也就是说分区可以用多个字段,但是这些字段必须是在唯一索引或者主建索引中的某几个。

3、索引类型

2、normal:表示普通索引
1、unique:表示唯一的,不允许重复的索引,如果该字段信息保证不会重复例如身份证号用作索引时可设置为unique

3、full textl: 表示 全文搜索的索引。 FULLTEXT 用于搜索很长一篇文章的时候,效果最好。用在比较短的文本,如果就一两行字的,普通的 INDEX 也可以。
总结,索引的类别由建立索引的字段内容特性来决定,通常normal最常见。

4、union all和union的区别

1、union 操作符用于合并两个或多个SELECT语句的结果集。默认地,UNION操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。

2、union all只是简单的将两个结果合并后就返回

注意:union会自动压缩多个结果集合中的重复结果,而union all则将所有的结果全部显示出来,不管是不是重复。

你可能感兴趣的:(面试,数据库相关,mysql,面试,数据库)