推荐一个 零声学院 免费公开课程,个人觉得老师讲得不错,分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习]
后台服务器:https://course.0voice.com/v1/course/intro?courseId=5&agentId=0
1.体系结构
select(listen+1,readfd,NULL,NILL,0);
int clientfd=accept(listenfd,&addr,&len);
my_sql_thread_create(key_thread_one_connection,&id,^connection_atrrib,handle_connection,(void*)channel_info);
MySql采用一个select()函数,只监听读事件,0表示阻塞等待连接到达。当监听到连接到达,利用accept()接受连接,为每一条连接分配一个线程,一个fd一个线程。redis采用reactor网络封装异步方式,操作内存,与之不同的是,MySql采用阻塞的方式,毕竟操作硬盘是重IO操作。
为什么MySql采用连接池呢?主要有三点,首先,因为阻塞的IO,需要等待一个返回才发起另一个连接,等待时间过长,影响执行效率。其次,MySql采用的短连接,如果长时间不回应连接将会被踢掉,密码验证等操作比较复杂,连接池可以减少等待的时间。最后,MySql只能支持150+条连接,连接池可以充分的利用并发模型。
SQL处理流程
- SQL Interface:Sql语法分析
- Parser:对象权限验证并过滤
- Optimizer:分析语句具体执行路径,根据缓存分析采用什么样的执行方式,优化器
- Cathes & Buffer:缓存
MySql采用可插拔式的数据引擎,根据表采用具体的引擎。
2.数据库的三范式和反范式
- 范式一:确保每列保持原子性,数据库中的所有字段都是不可分解的原子值。
- 范式二:确保表中的每列都和主键有关,而不能只与主键的某一部分相关(组合索引)。
- 范式三:与二类似,确保每列都和主键直接相关,而不是间接相关;减少数据冗余。
- 反范式:范式可以避免数据冗余,减少数据库空间,减少维护数据完整性的麻烦;但是采用范式又造成表变多,造成更多的连接查询,影响性能,因此又考虑进行反范式设计。
注意点:
- 判空查询都不会走索引,建议不要判空。is null 造成索引失效。
- LIMIT 1,2 范围查询的速度比较快。
- 分组查询的目的是去重和合并。
- in /not in 会进行全表扫描
其他
删除表的细节差别
- DROP TABLE ‘table_name’;删除表以及表结构。
- TRUNCATE TABLE ‘table_name’;截断表,有自增索引从初始值开始累加。效率相对较高。
- DELETE TABLE ‘table_name’;逐行删除,有自增索引从之前值继续累加。
为什么inodb要主动创建主键,并以自增的整数作为主键?
外键约束
CREATE TABLE ‘course’{
‘cid’ int(11) NOT NULL AUTO_INCREMENT,
‘cname’ varchar(32) NOT NULL,
‘teacher_id’ int(11) NOT NULL,
PRIMARY KEY (‘cid’),
KET ‘fk_course_teacher’ (‘teacher_id’),
CONSTRAINT ‘fk_course_teacher’ FOREIGN KEY (‘teacher_id’) REFERENCES "teacher’(‘id’)
}ENGINE=InnoDB AUTO _INCREMENT=5 DEFAULT CHARSET=utf8;
–当删除teacher表中id行时,teacher_id 也会被删除。
分组聚合
SELECT ‘gender’,GROUP CONCAT(sname) FROM ‘student’ GROUP BY ‘gender’;