并发编程&MySQL数据库
2018-08-17 18:08:35 1 举报
AI智能生成
并发编程&MySQL数据库
作者其他创作
大纲/内容
MySQL数据库
数据库介绍
数据库的概念
数据库就是数据存储的仓库
数据库组成
1.数据库服务器
就是一台计算机,用途就是运行数据库管理软件的计算机
2.数据库管理软件
MySQL,oracle,db2,sqlserver,数据库无非就是套接字的客户端和套接字的服务端
3.库
表应该有序存放,不能全部都放在一个地方,不同的项目不能混乱在一起,那么就用数据库放表
4.表
由于单纯的文本文件是不能表述清楚事物的特征的,计算机无法识别是如何区分的,这就要引入表来描述
5.记录
组成事物的一系列的所有的特征,为计算机识别事物
6.数据
描述事物特征的符号
数据库分类
1.关系型
sqllite,db2,oracle,access,sql server,MySQL,注意:sql语句通用
关系型数据库需要有表结构(字段+数据类型+数据条件)
2.非关系型
mongodb,redis,memcache
非关系型数据库是key-value存储的,没有表结构
存储引擎介绍
存储引擎的概念
mysql每建立一个库就是一个文件夹,每建立一张表就是一个文件,如果自己建立一张表,应该根据数据类型的不同存储在不同的表中,存储引擎就是表的类型
存储引擎的种类
InnoDB 存储引擎(最常用)
支持事务,其设计目标主要面向联机事务处理(OLTP)的应用。
特点是行锁设计、支持外键,并支持类似 Oracle 的非锁定读,即默认读取操作不会产生锁
特点是行锁设计、支持外键,并支持类似 Oracle 的非锁定读,即默认读取操作不会产生锁
MyISAM 存储引擎
不支持事务、表锁设计、支持全文索引
缓冲池只缓存(cache)索引文件,而不缓存数据文件
缓冲池只缓存(cache)索引文件,而不缓存数据文件
NDB 存储引擎
NDB 存储引擎是高可用、 高性能、高可扩展性的数据库集群系统
Memory 存储引擎
,Memory 存储引擎中的数据都存放在内存中,数据库重启或发生崩溃,表中的数据都将消失
Infobright 存储引擎
存储是按照列而非行的
NTSE 存储引擎
网易公司开发的面向其内部使用的存储引擎。目前的版本不支持事务, 但提供压缩、行级缓存等特性,不久的将来会实现面向内存的事务支持。
BLACKHOLE
黑洞存储引擎,可以应用于主备复制中的分发主库
MySQL初识
MySQL的概念
基于套接字的软件就是数据管理软件,就是数据库
MySQL的特点
1.mysql本身支持并发,实际都是在操作共享数据
2.mysql处共享数据的安全性问题,需要加锁
3.mysq也能解决数据的查询性能问题等
MySQL的简单配置
MySQL语法
常用语句初识
库操作
增
create database db1 charset utf8;
删
drop database db1;
改
alter database db1 charset utf8;
查
show databases;
表操作
增
create table t1(id int,name char);
删
drop table t1;
改
alter table t1 modify name char(6);
查
show create table t1;
desc t1;
记录操作
增
insert t1(id,name) values(1,'panda'),(2,'boy'),(3,'zombie');
删
delete from t1 where id = 1;
改
update db1.t1 set name='panda' where id = 2;
查
select id,name from db1.t1;
MySQL数据类型
整数类型
整型
TINYINT
小整数值
SMALLINT
大整数值
MEDIUMINT
大整数值
INT或INTEGER
大整数值
BIGINT
极大整数值
浮点型
FLOAT
单精度
浮点数值
浮点数值
DOUBLE
双精度
浮点数值
浮点数值
DECIMAL
小数值
日期类型
datetime
常用
timestamp
不常用
字符类型
char:定长类型
优点
简单粗暴,不管多少数据,按照固定格式存储,存储和提取数据都快
缺点
浪费存储的空间
varchar:变长类型
优点
更加节省空间,存储数据更精准
缺点
存储和提取数据慢,因为要先读取数据的头,判断有多少个字节以后再提取数据
枚举类型与集合类型
单选
enum单选
只能在给定的范围内选一个值,如性别、名族等
多选
set多选
在给定的范围里可以选择一个或一个以上的值(爱好1、爱好2、爱好3等)
进阶语法
约束条件
not null
设置数据不为空
default
为数据设置默认值
unique key
限制字段传入的值是唯一的,不重复的
primary key
如果没有明确的指定primary key的话,会指定一个不为空且唯一的字段作为主键
auto_increment
自增长
foreign key【非常重要】
建立表之间的关系
ON DELETE CASCADE ->删除同步
ON UPDATE CASCADE->更新同步
ON UPDATE CASCADE->更新同步
表关系
多对一
左表多对一右表
是否左表的多条记录可以对应右表的一条记录,如果是,则证明左表的一个字段foreign key 右表一个字段(通常是id)
右表多对一左表
是否右表的多条记录可以对应左表的一条记录,如果是,则证明右表的一个字段foreign key 左表一个字段(通常是id)
是否右表的多条记录可以对应左表的一条记录,如果是,则证明右表的一个字段foreign key 左表一个字段(通常是id)
多对多
多对多的关系表建立需要第三张表去存储两张表之间的关系
一对一
一张客户表,一张学生表,这就是一对一关系
查询语法与执行顺序
语法顺序
SELECT 字段1,字段2... FROM 表名
WHERE 条件
GROUP BY field
HAVING 筛选
ORDER BY field
LIMIT 限制条数
WHERE 条件
GROUP BY field
HAVING 筛选
ORDER BY field
LIMIT 限制条数
执行顺序
(7) SELECT
(8) DISTINCT <select_list>
(1) FROM <left_table>
(3) <join_type> JOIN <right_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) HAVING <having_condition>
(9) ORDER BY <order_by_condition>
(10) LIMIT <limit_number>
(8) DISTINCT <select_list>
(1) FROM <left_table>
(3) <join_type> JOIN <right_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) HAVING <having_condition>
(9) ORDER BY <order_by_condition>
(10) LIMIT <limit_number>
1.找到表:from
2.拿着where指定的约束条件,去文件/表中取出一条条记录
3.将取出的一条条记录进行分组group by,如果没有group by,则整体作为一组
4.将分组的结果进行having过滤
5.执行select
6.去重
7.将结果按条件排序:order by
8.限制结果的显示条数
2.拿着where指定的约束条件,去文件/表中取出一条条记录
3.将取出的一条条记录进行分组group by,如果没有group by,则整体作为一组
4.将分组的结果进行having过滤
5.执行select
6.去重
7.将结果按条件排序:order by
8.限制结果的显示条数
语法介绍
join on 连表操作
交叉连接
不适用任何匹配条件。生成笛卡尔积
内连接
只连接匹配的行
左连接
优先显示左表全部记录
右连接
优先显示右表全部记录
全外连接
显示左右两个表全部记录
where约束,条件过滤
group by分组
having过滤
order by排序
limit限制条数
子查询
子查询概念
子查询就是把一条查询语句放入另一条查询语句里当做查询的条件来使用
1:子查询是将一个查询语句嵌套在另一个查询语句中。
2:内层查询语句的查询结果,可以为外层查询语句提供查询条件。
3:子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字
4:还可以包含比较运算符:= 、 !=、> 、<等
IN关键字
比较运算符
EXISTS关键字
MySQL其他内置功能
权限管理
创建账号(新建账号是没有任何权限的)
授权
控制不同的权限管理
视图
视图的概念
视图只有表结构没有表内容,数据来源于其他表
创建视图
CREATE VIEW 视图名称 AS SQL语句
使用视图
增
CREATE VIEW 视图名称 AS SQL语句
删
DROP VIEW 视图名称
改
ALTER VIEW 视图名称 AS SQL语句
修改视图的数据会影响原表,尽量别修改
查
select 字段 from 表名
触发器
触发器的概念
使用触发器可以定制用户对表进行【增、删、改】操作时前后的行为,注意:没有查询
创建触发器
delimiter //
CREATE TRIGGER tri_after_insert_cmd AFTER INSERT ON cmd FOR EACH ROW
BEGIN
IF NEW.success = 'no' THEN #等值判断只有一个等号
INSERT INTO errlog(err_cmd, err_time) VALUES(NEW.cmd, NEW.sub_time) ; #必须加分号
END IF ; #必须加分号
END//
delimiter ;
CREATE TRIGGER tri_after_insert_cmd AFTER INSERT ON cmd FOR EACH ROW
BEGIN
IF NEW.success = 'no' THEN #等值判断只有一个等号
INSERT INTO errlog(err_cmd, err_time) VALUES(NEW.cmd, NEW.sub_time) ; #必须加分号
END IF ; #必须加分号
END//
delimiter ;
使用触发器
触发器无法由用户直接调用,而知由于对表的【增/删/改】操作被动引发的
删除触发器
drop trigger 触发器名
事务
事务的概念
事务用于将某些操作的多个SQL作为原子性操作,一旦有某一个出现错误,即可回滚到原来的状态,从而保证数据库数据完整性
存储过程
存储过程的概念
mysql将应用程序开发和数据库开发解耦,存储过程是mysql内置功能的所有的总和
存储过程的优点
1. 用于替代程序写的SQL语句,实现程序与sql解耦
2. 基于网络传输,传别名的数据量小,而直接传sql数据量大
创建简单存储过程(无参)
创建存储过程(有参)
执行存储过程
删除存储过程
函数
数学函数
聚合函数(常用于GROUP BY从句的SELECT查询中)
字符串函数
日期和时间函数
加密函数
自定义函数
流程控制
条件语句
if.....esle
循环语句
while
loop
索引原理
索引的概念
索引在MySQL中也叫做“键”,是存储引擎用于快速找到记录的一种数据结构
索引的作用
索引优化应该是对查询性能优化最有效的手段了。索引能够轻易将查询性能提高好几个数量级
索引的本质
通过不断地缩小想要获取数据的范围来筛选出最终想要的结果,同时把随机的事件变成顺序的事件,也就是说,有了这种索引机制,我们可以总是用同一种查找方式来锁定数据
索引的结构
b+树:(B+树是通过二叉查找树,再由平衡二叉树,B树演化而来)
索引字段要尽量的小
索引的最左匹配特性
索引的分类
聚集索引
它对主键的排序查找和范围查找速度非常快,叶子节点的数据就是用户所要查询的数据
范围查询(range query),即如果要查找主键某一范围内的数据,通过叶子节点的上层中间节点就可以得到页的范围,之后直接读取数据页即可
辅助索引
辅助索引的叶子节点不包含行记录的全部数据
当通过辅助索引来寻找数据时,InnoDB存储引擎会遍历辅助索引并通过叶子级别的指针获得只想主键索引的主键,然后再通过主键索引来找到一个完整的行记录
并发编程
操作系统发展史
操作系统介绍
操作系统的概念
应用程序的调用都是由操作系统实现的,操作系统会管理多个应用程序,具体执行程序是由硬件CPU管理的
多个应用程序启动会先给操作系统请求,由操作系统的算法判断硬件是否执行
多个应用程序启动会先给操作系统请求,由操作系统的算法判断硬件是否执行
核心功能
1.封装好硬件的复杂接口,给应用程序调用
2.管理应用程序上的启动的多个进程(分配给CPU资源)
第一代计算机
特点
没有操作系统的概念
所有的程序设计都是直接操控硬件
优点
程序员在申请的时间段内独享整个资源,可以即时地调试自己的程序(有bug可以立刻处理)
缺点
浪费计算机资源,一个时间段内只有一个人用
第二代计算机
特点
批处理系统
1.程序批量输入
2.顺序执行
3.程序批量输出
优点
批处理,节省了机时
缺点
整个流程需要人参与控制,将磁带搬来搬去(中间俩小人)
顺序计算->串行(仍然是一个一个执行的,把一堆程序的结果一起执行,最后全部执行完了以后输出)
影响了程序的开发效率,无法及时调试程序
第三代计算机
特点
多道技术
本质上CPU只能运行一个程序,但是不断切换的时候让人的感觉就是CPU在不断运行并发程序
多道技术中的多道指的是多个程序,多道技术的实现是为了解决多个程序竞争或者说共享同一个资源(比如cpu)的有序调度问题,解决方式即多路复用,多路复用分为时间上的复用和空间上的复用
本质上CPU只能运行一个程序,但是不断切换的时候让人的感觉就是CPU在不断运行并发程序
分时操作系统
特点
多个联机终端+多道技术
【总结】
操作系统的作用
1.隐藏丑陋复杂的硬件接口,提供良好的抽象接口
2.管理、调度进程,并且将多个进程对硬件的竞争变得有序
多道技术
1.产生背景:针对单核,实现并发
2.空间上的复用:如内存中同时有多道程序
3.时间上的复用:复用一个cpu的时间片
强调:遇到io切,占用cpu时间过长也切,核心在于切之前将进程的状态保存下来,
这样才能保证下次切换回来时,能基于上次切走的位置继续运行
这样才能保证下次切换回来时,能基于上次切走的位置继续运行
进程与线程
进程与线程初级
进程
进程的概念
进程就是一个正在执行的过程或者是一个任务,而复杂执行的任务的是CPU
进程的创建
系统初始化(查看进程linux中用ps命令,windows中用任务管理器,前台进程负责与用户交互,后台运行的进程与用户无关,运行在后台并且只在需要时才唤醒的进程,称为守护进程,如电子邮件、web页面、新闻、打印)
一个进程在运行过程中开启了子进程(如nginx开启多进程,os.fork,subprocess.Popen等)
用户的交互式请求,而创建一个新进程(如用户双击暴风影音)
一个批处理作业的初始化(只在大型机的批处理系统中应用)
进程的三种状态
就绪状态
当进程已分配到除CPU以外的所有必要资源后,只要再获得CPU,便可立即执行,进程这时的状态就称为就绪状态
执行状态
进程已获得CPU,其程序正在执行。在单处理机系统中,只有一个进程处于执行状态;在多处理机系统中,则有多个进程处于执行状态
阻塞状态
正在执行的进程,由于等待某个事件发生而无法执行时,便放弃处理机而处于阻塞状态。引起进程阻塞的事件可有多种,例如,等待I/O完成、申请缓冲区不能满足、等待信件(信号)等
进程的方法
使用multiprocessing
from multiprocessing import Process
p1 = Process(target=task, args=('panda',))
p1.start() #仅仅是给操作系统发送了一个信号
multiprocessing的Process属性和方法
join方法
主进程需要等待子进程结束以后才能运行
start方法
给操作系统发送了一个信号,是由操作系统去调度是否启动线程,执行顺序是无法确定的!
start+join方法
执行方式最后的执行时间是以子进程的最长执行时间为准,并不是串行的
is_alive方法
查看进程是否在运行
terminate方法
交给操作系统,对这个进程进行回收(不是立刻回收,操作系统需要一点时间对内存进行释放)
name方法
进程的名称
创建一个类继承Process
进程的编号
pid
操作系统对进程的管理也是需要编号的,这个编号就是进程的ID,简称为pid
ppid
父进程
僵尸进程和孤儿进程
僵尸进程
僵尸进程的概念
僵尸进程是unix或linux系统提供的一种数据结构,即使子进程已经结束了,那么父进程也可以查看子进程的状态,父进程在自己结束的时候会发起系统命令wait,结束所有的僵尸子进程
僵尸进程的特点
1.所有的子进程都是要经历僵尸进程的状态的
2.僵尸进程是有害的,因为进程的pid还在占用,僵尸进程多了,会占用多个pid,如果父进程一直不结束,僵尸进程会一直不结束,那么新的子进程就会难开启
孤儿进程
孤儿进程的概念
子进程没结束,但是父进程结束了,那么子进程就会被init的进程接管,init是所有进程的父进程,孤儿进程是无害的
生产者消费者模型
概念
生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题,生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者
解决的问题
平衡生产者消费者的数据处理速度差
程序解耦合
JoinableQueue
底层原理
在生产者和消费者之间建立一个容器,生产者往容器里生产,消费者去容器里取,这样就解决了耦合问题
线程
概念
进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才是cpu上的执行单位
多线程的概念
在一个进程中存在多个控制线程,多个控制线程共享该进程的地址空间
多线程的好处
1. 多线程共享一个进程的地址空间
2. 线程比进程更轻量级,线程比进程更容易创建可撤销
3. 若多个线程都是cpu密集型的,那么并不能获得性能上的增强,但是如果存在大量的计算和大量的I/O处理,拥有多个线程允许这些活动彼此重叠运行,从而会加快程序执行的速度
4. 在多cpu系统中,为了最大限度的利用多核,可以开启多个线程,比开进程开销要小的多
线程Thread的属性和方法
setName
1.设置线程名称
is_alive
2.查看线程是否存活
active_count
3.查看当前执行线程活跃数
enumerate
4.显示列表格式的,把当前活跃的线程对象放入列表里
守护线程
在一个进程内(只有一个线程),如果不开线程,默认就一个主线程,主线程代码运行完毕,进程就可以结束了
在一个进程内(多个线程),主线程在代码运行完以后,仍然要等其他的线程把代码运行完以后才能结束
主线程从运行角度上就代表了进程的运行周期,也就是说代码运行完毕以后要等非守护线程的其他线程都允许完毕以后才能结束,守护线程等到所有进程内所有非守护线程都结束了以后才能结束
协程
本质
单线程下,由用户自己控制一个任务遇到io阻塞了就切换另外一个任务去执行,以此来提升效率
特点
必须在只有一个单线程里实现并发
修改共享数据不需加锁
用户程序里自己保存多个控制流的上下文栈
一个协程遇到IO操作自动切换到其它协程(如何实现检测IO,yield、greenlet都无法实现,就用到了gevent模块(select机制))
进程与线程进阶
进程和线程的区别
1.开进程的开销远大于开线程的开销
2.同一个进程内的多个线程共享该进程的地址内存空间
3.pid->进程的id号都不同,但是线程的pid号是相同的
加锁机制
互斥锁
把并行变成串行,牺牲了执行的效率来保证数据的安全
GIL全局解释锁
本质
就是一把互斥锁,所以在python中cpu只能实现一次运行一个线程
作用
1.保证了线程数据的执行安全,但是牺牲了数据的处理效率
2.对于cpython解释器来说,并不能用上多核优势(当启动了一个进程,这个进程内有多个线程,这样是不能同时执行多个线程的,只能单线程的执行)
与互斥锁的区别
GIL是解释器级别的,是保证垃圾回收机制的数据的
码内的互斥锁是保证了代码之间的数据的安全,不同的数据级别要用不同的锁
死锁与递归锁
死锁的概念
是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程
递归锁的概念
在Python中为了支持在同一线程中多次请求同一资源,python提供了可重入锁RLock。
这个RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require
这个RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require
递归锁和互斥锁的区别
递归锁可以连续acquire多次,而互斥锁只能acquire一次
进程与线程的使用场景
如果并发的多个任务是计算密集型:多进程效率高
如果并发的多个任务是I/O密集型:多线程效率高
信号量
概念
信号量也是一把锁,可以指定信号量为5
意义
信号量同一时间可以有5个任务拿到锁去执行
信号量就是可以多个线程在运行
Event事件
使用场景
Event机制来协调各个工作线程的连接操作
定时器
概念
隔多少时间去触发一个任务
作用
可以产生验证码的时候设置时间
线程队列
先进先出
class queue.Queue(maxsize=0)
堆栈(后进先出)
class queue.LifoQueue(maxsize=0)
优先级队列:存储数据时可设置优先级的队列
class queue.PriorityQueue(maxsize=0)
进程池与线程池
本质
池本质就是开进程和线程,本质没有区别
计算密集型
需要用多核的优势时候就要用进程池
IO密集型
不需要过多CPU资源的时候就要用线程池
gevent模块
作用
检测IO
打补丁,所有的设计IO操作的部分都全部打上补丁,做上标记
from gevent import monkey;monkey.patch_all()
IO模型介绍
阻塞IO模型
所谓阻塞型接口是指系统调用(一般是IO接口)不返回调用结果并让当前线程一直阻塞,只有当该系统调用获得结果或者超时出错时才返回
非阻塞IO模型
轮询
在非阻塞式IO中,用户进程其实是需要不断的主动询问kernel数据准备好了没有
对cpu损耗大,不推荐
多路复用IO模型
事件IO驱动
select监听
相比其他模型,使用select() 的事件驱动模型只用单线程(进程)执行,占用资源少,不消耗太多 CPU,同时能够为多客户端提供服务。如果试图建立一个简单的事件驱动的服务器程序,这个模型有一定的参考价值
异步IO模型
当用户线程收到通知时,数据已经被操作系统从内核拷贝到用户指定的缓冲区内,用户线程直接使用即可
0 条评论
下一页