通常为了高可用,还会备份大量的数据到备用数据库,当运行的数据库死掉以后能够接替原来的数据库python
数据库的优点mysql
什么是数据linux
什么是数据库面试
什么是数据库管理系统(DataBase Management System)简称DBMSredis
概念sql
数据库的分类mongodb
mysql数据库
https://downloads.mysql.com/archives/community/windows
下载以后点击安装包进行安装安全
环境变量的配置:
在任何目录下都能找到对应的文件
才能在任意位置输入命令启动该应用
windows下mysql install 安装mysql服务 mysql服务就被注册到操做系统中
net start mysql 启动mysql
net stop mysql 关闭mysql
启动客户端链接server
mysql -u root -p
输入密码
或者 mysql -uroot -p123456
mysql -uroot -p123456
mysql帐号操做
#进入mysql客户端 $mysql mysql> select user(); #查看当前用户 mysql> exit # 也能够用\q quit退出 # 默认用户登录以后并无实际操做的权限 # 须要使用管理员root用户登录 $ mysql -uroot -p # mysql5.6默认是没有密码的 #遇到password直接按回车键 mysql> set password = password('root'); # 给当前数据库设置密码 # 建立帐号 # create user '用户名'@'主机ip/主机域名' identified by '密码'; mysql> create user 'wrr'@'192.168.10.%' IDENTIFIED BY '123';# 指示网段 mysql> create user 'wrr'@'192.168.10.5' # 指示某机器能够链接 mysql> create user 'wrr'@'%' #指示全部机器均可以链接 mysql> show grants for 'wrr'@'192.168.10.5';查看某个用户的权限 # 远程登录 $ mysql -uroot -p123 -h 192.168.10.3 # 给帐号受权 #grant select on 数据库名.* to '用户名'@'主机的ip/主机域名' mysql> grant all on *.* to 'wrr'@'%'; #grant 权限类型 #grant all 给全部的权限 #grant select,insert 给查询和插入的权限 mysql> flush privileges; # 刷新使受权当即生效 # 建立帐号并受权 mysql> grant all on *.* to 'wrr'@'%' identified by '123'
SQL语言主要用于存取数据、查询数据、更新数据和管理关系数据库系统,SQL语言由IBM开发。SQL语言分为3种类型:
一、DDL语句 数据库定义语言(defined): 数据库、表、视图、索引、存储过程,例如CREATE DROP ALTER
二、DML语句 数据库操纵语言(manager): 插入数据INSERT、删除数据DELETE、更新数据UPDATE、查询数据SELECT
三、DCL语句 数据库控制语言(control): 例如控制用户的访问权限GRANT、REVOKE
show engines; 查看支持的存储引擎
show variables like '%engin%'; 查看默认的引擎
Support:mysql是否支持这种存储引擎
mysql5.6 默认为Innodb存储引擎
Myisam 在mysql5.5以前默认的存储引擎 表锁
操做数据的代码-》 存储引擎 - 〉数据
(1)数据存储在硬盘上
数据和索引存储在一块儿 2个文件 Innodb存储引擎 数据持久化
数据索引一个文件
表结构一个文件
Transactions:事务,保持数据安全
Supports transactions:支持事务,保证数据的完整性,将多个操做变成原子性操做
开启事务-》 执行原子性操做-〉提交事务
row-level locking:行级锁:修改的行少的时候使用,修改数据频繁的时候
表级锁:批量修改多行,对于大量数据的同时修改
foreign keys:外键,约束两张表中的关联字段不能随意的添加、删除,下降数据增删改的出错率
学生表中能够添加学生的姓名和年龄,再设置一个id 一、2
在班级表里设置id 一、2分别表示一班和二班,显示对应的班级人数
可是想要在学生表中id能够设置为3,若是想要学生表的id根据班级表存在的id进行设置,那么可给id加上外键,当id设置为3会报错
而且当学生表中有设置id为2的,那么班级表中的二班不能删除
数据和索引不须要存储在一块儿 3个文件 Myisam存储引擎 数据持久化
(2)数据存在内存中,也就是说断电数据消失 1个文件 Memory 存储引擎
表结构
MEMORY:Hash based基于哈希的,存储在内存中,useful for temporary tables对临时表很是有用
通常像首页的热点新闻就会存储在memory中,查找不到再到大表中查找
面试题:
你了解mysql存储引擎吗?
你的项目用了什么存储引擎?
数字 和 bool
字符串
char 0-255字节 经常使用于身份证号、手机号、qq号(12位的qq更多)、username(12-18)、password(10-16)
varchar 0-65535字节 经常使用于评论、朋友圈、微博
时间
datetime 八个字节20210415121900 表示范围1000-01-01 00:00:00/9999-12-31 23:59:59
year 一个字节 1901/2155
date 三个字节 20210415 表示范围1000-01-01/9999-12-31
time 三个字节 121900 表示范围 '-838:59:59'/'838:59:59'
timestamp 四个字节 1970-01-01 00:00:00/2038 默认值为当前时间戳 不能为空 更新其余数据的时候自动按照当前的时间戳更新最新的时间戳,像登录的时候,能够记录最后一次登录的时间
enum/set
按照必定的范围选择
无符号的:只和数字有关 unsigned
不能为空 not null
默认值 default
不能重复 unique 值不能重复,null能够写入多个 第一个被定义为非空+惟一的那一列会成为这张表的primary key
联合惟一 unique
create table t14( id int, server_name char(12), ip char(15), port char(5), unique(ip, port) );
自增 auto_increment 只能对数字有效,自带非空约束,至少是unique的约束以后才能使用auto_increment
create table t16( id int primary key auto_increment, name char(12) )
主键:非空+惟一约束 = 主键 primary key 一张表只能定义一个主键 若是不指定主键 默认是第一个非空+惟一
联合主键 primary key( )
create table t17( id int, server_name char(12), ip char(15), port char(5), primary key(ip, port) );
外键: foreign key (本身的字段) references 外表(外表字段)
外表字段必须至少是惟一的
学生表
create table student( id int primary key auto_increment, name char(12) not null, gender enum('male', 'female') default 'male', class_id int, foreign key(class_id) references class_t(cid) );
班级表
create table class_t( cid int primary key auto_increment, cname char(12) not null, startd date );
须要先创建班级表,而且写入数据,让学生表能够关联到
且学生表内有关联到班级表的,须要修改班级或者删除,才能对班级表进行修改或者删除
须要级联更新、级联删除,能够在foreign key(class_id) references class_t(cid) on update cascade on delete cascade
删除班级表中一个班,那学生表中关联这一个班的数据也会删除
注意空字符串' '和空null在数据库中不同
语法: 1. 修改表名 ALTER TABLE 表名 RENAME 新表名; 2. 增长字段 ALTER TABLE 表名 ADD 字段名 数据类型 [完整性约束条件…], ADD 字段名 数据类型 [完整性约束条件…]; 3. 删除字段 ALTER TABLE 表名 DROP 字段名; 4. 修改字段 ALTER TABLE 表名 MODIFY 字段名 数据类型 [完整性约束条件…]; ALTER TABLE 表名 CHANGE 旧字段名 新字段名 旧数据类型 [完整性约束条件…]; ALTER TABLE 表名 CHANGE 旧字段名 新字段名 新数据类型 [完整性约束条件…]; 5.修改字段排列顺序/在增长的时候指定字段位置 ALTER TABLE 表名 ADD 字段名 数据类型 [完整性约束条件…] FIRST; ALTER TABLE 表名 ADD 字段名 数据类型 [完整性约束条件…] AFTER 字段名; ALTER TABLE 表名 CHANGE 字段名 旧字段名 新字段名 新数据类型 [完整性约束条件…] FIRST; ALTER TABLE 表名 MODIFY 字段名 数据类型 [完整性约束条件…] AFTER 字段名;
多对一:
学生-班级
多个学生是一个班级的
学生表有一个外键关联班级
书籍-做者
商品-订单
多对多:
一对一:
select * from employee;
select id,name from employee; 查询几个字段
select id,name as n from employee; 查询出来的时候重命名(加as)
select id,name n from employee; 查询出来的时候重命名(空格)
select distinct post from employee; 查询结果去除重复项
select distinct age,sex from employee; 查询的结果只有当年龄和性别都重复才会是重复项
select emo_name,salary*12 as annual_salary from employee; 四则运算(计算年薪)
select concat(emp_name,':',salary) from employee; 拼接concat,有时候姓和名的拼接
select concat_ws('|','apple','male'); 默认以第一个字符为拼接符进行拼接后面的内容
结合case语句 case ... end
selcet ( case when emp_name = 'apple' then emp_name when emp_name = 'banana' then concat(emp_name, 'BIGSB') else concat(emp_name, 'SB') end ) as new_name from employee;
筛选符合条件的行
group by :
根据谁分组,能够求这个组的总人数,最大值,最小值,平均值,求和,可是求出来的值只和分组字段对应
并不和其余任何字段对应,这个时候查出来的全部字段都不生效
count(根据分组计数) max min sum avg
select sex,count(sex) from employee group by sex; 显示男女分别有多少人
select age,count(age) from employee group by age; 显示不一样的年龄有多少人
更好的查看
select post,group_concat(emp_name) from employee group by post; 会自动拼接,可是拿不到每个的值
选择各个部门最低工资的人
select post,emp_name,min(salary) from employee group by post; 这是错误的,由于分组显示的姓名不是真正工资最低的,是分组出来
找不到对应的人
在having条件中可使用聚合函数
适合去筛选符合条件的某一组数据,而不是某一行数据
先分组,再过滤:求人数大于xx的性别,求年龄大于多少人的年龄
获取每一个部门的平均工资筛选出平均值大于10000的部门
select post,avg(salary) from employee group by post having avg(salary) > 10000;
默认升序排 asc
降序 desc
select * from employee order by selery; 根据薪资从小到大排
select * from employee order by age desc; 根据年龄从大到小排
select * from employee order by age,salary desc; 先根据年龄从小到大排,年龄相同,再根据薪资从大到小排
limit n 取前几条数据 不写m默认为0
select * from employee order by selery desc limit 3; 只取薪资最高的前三我的的数据
limit m,n 从第m+1项开始取n项
limit n offset m 与上面相同,从m+1项开始取n项
连表查询
一张department表,一张employee员工表
select * from department, employee; 会产生一个大表,表是笛卡尔积的形式产生的
select * from department, employee where department.id = dep_id; id有多个须要指定是department仍是employee表里的
所谓连表:
表与表之间的链接方式:
查询平均年龄在25岁以上的部门
select dep_id from employee group by dep_id having avg(age)>25;
select name from department where id in (select dep_id from employee group by dep_id having avg(age)>25);
查看技术部员工姓名
select name from employee where dep_id in (select id from department where name='技术');
查询大于全部人平均年龄的员工名与年龄
select name, age from employee where age>(select avg(age) from employee);
查询大于部门内平均年龄的员工名与年龄
select name,age from employee as t1 inner join (select dep_id,avg(age) as avg_age from employee group by dep_id) as t2 on t1.dep_id=t2.dep_id where age>avg_age;
exists关键字表示存在,使用这个关键字以后内层查询语句不返回查询的记录,返回一个真假值,返回True,外层查询语句将进行查询,当返回值为False,外层查询语句不进行查询
select * from employee where exists (select id from department where id=200);
工做中必备:
建立
删除
知道用了它会加快查询速度
面试:
函数都是处理简单的逻辑
存储过程处理的逻辑比较复杂
复杂的逻辑都是用python代码来处理
简单的数据增删改查用sql解决
查询过程当中不须要回表
分别建立的两个索引在某一次查询中临时合并成一条索引 a=1 or b=2
explain select 语句 可以查看sql语句有没有按照预期执行,能够查看索引的使用状况,type等级
通常都是经过python操做数据
import pymysql conn = pymysql.connect(host='127.0.0.1', user='root', password='123', database='homework') cur = conn.cursor() #cursor游标 默认以元组返回 #cur = conn.cursor(cursor=pymysql.cursors.DictCursoor) #取出来的数据是以字典返回 更浪费空间 cur.execute('select * from student;') ret = cur.fetchone() print(ret) # 拿到一条数据 ret2 = cur.fetchmany(10) # 拿到多条数据 print(ret2) ret3 = cur.fetchall() # 拿到全部剩余的数据 print(ret3) print(cur.rowcount) # 表示拿到多少条数据 cur.close() conn.close()
#增 删 改 import pymysql conn = pymysql.connect(host='127.0.0.1', user='root', password='123', database='homework') cur = conn.cursor() try: cur.execute('insert into student values(17, "男", 3, "apple")') #执行了只至关于在内存中插入 cur.execute('update student set gender ="male" where id=17') # 修改 cur.execute('delete from student where id=17') conn.commit() #提交 except Exception as e: print(e) conn.rollback() # 回滚 cur.close() conn.close()
实际在操做中会遇到的问题
结合数据库和python写一个登录
import pymysql usr = input('username :') pwd = input('password :') conn = pymysql.connect(host='127.0.0.1', user='root', password='123', database='test' ) conn.cursor() cur.execute('select * from userinfo where user="%s" and password="%s"'%(usr, pwd)) # select * from userinfo where user = "apple" or 1=1; --"... 后面的东西注释了 #sql注入 #最好使用execute自动拼接 cur.execute('select * from userinfo where user=%s and password=%s', (usr, pwd)) #不用拼接,也不用加"" cur.close() conn.close()
事务
锁
begin #开启事务 select age from userinfo where id=1 for update; # 查询id值,for update 加上行级锁 update emp set salary=100000 where id=1; # 完成更新 commit #提交事务
备份
表和数据的备份
mydqldump.exe
在cmd命令直接执行
mysqldump -h 服务器 -u用户名 -p密码 数据库名 > 备份文件名.sql
回复数据 在mysql中执行命令
source D:\python\备份文件名.sql
数据的
增
删
改
查
select 字段 from 表
顺序:from 表--> where -> group by -> having -> select -> order by -> limit m,n
拓展
在执行select语句的时候,其实是经过where,group by,having这几个语句锁定对应的行
而后循环每一行执行select语句
select name from t where id>2;
先from t,再where id>2拿到数据,再循环拿到的数据,筛选name字段
select name,(select_now()) from t; 一样也是循环拿到数据进行筛选
若是一个问题既可使用连表查询也可使用子查询解决,推荐那个连表查询,效率更高
习题:
查询至少有一门可与学号为1的同窗所学课程相同的同窗的学号和姓名
select sid,sname from student right join (
select distinct student_id from score where cid in (select course_id from score where student_id=1) and student_id != 1;
) as t in student_sid = t.student_id;
查询课程编号为‘2’的成绩比课程编号‘1’低的全部同窗的学号、姓名
正确的使用mysql数据库