第三十五章
数据库初识
数据库管理系统-DBMS
网络应用服务端
咱们要使用服务端的数据 - 须要有一个客户端
客户端能够本身写 : 将来写代码的时候
也能够用别人写好的 : 第三方的工具 数据库管理软件的公司出版的官方客户端
数据库管理系统本质上也是管理一堆文件
只不过人家的管理方式比咱们更高效 更安全
数据库管理员-DBA
搭建数据库服务环境
用户的建立 权限的管理
性能\语句的优化
数据库的二次开发 : 让数据库具备公司的特质
软件
mysql : 小公司 互联网企业
甲骨文 oracle : 事业单位 金融企业
微软 sql server
sqllite
名词
DB 数据库 - 文件夹
table 表 - 文件
data 一条数据-每一行数据
数据库的分类
关系型数据库 mysql oracle sqlserver sqllite
非关系型数据库 redis mongodb memcache hbase
第三十六章
# 你启动的mysql.exe是客户端 S 你安装的服务是server
# 在客户端须要指定 要登陆的数据库所在的ip 以及用户名和密码
# mysql -uroot -p123 -h192.168.12.45
# mysql> set password = password('123'); 设置密码
# 须要注意要在sql的结尾输入;表示整个sql语句的结束
# 若是忘记了能够在换行以后补上。
# \c表示放弃当前行要执行的sql语句
# exit 表示退出客户端
# 用户
# create user '用户名'@'容许的网段' identified by '密码'
# grant usage on 数据库.表 to 'eva'@'%';
# grant select on 数据库.* to 'eva'@'%';
# grant update on *.* to 'eva'@'%';
# grant insert on *.* to 'eva'@'%';
# grant delete on *.* to 'eva'@'%';
# grant all on ftp.* to 'eva'@'%';
# show databases; 查看当前的全部库
# create database ftp;
# mysql -ueva -h192.168.12.22 -p123
# mysql> select user();
基础操做
# 你启动的mysql.exe是客户端 S 你安装好的服务是server
# 在客户端须要指定 要登陆的数据库所在的ip 以及用户名和密码
# mysql -uroot -p123 -h192.168.12.45
# mysql> set password = password('123'); 设置密码
# 须要注意要在sql的结尾输入;表示整个sql语句的结束
# 若是忘记了能够在换行以后补上。
# \c表示放弃当前行要执行的sql语句
# exit 表示退出客户端
# 用户
# create user '用户名'@'容许的网段' identified by '密码'
# grant usage on 数据库.表 to 'eva'@'%';
# grant select on 数据库.* to 'eva'@'%';
# grant update on *.* to 'eva'@'%';
# grant insert on *.* to 'eva'@'%';
# grant delete on *.* to 'eva'@'%';
# grant all on ftp.* to 'eva'@'%';
# show databases; 查看当前的全部库
# create database ftp;
# mysql -ueva -h192.168.12.22 -p123
# mysql> select user();
建立表
# 数据类型
# 数字类型
# 整数 tinyint int
# 小数 float double
# 字符串
# 定长、节省时间、浪费空间 char(255)
# 变长、节省空间、浪费时间 varchar(65535)
# 时间类型
# now()函数表示当前时间
# datetime 年月日时分秒 0000-9999
# date 年月日
# time 时分秒
# year 年
# timestamp 年月日时分秒 1970-2038
# enum和set
# enum 单选
# set 多选
数值类型和字符串
# 整数
# create table t1(i1 tinyint,i2 int);
# 默认建立的全部数据都是有符号的
# create table t2(i1 tinyint unsigned,i2 int unsigned);
# unsigned表示无符号
# 小数
# create table t3(f1 float,f2 double)
# create table t4(f1 float(7,2))
# 字符串
# char(25)
# 'abc ' 浪费空间、节省时间
# varchar(25)
# '3abc' 节省空间、浪费时间
# create table t5(c1 char(5),c2 varchar(5));
时间类型和枚举集合
# create table t6(dt datetime,d date,t time,y year,ts timestamp);
# insert into t6 values(now(),now(),now(),now(),now());
# insert into t6(dt) values('2018-8-8 8:8:8');
# insert into t6(dt) values(20180808080808);
# insert into t6(d) values(20180808);
# insert into t6(t) values('8:8:8');
# create table t7(dt datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,y year);
# create table t8(username char(12),gender enum('male','female'));
# create table t9(username char(12),hobby set('抽烟','喝酒','烫头','洗脚'));
第三十七章
select
# select * from 表;
# 指定列查询
# select emp_name,salary from employee;
# 在列中使用四则运算
# select emp_name,salary*12 from employee;
# 重命名
# select emp_name,salary*12 as annul_salary from employee;
# select emp_name,salary*12 annul_salary from employee;
# 去重
# select distinct post from employee;
# select distinct sex,post from employee;
# 函数 concat() 拼接
# select concat('姓名 :',emp_name),concat('年薪:',salary*12) from employee;
# select concat_ws('|','a','b','c')
# case when语句 == if条件判断句
where语句 根据条件筛选行
# 比较运算 = > < >= <= !=/<>
# select * from employee where age>18;
# select * from employee where salary<10000;
# select * from employee where salary=20000;
# between a and b #[a,b]
# select * from employee where salary between 10000 and 20000;
# in
# select * from employee where salary in (17000,19000);
# like 模糊查询
# _ 通配符 表示一个字符长度的任意内容
# select * from employee where emp_name like 'jin___'
# % 通配符 表示任意字符长度的任意内容
# select * from employee where emp_name like 'jin%'
# select * from employee where emp_name like '%g'
# select * from employee where emp_name like '%n%'
# regexp 正则匹配
# select * from employee where emp_name regexp '^jin'
逻辑运算
# and
# select * from employee where age>18 and post='teacher';
# or
# select * from employee where salary<10000 or salary>30000;
# not
# select * from employee where salary not in (10000,17000,18000);
关于null
# 查看岗位描述为NULL的员工信息
# select * from employee where post_comment is null;
# 查看岗位描述不为NULL的员工信息
# select * from employee where post_comment is not null;
5个聚合函数
# count
# max
# min
# avg
# sum
分组聚合 group by
# 查询岗位名以及岗位包含的全部员工名字
# select post,group_concat(emp_name) from employee group by post;
# 查询各部门年龄在20岁以上的人的平均薪资
# select post,avg(salary) from employee where age>20 group by post;
# select * from 表 where 条件 group by 分组
过滤 having (group by + 聚合函数)
# 查询平均薪资大于1w的部门
# select avg(salary) from employee group by post having avg(salary) > 10000
# 1. 查询各岗位内包含的员工个数小于2的岗位名、岗位内包含员工名字、个数
# select post,emp_name,count(id) from employee group by post having count(id)<2
# 2. 查询各岗位平均薪资大于10000的岗位名、平均工资
# select post,avg(salary) from employee group by post having avg(salary) > 10000
# 3. 查询各岗位平均薪资大于10000且小于20000的岗位名、平均工资
# select post,avg(salary) from employee group by post having avg(salary) between 10000 and 20000;
order by 排序
# 升序
# select * from employee order by salary;
# select * from employee order by salary asc;
# 降序
# select * from employee order by salary desc;
# select * from employee order by age,salary;
# select * from employee order by age,salary desc;
# select * from employee order by age desc,salary;
limit 取行
# select * from 表 order by 列 limit n; 取前n条
# select * from 表 order by 列 limit m,n; 从m+1开始,取n条
# select * from 表 order by 列 limit n offset m; 从m+1开始,取n条
顺序:
select * from 表 where 条件 group by 分组 having 过滤 order by 排序 limit n;
第三十八章
pymysql模块
import pymysql
# conn = pymysql.connect(host='localhost', user='root', password="123",
# database='day38')
# cur = conn.cursor(pymysql.cursors.DictCursor) # cur游标 cur数据库操做符
# 对数据的增删改查
# ret = cur.execute('select * from books')
# ret 影响行数 在这里表示查到7行数据
# for i in range(ret):
# row1 = cur.fetchone() # 每次取一条数据
# print(row1)
# row2 = cur.fetchmany(3) # 按照指定参数取n条
# print(row2)
# row3 = cur.fetchall() # 取全部,过于浪费内存
# print(row3)
# insert update delete conn.commit()
# cur = conn.cursor() # cur游标 cur数据库操做符
# cur.execute('insert into books values("学python从开始到放弃","alex","人民大学出版社",50,"2018-7-1")')
# conn.commit()
# cur = conn.cursor()
# sql = 'insert into books values(%s,%s,%s,%s,%s)'
# # 操做文件
# with open('file',encoding='utf-8') as f:
# for line in f:
# try:
# lst = line.strip().split('|')
# cur.execute(sql,lst)
# conn.commit()
# except:
# conn.rollback()
# cur.close()
# conn.close()
# sql注入
# 登录注册 + 数据库
# 表 userinfo
# cur = conn.cursor()
# name = input('user:')
# passwd = input('password:')
# sql = "select * from userinfo where username = %s and password = %s;"
# print(sql)
# ret = cur.execute(sql,(name,passwd))
# if ret:
# print('登录成功')
# else:
# print('登录失败')
# sql注入
# select * from userinfo where username = 'xxx' or 1=1 ; -- ' and password =
多表查询
# 怎么让两张表之间产生关系?
# 连表
# 内链接(全部不在条件匹配内的数据,都会被剔出连表)
# 方式一 :select * from employee,department where dep_id = department.id;
# 方式二 :select * from employee inner join department on dep_id = department.id;
# 外链接
# 左外链接 left join
# select * from employee left join department on dep_id = department.id;
# 右外链接 right join
# select * from employee right join department on dep_id = department.id;
# 全外链接 full join
# select * from employee left join department on dep_id = department.id
# union
# select * from employee right join department on dep_id = department.id
#示例1:之内链接的方式查询employee和department表,而且employee表中的age字段值必须大于25,即找出年龄大于25岁的员工以及员工所在的部门
# select employee.name,department.name from employee inner join department on dep_id = department.id where age>25;
# select e.name ename,d.name dname from employee e inner join department d on dep_id = d.id where age>25;
# select e.name,d.name from employee e inner join department d on dep_id = d.id where age>25;
#示例2:之内链接的方式查询employee和department表,而且以age字段的升序方式显示。
# select * from employee inner join department on dep_id = department.id order by age;
# 子查询
# 查询平均年龄在25岁以上的部门名
# select name from department where id in (select dep_id from employee group by dep_id having avg(age)>25);
# 查看技术部员工姓名
# 先查询技术部的id
# select id from department where name = '技术';
# 根据技术部id查询employee表 找到技术部id对应的人名
# select * from employee where dep_id = 200;
# 结果
# select name from employee where dep_id = (select id from department where name = '技术');
# 查看不足1人的部门名(子查询获得的是有人的部门id)
# 先从employee中查有多少个部门有人
# select distinct dep_id from employee;
# 从department表中把不在上述部门中的那些项找出来
# select * from department where id not in (200,201,202,204);
# 结果
# select * from department where id not in (select distinct dep_id from employee);
# 查询大于全部人平均年龄的员工名与年龄
# 全部人的平均年龄
# select avg(age) from employee; # 28
# 查大于上述平均年龄的人
# select name,age from employee where age>28;
# 结果
# select name,age from employee where age>(select avg(age) from employee);
# 查询大于部门内平均年龄的员工名、年龄
# 查询各部门平均年龄
# select dep_id,avg(age) from employee group by dep_id;
# 查大于部门平均年龄的人
# select * from employee where dep_id = 200 and age>18
# select * from employee where dep_id = 201 and age>43
# select * from employee where dep_id = 202 and age>28
# select * from employee where dep_id = 204 and age>18
# 结果
# select * from employee inner join (select dep_id,avg(age) as avg_age from employee group by dep_id) as t
# on employee.dep_id = t.dep_id;
#
# select * from employee inner join (select dep_id,avg(age) as avg_age from employee group by dep_id) as t
# on employee.dep_id = t.dep_id where age>avg_age;
第三十九章
存储引擎
# show create table books;
# show engines;
# 什么是存储方式、存储机制(存储引擎)
# 表结构 存在一个文件中 : 硬盘上
# 表数据 存在另外一个文件中、内存中
# 索引(目录) 为了方便查找设计的一个机制 :
# 存储引擎的种类
# innodb : 索引+数据 表结构 数据的持久化存储
# 事务 :一致性 n条语句的执行状态是一致的
# begin; # 开启事务
# select id from innot where id =1 for update;
# update innot set id = 2 where id = 1;
# commit; # 提交事务 解锁被锁住的数据,让他们可以被修改
# 行级锁 :只对涉及到修改的行加锁,利于并发的修改,可是对于一次性大量修改效率低下
# 表级锁 :一次性加一把锁就锁住了整张表,不利于并发的修改,可是加锁速度比行锁的效率要高
# 外键约束 :被约束表中的数据不能随意的修改/删除 约束字段据要根据被约束表来使用数据
# myisam : 索引 数据 表结构 数据的持久化存储
# 表级锁
# memory : 表结构
# 数据断电消失
# create table innot(id int) engine = innodb;
# create table myist(id int) engine = myisam;
# create table memot(id int) engine = memory;
约束
# not null 非空约束
# create table t1(id int not null,name char(12));
# 默认插入0,严格模式报错
# create table t2(id int,name char(12) not null);
# 默认插入空字符串,严格模式报错
# default 默认值 default
# create table t3(id int,name char(12),sex enum('male','female') default 'male');
# 非空约束 和 默认值
# create table t3(id int not null,name char(12) not null,sex enum('male','female') not null default 'male');
# unique惟一约束 (不能重复)
# create table t4(id int unique,name char(12));
# 联合惟一约束
# create table t5(family char(12),name char(12),unique(family,name));
# create table t5(family char(12) not null,name char(12) not null,unique(family,name)); # 约束各自不能为空 且联合惟一
# 惟一+非空 id name
# create table t6(id int not null unique`11111111111111111111111, name char(12) not null unique);
# pri 是怎么产生的? 第一个被设置了非空+惟一约束会被定义成主键 primary key
# 主键在整张表中只能有一个
# 主键(非空+惟一)
# create table t6(id int primary key, name char(12) not null unique);
# create table t5(family char(12) ,name char(12),primary key(family,name)); # 约束各自不能为空 且联合惟一 还占用了整张表的主键
# 对某一列设置自增 auto_increment(自动增长,not null约束)
# create table t6(id int auto_increment, name char(12)); # 报错
# create table t7(id int unique auto_increment, name char(12) primary key) ;
# create table t8(id int primary key auto_increment, name char(12)) ;
# create table t9(id int unique auto_increment, name char(12)) auto_increment=100000;
# delete from t7; 清空表数据但不能重置auto_increment
# truncate table t7; # 清空表而且重置auto_increment
# 全部的操做都没法改变auto_increment的自动计数。可是咱们也没有必要去改变它。
# 1.至少要看到自增的效果
# 2.至少写3条数据 4,5,6
# 3.删掉第5条,再看结果
# 4.再insert一条数据
# 5.删掉第5条,再看结果
# 6.再insert一条数据
# 7.清空整张表
# 8.再insert一条数据,再看结果
# 修改auto_increment
# alter table 表名 auto_increment = n; 修改表的auto_increment
# alter table t7 auto_increment = 1000; 修改表的auto_increment
# 外键
# 没有创建外键:
# create table stu(id int,name char(12),class_id int);
# create table class(cid int,cname char(12));
# insert into stu values (1,'日魔',1),(2,'炮手',1)
# insert into class values(1,'py27');
# insert into class values(2,'py28');
# select * from stu,class where class_id = cid;
# delete from stu where id = 1;
# delete from class where cid = 1;
# stu2 class2
# create table class2(cid int unique,cname char(12));
# create table stu2(id int,name char(12),class_id int,foreign key(class_id) references class2(cid));
# insert into class2 values(1,'py27');
# insert into stu2 values (1,'日魔',1),(2,'炮手',1)
# delete from class2 where cid = 1;
# insert into class2 values(2,'py28');
# update class2 set cid = 1 where cid = 2; 不能修改
# stu3 class3 级联更新
# create table class3(cid int primary key,cname char(12));
# create table stu3(id int,name char(12),class_id int,foreign key(class_id) references class3(cid) on update cascade);
# insert into class3 values(1,'py27');
# insert into stu3 values (1,'日魔',1),(2,'炮手',1)
# update class3 set cid = 2; 修改了class3中的cid,stu3中相关的数据也会跟着变化,是on update cascade设置致使的
第四十章
表的修改
# create table
# drop table
# desc 表名;
# alter table
# alter table 表名 rename 表名;
# alter table 表名 charset 编码;
# alter table 表名 auto_increment 自增的位置;
# alter table 表名 add 字段名 类型(长度) 约束;
# alter table 表名 drop 字段名;
# alter table 表名 change 字段名 新名字 类型(长度) 约束;
# alter table 表名 modify 字段名 新类型(新长度) 约束;
# name id age
# alter table 表名 change id id 类型(长度) 约束 first;
# alter table 表名 change id id 类型(长度) 约束 after age;
# alter table 表名 add 字段名 类型(长度) 约束 first;
# alter table 表名 add 字段名 类型(长度) 约束 after name;
表与表之间的关系
# 一对多 foreign key
# create table class(id int primary key,cname char(12));
# create table student(id int primary key,sname char(16),cid int,
# foreign key(cid) references class(id));
# 多对多
# create table class(id int primary key,cname char(12));
# create table teacher(id int primary key,tname char(12));
# create table teach_cls(id int,cid int,tid int,
# foreign key(cid) references class(id)),
# foreign key(tid) references teacher(id))
# );
# 一对一
# create table guest(id int primary key,name char(12));
# create table student(id int primary key,sname char(12),gid int unique,
# foreign key(gid) referances guest(id));
索引原理
# 磁盘预读性原理
# 1个block块 4096个字节/9ms
# 树
# 树 根节点 分支节点 叶子节点
# 平衡树 balance tree - B树
# 汇集索引/聚簇索引 : 叶子节点会存储整行数据 —— innodb的主键
# 辅助索引/非汇集索引 :除了主键以外的普通索引都是辅助索引,一个索引没办法查到整行数据,须要回汇集索引再查一次(回表)
# b+树 是为了更好的处理范围问题在b树的基础上有所优化
# mysql中innodb存储引擎的全部的索引树都是b+树
索引优缺点:
优势:加快查询速度
缺点:下降写的速度,占用更多的磁盘空间
第四十一章
索引
# 索引 : index / unique / primary key
# 操做索引 :建立和删除
# 建立 :create index 索引名 on 表名(字段名);
# create index ind_id on s1(id);
# create index ind_id2 on s1(id);
# 删除 :drop index 索引名 on 表名;
# drop index ind_id2 on 表名;
# 正确的使用索引(******)
# 1.只有对建立了索引的列进行条件筛选的时候效率才能提升
# 2.索引对应的列作条件不能参与运算、不能使用函数
# 3.当某一列的区分度很是小(重复率高),不适合建立索引
# 4.当范围做为条件的时候,查询结果的范围越大越慢,越小越快
# 5.like关键字 : 若是使用%/_开头都没法命中索引
# 6.多个条件 : 若是只有一部分建立了索引,条件用and相连,那么能够提升查询效率
# 若是用or相连,不能提升查询效率
# and
# select count(*) from s1 where id=1000000 and email = 'eva1000000@oldboy';
# or
# select count(*) from s1 where id=1000000 or email = 'eva1000000@oldboy';
# 7.联合索引
# creat index ind_mix on s1(id,name,email);
# select count(*) from s1 where id=1000000 and email = 'eva1000000@oldboy'; 快
# select count(*) from s1 where id=1000000 or email = 'eva1000000@oldboy'; 慢 条件不能用or
# select count(*) from s1 where id=1000000; 快
# select count(*) from s1 where email = 'eva1000000@oldboy'; 慢 要服从最左前缀原则
# select count(*) from s1 where id>1000000 and email = 'eva1000000@oldboy'; 慢 从使用了范围的条件开始以后的索引都失效
# 基础概念(介绍)
# explain 执行计划
# explain select count(*) from s1 where id=1000000 and email = 'eva1000000@oldboy';
# 覆盖索引
# 在查询的过程当中不须要回表 -- 覆盖索引 using index
# explain select count(*) from s1 where id < 1000;
# 索引合并
# explain select count(*) from s1 where id=1000000 or email = 'eva1000000@oldboy';