为什么分库分表

  • 单表数据量过大,会出现慢查询,所以需要水平分表

  • 可以把低频、高频的字段分开为多个表,低频的表作为附加表,且逻辑更加清晰,性能更优

  • 随着系统的业务模块的增多,放到单库会增加其复杂度,逻辑不清晰,不好维护,所以会对业务进行微服务拆分,同时拆分数据库

怎么分库分表

  • 对于水平,不同的业务按不同的条件去分,比如财务数据,可以按年份作为库,月份做为表。 比如多用户系统,可以按用户id取模划分。
  • 对于垂直,一般按不同的业务模块来划分即可

事务

  • 原子性(Atomicity):指事务是一个不可分割的最小工作单位,事务中的操作只有都发生和都不发生两种情况

  • 一致性(Consistency):事务必须使数据库从一个一致状态变换到另外一个一致状态,举一个栗子,李二给王五转账50元,其事务就是让李二账户上减去50元,王五账户上加上50元;一致性是指其他事务看到的情况是要么李二还没有给王五转账的状态,要么王五已经成功接收到李二的50元转账。而对于李二少了50元,王五还没加上50元这个中间状态是不可见的。

  • 隔离性(Isolation):一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

  • 持久性(Durability):一个事务一旦提交成功,它对数据库中数据的改变将是永久性的,接下来的其他操作或故障不应对其有任何影响。

悲观锁,排他锁,写锁

数据更新、插入、删除都是带锁的。 只有获得锁才能更新数据,如果查询其他也有for update 或者读锁,那么他的查询也不能更新

  • select * from table where id=xx for update;

尽量要带上条件,且条件一定要有索引, 避免锁表

读锁,共享锁

  • select ... lock in share mode;

读锁相互可以兼容,与写锁冲突,所以如果数据上了写锁,读锁就要等待。同理,如果数据上了读锁,写锁就要等待

查看锁

  • 锁情况 select * from information_schema.innodb_locks;

  • 引擎整体情况 包括锁 show engine innodb status;

索引

  • 对于联合索引 index(a,b,c), 5.7版本及之前遵从最左匹配原则,就是说 单纯是 a和ab和abc和ac走索引,其他不走

  • 当存在多个索引,possible keys有多个,但是使用的时候mysql会选取成本最少的那一个使用

  • 什么字段适合加索引? where order by group by

  • 不应该建立索引的字段规则 1.不应该在字段比较长的字段上建立索引,因为会消耗大量的空间 2.对于频繁更新、插入的字段应该少建立索引,因为在修改和插入之后,数据库会去维护索引,会消耗资源 3.尽量少在无用字段上建立索引【where条件中用不到的字段】 4.表记录太少不应该创建索引 5.数据重复且分布平均的表字段不应该创建索引【选择性太低,例如性别、状态、真假值等字段】

  • 通常场景,IN条件查询走索引;

  • 当IN多条件查询时,例子: id in (1,2)。 如果数据量大于总数据量30%(这个数好像不准确),就会走全表扫描(暂未找到官方结论,但在Mysql版本为8.0.18中,本人验证基本符合上述结论);

  • 当IN是单条件,例子:id in (1) 数据量大于总数据30%时,依然走索引。

隔离级别

  • 脏读:事务a读到了事务b未提交到数据

  • 不可重复读:事务a读到了事务提交的数据

  • 幻读:事务a读到了事务b insert的数据(第一次查询读条数和第二次读不同)

级别 脏读 不可重复读 幻读
Read uncommitted v
Read committed Sql Server -- Oracle × v
Repeatable read Mysql × ×
Serializable × × ×

但是mysql的innodb通过mvcc机制避免了幻读。

  • 普通读(快照读,即普通的select)读到的是历史版本的数据,

  • 当前读(select..for update , insert , update, delete)这些因为需要修改数据,所以就不能读 历史数据,所以就会加锁阻塞。

  • 但是如果是穿插使用的话--先普通读再当前读,是无法避免幻读的。

mvcc

  1. 多版本并发控制技术
  2. 为了解决并发安全问题+提高并发处理能力+解决读写冲突
  3. 读写并发阻塞问题,提高并发读写能力
  4. 采用乐观锁的实现,降低了死锁的概率, 因为有个事务id
  5. 解决一致性读读问题,可重复读
  6. 悲观锁用来解决写和写读冲突
  7. 底层原理:

主要实现rr rc的隔离级别。 通过undolog readview技术共同实现可重复读、读已提交 undolog: 事务的历史版本链表,全局(多个事务共享)维护一个, 每一行有一个递增的事务id 前一个版本的指针 和一个隐藏的rowid readview:每个事务开启的时候,当前读后生成一个readview。有 trx_ids(活跃-未提交的事务id) min_trx_id(trx_ids中最小) max_rtx_id(预分配的下一个trx_id) creator_trx_id (创建readview的trx_id)

匹配规则: 如果数据事务ID trx_id < min_limit_id,表明生成该版本的事务在生成Read View前,已经提交(因为事务ID是递增的),所以该版本可以被当前事务访问。 如果trx_id>= max_limit_id,表明生成该版本的事务在生成ReadView后才生成,所以该版本不可以被当前事务访问。 如果 min_limit_id =<trx_id< max_limit_id,需腰分3种情况讨论

(1).如果m_ids包含trx_id,则代表Read View生成时刻,这个事务还未提交,但是如果数据的trx_id等于creator_trx_id的话,表明数据是自己生成的,因此是可见的。

(2)如果m_ids包含trx_id,并且trx_id不等于creator_trx_id,则Read View生成时,事务未提交,并且不是自己生产的,所以当前事务也是看不见的;

(3).如果m_ids不包含trx_id,则说明你这个事务在Read View生成之前就已经提交了,修改的结果,当前事务是能看见的

rr: 使用第一次当前读创建的readview rc: 每一次当前读都更新readview

三范式

  • 第一范式(1NF):每个列都不可以再拆分。(比如地址,如果用到城市、省份的数据的话,一定还要继续拆分)

  • 第二范式(2NF):在第一范式的基础上,非主键列完全依赖于主键,而不能是依赖于主键的一部分。(在第一范式的基础上消除非主键对主键的部分依赖, 比如成绩表有学号、学生、系主任、系名、课程、分数), 其实如果学号+课程为主键就能确定分数,所以其他无关的字段就可以分离出去)

  • 第三范式(3NF):在第二范式的基础上,非主键列只依赖于主键,不依赖于其他非主键。(其实说白了就是面向对象编程的思想,比如:把系名、系主任拆到另一张表)

但也不一定必须满足3范式,对于数据量大的业务其实要避免3表及以上的join操作,因为要避免没有用到索引,而是用一张宽表记录,查询即可。

怎么保证acid

  1. 原子性: undolog, 保留一份事务中语句的操作日志,当执行发生错误时候,进行回滚,用反向逻辑执行操作语句。

  2. 持久性: redolog, 无论是redolog,还是正常当数据,都是先写到buffer,在写到磁盘。但是redolog是通过追加当模式写入,即:顺序写。而数据 是随机写,明显速度更慢,而且mysql是按页即16kb的传输,所以更慢。采用了先持久化到redolog的方式。 innodb_flush_log_at_trx_commit = 1为 redolog同步到磁盘。如果是0,则系统每秒刷一次buffer到内存。

  3. 隔离性:写写操作,通过锁。写读操作,mvcc。

  4. 一致性:事务到目的,上面三种特性共同保障数据最终一致性

数据库出现慢查询原因

  1. 硬件资源问题,如内存不足

  2. 出现高并发,查询数量过大

  3. 没有建立索引

  4. sql没有命中索引

  5. 返回很多不必要的数据

  6. 数据库数量大

一亿订单数据如何设计数据库,需要卖家、状态进行查询

  1. 水平分表

  2. 通过买家好hash (因为通过买家查询的量是很大的)

  3. 做好映射,比如:卖家:买家列表--> 买家通过路由规则找到表 --> 再通过条件进行查询 --> 合并

innodb myisam区别

  1. 事务

  2. 外键

  3. innodb:聚簇索引 不支持fulltext 但可以通过sphinx插件支持。 myisam: 非聚簇 支持fulltext全文索引

  4. 行锁 表锁

  5. 存储文件, innodb两个:.frm(表定义) .ibd(数据和索引存储) myisam三个: .frm .myd(数据存储) .myi(索引存储)

为啥不用b树

b树非页子节点保存有数据,如果按照一行数据1k,不算上指针和键值的情况下,一个节点是16k,也就最大是16行数据, 所以3层b树最多是 16 * 16 * 16 = 4096行,太少了,所以只能增加层高,意味着增加io次数,所以这个方案不可用

redolog和binglog有啥不同

  1. 使用场景不同:binlog主要用于备份、迁移、数据同步, redolog主要保证事务的持久性,遇到故障时候提供回滚重放操作

  2. 记录时机不同,binglog是在commit之后再一次性记录的,redolog是事务中执行的时候一条一条记录的

  3. binlog是记录执行语句,redolog是记录物理块的数据变更

MySQL常见的后端面试题,你会几道?的更多相关文章

  1. python后端面试题

    1. 果壳 电话面试: 说一下TCP的三次握手,四次挥手,为什么会这样? http安全的性的了解,说一下对cookie和session的了解: 对mysql的了解,说一下你常用的数据类型,char和v ...

  2. 大小厂必问Java后端面试题(含答案)

    你好,我是yes. 这个系列的文章不会是背诵版,不是那种贴上标准答案,到时候照着答就行的面试题汇总. 我会用大白话尽量用解释性.理解性的语言来回答,但是肯定没有比平时通过一篇文章来讲解清晰,不过我尽量 ...

  3. java后端面试题汇总

    转载链接:https://www.nowcoder.com/discuss/90776?type=0&order=0&pos=23&page=0 基础篇 数据结构与算法 线性表 ...

  4. 小米Python后端面试题

    电话面 时长:30m 说一下对浏览器缓存的理解: 说一下MySQL优化: 说一下redis: 说一下从输入url到返回都发生了什么: 域名怎么解析的: 一面 1h 编程实现翻转单链表: MySQL中v ...

  5. Redis后端面试题

    目录 简要说一下什么是Redis? 为什么要⽤Redis(缓存)? 为什么要⽤Redis⽽不⽤map/guava做缓存? Redis与Memcached的区别 Redis的应⽤场景 redis为什么那 ...

  6. 前端面试题:CSS实现水平垂直居中

    这是一个挺常见的前端面试题,但是没有做过总结.有的时候可能会使用完了,很长一段时间不去使用,会慢慢忘记.所以,温故而知新,还是很有必要的. 一.绝对定位元素的居中实现 这一种工作中用的应该是最多的,兼 ...

  7. 常见前端面试题之HTML/CSS部分

    转自http://www.cnblogs.com/jscode/archive/2012/07/10/2583856.html Doctype是什么?如何触发严格模式与混杂模式模式?区分它们有何意义? ...

  8. 前端面试题2016--HTML

    本文由我收集总结了一些前端面试题,初学者阅后也要用心钻研其中的原理,重要知识需要系统学习.透彻学习,形成自己的知识链.万不可投机取巧,临时抱佛脚只求面试侥幸混过关是错误的!也是不可能的!不可能的!不可 ...

  9. 【web前端面试题整理02】前端面试题第二弹袭来,接招!

    前言 今天本来准备先了解下node.js的,但是,看看我们一个小时前与一个小时后的差距: 既然如此,我们继续来搜集我们的前端面试题大业吧!!! 特别感谢玉面小肥鱼提供哟,@玉面小飞鱼 题目一览 Jav ...

  10. 各大互联网公司前端面试题(js)

    对于巩固复习js更是大有裨益.    初级Javascript: 1.JavaScript是一门什么样的语言,它有哪些特点? 没有标准答案. 2.JavaScript的数据类型都有什么? 基本数据类型 ...

随机推荐

  1. 羽夏逆向破解日记簿——关于逆向epub格式转化器与思考

    看前必读   本软件是商业软件,本篇文章仅仅介绍 逆向分析过程 和 关于开发软件防止逆向的思考 ,不会提供任何成品破解补丁或成品软件,仅限用于学习和研究目的,否则,一切后果自负.您必须在下载后的24个 ...

  2. Typecho博客网站迁移:MySQL ➡️ MarialDB

    目录 1. 引言 2. Typecho的自定义配置迁移 3. 数据库迁移:MySQL- > MarialDB 3.1 在原服务器中备份并导出数据库文件 3.2 将"backupdb.s ...

  3. element Tree 树形控件

    文档地址 https://element.eleme.cn/#/zh-CN/component/tree 代码地址 https://gitee.com/wBekvam/vue-shop-admin/b ...

  4. Java计算百分比保留整数

    1.Java计算百分比保留整数的方法步骤 在Java中计算百分比并保留整数,通常涉及以下步骤: (1)计算原始数值与基准数值的百分比(通常使用 (原始数值 / 基准数值) * 100 的公式). (2 ...

  5. c#事件的实际应用场景

    最简单的定义事件的语法 public event Action<bool> Refreash; 先介绍这个Action 这个Action是委托的快速实现方式,我用.net framewor ...

  6. 解决:ModuleNotFoundError: No module named ‘urllib3.packages.six.moves问题

    解决方案: 第一步:把selenium版本降到3.3.1 配合urllib3版本1.26.2使用,成功解决 &在python interpreter安装availablePackages se ...

  7. Bear and String Distance

    传送锚点: codeforces.com Copy 4 26 bear output roar input 2 7 af output db input 3 1000 hey output -1 思路 ...

  8. WPF+Emgucv实现在图像上画出感兴趣的区域 并进行掩膜获取 得到图像均值 和简单的 漫水填充

    <Grid.RowDefinitions></Grid.RowDefinitions> <Grid> <UniformGrid Columns="2 ...

  9. 将任意程序安装成windows服务

    某些时候,一个程序控制台服务程序需要在系统启动的时候自动运行,这时候我们会想到采用windows服务的方式来实现 但是,如果程序本来不支持安装成服务的话,我就需要采用其他方案来实现 之前博主也遇到了类 ...

  10. 基于 Kubernetes 的 CICD 基础设施即代码

    在上一篇基于 Kubernetes 的基础设施即代码一文中,我概要地介绍了基于 Kubernetes 的 .NET Core 微服务和 CI/CD 动手实践工作坊使用的基础设施是如何使用代码描述的,以 ...