首先mysql是c++开发的.
github地址:
很多大型软件基本都是c/c++开发的.你会了c/c++基本就具备了领略程序世界的大门的钥匙.
mysql是一个完善的数据库软件.
最上层:处理连接,授权认证,安全等
第二层:核心服务功能:查询解析,分析,优化,缓存以及所有内置函数(日期,时间,数据,加密等),存储过程,触发器,视图等.
第三层:存储引擎,存储引擎负责mysql中数据的存储和提取.每个引擎各有优势.服务器通过API与存储引擎进行通信.接口屏蔽了不同引擎的差异,对上层的查询过程透明.
你如果去读它,你基本就可以深入到这些业务点中.然后获取的提升绝对不是一星半点.你会发现开发一个web应用,开发一个中间件如此简单.你获取的是大神级工程师的开发思想,技巧.
举个例子:MVCC ,innodb 隔离性实现的技术.
设计原理很简单,也很巧妙.对数据安全和高并发做了平衡处理.
这个是单纯学习计算机语言,算法数据结构给不了的体验.
当前,你得能看的下去,你有那个恒心.吹牛逼就不要今天这一节问了?
首先,能看懂 MySQL 源码的人物,我感觉肯定在技术上是一位大牛,能够将 C/C++ 语言的 MySQL 源码看懂,肯定也是一位非常有耐心的技术人,能够耐着性子去专研. 如果能够将Mysql源码研究的很透彻的话,我相信出去到大厂找数据库内核开发的岗位时,绝对是一个非常巨大的优势.
能看懂 Mysql 的源码,首先第一点需要对 C/C++ 语言的知识点非常的熟悉,因为 MySQL 底层几乎都是 C/C++ 语言写的,比如指针等. 对于 MySQL 源码能够看得的话,我相信在和别人谈论数据库相关的问题时,其实也会更加有专业性和深度,能够快速的理解对方所说的数据库问题.
同时,如果对 MySQL 源码有着很深入了解的话,其实对于数据库的相关配置优化等也会掌握的更好,因为你对底层原理了解的很透彻,对于自己做的每一件事情都是有理有据.每个数据库参数是什么含义,为什么要这样设置,背后都有你自己的理解和原因.这对于公司来说,也是非常需要这样的人才.
当初我校招的时候,其实准备想投数据库开发相关的岗位,当时其实自己也自学过 MySQL 底层的原理(不过我没有去研究过源码). MySQL 最主要的还是底层可插拔式的存储引擎,比如 InnoDB、MYISAM等,重点是 InnoDB存储引擎.学习看 MySQL 源码的话,我建议可以选择其中一个模块开始入手.
我刚开始看 <
新同学在去研究某一门开源技术组件的源码时,不建议直接上手去看代码,你应该是先去整体了解一下该技术组件的整体原理和框架,源码层则是更加细节方面的实现,你应该带着某一个问题去看,有针对性和目的性的去看源码,这样你的提升才会更加的快速.
我会持续大数据、数据库方面的内容,如果你有任何问题,也欢迎关注私信我,我会认真解答每一个问题.期待您的关注
拜托啦,我不只能看懂你的SQL,我还可以看懂VB、C++、数据库我也看
不能单独学习mysql这个数据库,以学习sql语言为主,可以以某个数据库为例,这样所有的数据库都可以通用了.
①.、InnoDB存储引擎
存储格式 : 数据,索引集中存储,存储于同一个表空间文件中.
InnoDB的行锁模式及其加锁方法: InnoDB中有以下两种类型的行锁:共享锁(读锁: 允许事务对一条行数据进行读取)和 互斥锁(写锁: 允许事务对一条行数据进行删除或更新), 对于update,insert,delete语句,InnoDB会自动给设计的数据集加互斥锁,对于普通的select语句,InnoDB不会加任何锁.
InnoDB行锁的实现方式: InnoDB行锁是通过给索引上的索引项加锁来实现的,如果没有索引,InnoDB将通过隐藏的聚簇索引来对记录加锁.InnoDB这种行锁实现特点意味着:如果不通过索引条件检索数据,那么InnoDB将对表中的所有记录加锁,实际效果跟表锁一样.
(1)在不通过索引条件查询时,InnoDB会锁定表中的所有记录.
优点:
①.、支持事务处理、ACID事务特性;
缺点:
因为它没有保存表的行数,当使用COUNT统计时会扫描全表.
使用场景:
功能:
(1)支持数据压缩存储,但压缩后的表变成了只读表,不可写;如果需要更新数据,则需要先解压后更新.
①高性能读取;
①.、锁级别为表锁,表锁优点是开销小,加锁快;缺点是锁粒度大,发生锁冲动概率较高,容纳并发能力低,这个引擎适合查询为主的业务.
InnoDB和MyISAM一些细节上的差别:
①..索引概述
利用关键字,就是记录的部分数据(某个字段,某些字段,某个字段的一部分),建立与记录位置的对应关系,就是索引.索引的关键字一定是排序的.索引本质上是表字段的有序子集,它是提高查询速度最有效的方法.一个没有建立任何索引的表,就相当于一本没有目录的书,在每次查询时就会进行全表扫描,这样会导致查询效率极低、速度也极慢.如果建立索引,那么就好比一本添加的目录,通过目录的指引,迅速翻阅到指定的章节,提升的查询性能,节约了查询资源.
从索引的定义方式和用途中来看:主键索引,唯一索引,普通索引,全文索引.
无论任何类型,都是通过建立关键字与位置的对应关系来实现的.索引是通过关键字找对应的记录的地址.
以上类型的差异:对索引关键字的要求不同.
关键字:记录的部分数据(某个字段,某些字段,某个字段的一部分).
普通索引,index:对关键字没有要求.
唯一索引,unique index:要求关键字不能重复.同时增加唯一约束.
主键索引,primary key:要求关键字不能重复,也不能为NULL.同时增加主键约束.
PS:这里主键索引和唯一索引的区别在于:主键索引不能为空值,唯一索引允许空值;主键索引在一张表内只能创建一个,唯一索引可以创建多个.主键索引肯定是唯一索引,但唯一索引不一定是主键索引.
如果索引不遵循使用原则,则可能导致索引无效.
(1)列独立
如果需要某个字段上使用索引,则需要在字段参与的表达中,保证字段独立在一侧.否则索引不会用到索引, 例如这条sql就不会用到索引:select * from A where id+1=10;
复合索引:一个索引关联多个字段,仅仅针对左边字段有效果,添加复合索引时,第一个字段很重要,只有包含第一个字段作为查询条件的情况才会使用复合索引(必须用到建索引时选择的第一个字段作为查询条件,其他字段的顺序无关),而且查询条件只能出现and拼接,不能用or,否则则无法使用索引.
必须要保证 OR 两端的条件都存在可以用的索引,该查询才可以使用索引.
即使满足了上面说原则,MySQL也能弃用索引,例如:select * from A where id 1;这里弃用索引的主要原因:查询即使使用索引,会导致出现大量的随机IO,相对于从数据记录的第一条遍历到最后一条的顺序IO开销,还要大.
(1)索引检索:检索数据时使用索引.
建立索引索引时,不能仅仅考虑where检索,同时考虑其他的使用场景.(在所有的where字段上增加索引,就是不合理的)
前缀索引是建立索引关键字一种方案.通常会使用字段的整体作为索引关键字.有时,即使使用字段前部分数据,也可以去识别某些记录.就比如一个班级里,我要找王xx,假如姓王的只有1个人,那么就可以建一个关键字为'王'的前缀索引.语法:Index +index_name+ (+index_field+(N))使用index_name前N个字符建立的索引.
(1) 应尽量避免在 where 子句中使用 != 或 操作符,否则将引擎放弃使用索引而进行全表扫描;
join 的两种算法:BNL 和 NLJ
NLJ(Nested Loop Join)嵌套循环算法;以如下 SQL 为例:
SQL 执行时内部流程是这样的:
① 先从 t1(假设这里 t1 被选为驱动表)中取出一行数据 X;
BNLJ(Block Nested Loop Join)块嵌套循环算法;
① 把 t1 表(假设这里 t1 被选为驱动表)满足条件的数据全部取出放到线程的 join buffer 中;
BNLJ相对于NLJ的优点在于,驱动层可以先将部分数据加载进buffer,这种方法的直接影响就是将大大减少内层循环的次数,提高join的效率.
例如:
如果内层循环有100条记录,外层循环也有100条记录,这样的话,每次外层循环先将10条记录放到buffer中,内层循环的100条记录每条与这个buffer中的10条记录进行匹配,只需要匹配内层循环总记录数次即可结束一次循环(今天这一节,即只需要匹配100次即可结束),然后将匹配成功的记录连接后放入结果集中,接着,外层循环继续向buffer中放入10条记录,同理进行匹配,并将成功的记录连接后放入结果集.后续循环以此类推,直到循环结束,将结果集发给client为止.
可以发现,若用NLJ,则需要100 * 100次才可结束,BNLJ则需要100 / block_size * 100 = 10 * 100次就可结束,大大减少了循环次数.
JOIN 按照功能大致分为如下三类:
JOIN、STRAIGHT_JOIN、INNER JOIN(内连接,或等值连接):取得两个表中存在连接匹配关系的记录.
注意:mysql不支持Full join,不过可以通过UNION 关键字来合并 LEFT JOIN 与 RIGHT JOIN来模拟FULL join.
mysql 多表连接查询方式,因为mysql只支持NLJ算法,所以如果是小表驱动大表则效率更高;反之则效率下降;所以呢mysql对内连接或等值连接的方式做了一个优化,会去判断join表的数据行大小,然后取数据行小的表为驱动表.
INNER JOIN、JOIN、WHERE等值连接和STRAIGHT_JOIN都能表示内连接,那平时如何选择呢?一般情况下用INNER JOIN、JOIN或者WHERE等值连接,因为MySQL 会按照"小表驱动大表的策略"进行优化.当出现需要排序时,才考虑用STRAIGHT_JOIN指定某张表为驱动表.
两表JOIN优化
a.当无order by条件时,根据实际情况,使用left/right/inner join即可,根据explain优化 ;
b.当有order by条件时,如select * from a inner join b where 1=1 and other condition order by a.col;使用explain解释语句;
①.)如果第一行的驱动表为a,则效率会非常高,无需优化;
在使用left join(或right join)时,应该清楚的知道以下几点:
(1). on与 where的执行顺序
ON 条件("A LEFT JOIN B ON 条件表达式"中的ON)用来决定如何从 B 表中检索数据行.如果 B 表中没有任何一行数据匹配 ON 的条件,将会额外生成一行所有列为 NULL 的数据,在匹配阶段 WHERE 子句的条件都不会被使用.仅在匹配阶段完成以后,WHERE 子句条件才会被使用.它将从匹配阶段产生的数据中检索过滤.
所以我们要注意:在使用Left (right) join的时候,一定要在先给出尽可能多的匹配满足条件,减少Where的执行.
即使右表的数据不满足ON后面的条件,也会在结果集拼接一条为NULL的数据行,但WHERE后面的条件不一样,右表不满足WHERE的条件,左表关联的数据也会被过滤掉.
往往性能这玩意儿,更多时候体现在数据量比较大的时候,此时,我们应该避免复杂的子查询.