(一)索引
索引:数据库的性能调优;提升数据库的工作效率。
1、索引分类(逻辑分类)
1、主键索引:主键索引是一种唯一性索引,即不允许为空以及值重复
2、唯一性索引:在创建表的时候加上unique,值必须是唯一的
3、普通索引:执行任务的时候可以加快对数据的访问速度;没有任何限制条件。使用的关键字index或者key
4、空间索引:空间索引主要用于地理空间的数据类型。
5、全文索引:全文索引只能在varchar或text类型的字段上。
2、使用索引
索引可以在一定情况下可以加快查询速度,但是在某些情况下会降低效率
当表的查询大于修改、删除的操作 , 可以创建索引;
表查询的操作很少,表的数据很少使用到,不建议创建索引;
3、创建索引
-- 在创建表的时候创建索引
create table 表名(
字段名 数据类型,
字段名 数据类型,
index 索引名(字段名),
unique 索引名(字段名)
);
-- 在已有表中创建索引
create index 索引名 on 表名(字段名);
-- 唯一索引
create unique index 索引名 on 表名(字段名);
-- 删除索引
drop index 索引名 on 表名;
-- 查看表索引
show keys from 表名;
-- Non_unique
-- 返回1表示索引值不唯一
-- 返回0表示索引是唯一的
-- create index id on t1(id);
-- create unique index id on t1(id);
-- drop index id on t1;
-- create index age on t1(age);
-- desc t1;
-- 查看表索引
show keys from t1;
(二)视图
视图:视图是一个虚拟表。其内容由查询结果定义。
视图的结构与真实的表是一样的,视图最好只做查询操作。
视图可以简化高频、复杂查询操作;提高数据的安全性
1、视图语法
-- 创建视图
create view 视图名称 as select 查询语句;
-- 修改视图
-- 原表数据进行修改 , 视图中的数据也会发生改变
alter view 视图名称 as select 查询语句;
-- 删除视图
drop view 视图名称;
drop view if exists 视图名称;
-- 查看数据库所有的视图
show full tables in 数据库名 where table_type like 'VIEW';
-- create view old as select * from t1 where age>20;
-- create view young as select * from t1 where age<20;
-- select * from old;
-- update t1 set age=25 where name='阿宸';
-- update old set age=24 where name='阿宸';
-- select * from t1;
-- select * from old;
-- drop view young;
-- 查看数据库所有的视图
-- show full tables in 数据库名 where table_type like 'VIEW';
show full tables in class7 where table_type like 'VIEW';
(三)函数和存储过程
- 函数以及存储过程是
- 事先经过编译并存储在数据库中的一段sql语句的集合,
- 调用存储过程或者函数可以简化代码,提高数据处理效率。
- 函数有且只有一个返回值,并且要的是一个结果;
- 存储过程不能有返回值要的是执行过程;
1、函数的创建
delimiter 符号 -- 自定义语句结束符号
create function 函数名(形参) returns 返回类型
begin
函数体
return 返回值
end
delimiter ;
-- 调用函数
select 函数名();
-- 变量
set @变量名=值
select @变量名
set @name='阿宸';
select @name;
-- 在函数内创建变量
declare 变量名 数据类型
set 变量名=值
delimiter $$ -- 自定义语句结束符号
create function ac() returns int
begin
declare age int(3);
set age=(select age from t1 where name='阿宸');
return age;
end $$
delimiter ;
select ac();
在MySQL8会创建函数会出现的创建不成功的问题解决
这是因为有一个安全参数没有开启,log_bin_trust_function_creators 默认为0,是不允许function的同步的,开启这个参数,就可以创建成功了。
查看是否开启
show variables like '%func%';
为on则是开启了
找到安装路径
在programdata--mysql--mysql sever
在my.ini中的[mysqld]中lower_case_table_names=1
后面增加一条
log_bin_trust_function_creators=1
2、存储过程
存储过程可以实现比较复杂的业务逻辑
delimiter 符号 -- 自定义语句结束符号
create procedure 存储过程名称(参数)
begin
存储过程
end 符号
delimiter ;
-- 调用存储过程
call 存储过程名称();
delimiter 符号 -- 自定义语句结束符号
create procedure 存储过程名称([in/out] 参数名 数据类型)
begin
存储过程
end 符号
delimiter ;
-- 调用存储过程
call 存储过程名称(参数);
in , 可以接收常量或者是变量
out:只能接收变量
-- delimiter $$
--
-- create procedure ss()
-- begin
-- select * from t1 where age>20;
-- select name from t1 where age>20;
-- end $$
--
-- delimiter ;
-- call ss();
-- delimiter $$
--
-- create procedure s1(in num int)
-- begin
-- select * from t1 where age>num;
-- end $$
--
-- delimiter ;
call s1(19);
set @n=22;
call s1(@n);
(四)事务、存储引擎
1、事务
MySQL事务主要是用于处理操作
数量比较大 ,
复杂度比较高的数据;
多个数据必须同时操作成功,如果有一条操作不成功则则所有数据都不会发生变化,
这时数据库操作语句就构成一个事务。事务主要是处理是保护局增删改操作;
-- 开启事务
begin;
-- 结束事务
commit;
-- 数据回滚,回滚带上一条操作语句
rollback;
begin;
insert into students values
(10,2202,'刘永华','男');
delete from students where id=7;
rollback;
-- 查看事务隔离级别
select @@transaction_isolation;
事务的四大特性:原子性、一致性、隔离性、持久性
MySQL是属于可重复度的隔离界别
2、存储引擎
MySQL是如何存储数据的
-- 查看存储引擎
show engines;
InnoDB -- 默认的存储引擎,比较平衡的读写的效率都是可以的
MyISAM -- 注重查询 , 表级锁;对于写的效率不好
(五)触发器
在数据中设置一段静态代码 ,这个代码并不会自己执行 , 是当某个操作触发到这个设置的条件是,才会执行.
触发器像一个比较特殊的存储过程;不需要手动执行sql语句 ,自动触发sql语句
delimiter $$
create trigger 触发器名称 触发时间 触发条件 on 表名 for each row
begin
触发事件
end $$
delimiter ;
-- 触发时间(有两个):before 在触发条件之前;after 在触发条件之后
-- 触发条件:insert、update、delete
-- new 新数据 insert 、update
-- old 旧数据 update、delete
-- 增加学生信息 , 对应班级的人数自动增加
delimiter $$
create trigger tri after insert on students for each row
begin
declare num int;
-- 获得到学生对应班级的人数
set num=(select count_stu from class where class_id=new.class_id);
-- 对班级人数+1
update class set count_stu = num+1 where class_id=new.class_id;
end $$
delimiter ;
insert into students values (7,2202,'马晨旺','男');
-- 一下代码触发两次
insert into students values
(7,2202,'李金林','男'),
(7,2203,'朱晓际','男');
-- 修改学生班级 , 对应班级人数的触发操作
delimiter $$
create trigger tri_update after update on students for each row
begin
declare num_old int;
declare num_new int;
-- 获得到两个班级的人数
set num_old=(select count_stu from class where class_id=old.class_id);
set num_new=(select count_stu from class where class_id=new.class_id);
-- 对班级人数+1/-1
update class set count_stu = num_old-1 where class_id=old.class_id;
update class set count_stu = num_new+1 where class_id=new.class_id;
end $$
delimiter ;
update students set class_id=2203 where id=7;
(六)pymysql
pymysql就是python的第三方库,用来连接mysql的
使用python来操作数据库pip install pymysql
import pymysql
'''
1、建立数据库连接
db = pymysql.connect(
host : 连接MySQL主机的,本机连接直接写‘localhost’ , 本地ip:127.0.0.1
user : 连接用户名
password : 数据库密码
charset : 使用utf8
database : 数据库名称
port : mysql端口 默认都是3306(在本机连接MySQL可以不用端口)
)
'''
db = pymysql.connect(
host="localhost",
user = 'root',
password='root',
charset='utf8',
database='class7'
)
# 2、创建游标对象
cursor = db.cursor()
# sql = 'show tables'
# # 把sql语句交给游标方法
# cursor.execute(sql)
# 获取数据
# 返回的是一个元组 返回所有数据表格
# all = cursor.fetchall()
# print(all)
# 返回多条数据,参数不写默认为1
# many = cursor.fetchmany(2)
# print(many)
# # 返回一条数据
# one = cursor.fetchone()
# print(one)
# 创建数据表
table_name = 'user'
# sql = 'create table %s (id int(4) not null , name varchar(5))'%(table_name)
# cursor.execute(sql)
# 查看表结构
# sql = 'desc %s'%(table_name)
# cursor.execute(sql)
# print('表结构为:',cursor.fetchall())
# 插入数据
# 增加数字类型需要在insert后面加上ignore
# sql = "insert ignore into user values('1' ,'阿宸');"
# cursor.execute(sql)
# sql = "insert ignore into user values(%s ,%s);"
# # 每一条数据保存为元组类型 , 最后将多个元组放在一个列表中
# value = [
# ('2','张三'),
# ('3','李四'),
# ('4','王五'),
# ('5','赵六'),
# ('6','老七'),
# ('7','马大哈')
# ]
# # 提交多条数据时要使用executemany()
# cursor.executemany(sql , value)
# 在python中操作数据库对数据进行增删改操作时 , 必须对操作事务进行提交
# db.commit()
# 数据修改
# sql = "update user set name='二哈' where id='7'"
# cursor.execute(sql)
# db.commit()
# 数据删除
# sql = "delete from user where name='阿宸'"
# cursor.execute(sql)
# db.commit()
# sql = "select * from user"
# cursor.execute(sql)
# print(cursor.fetchall())
# 获得多条数据
# print(cursor.fetchmany(4))
# 单条数据
# print(cursor.fetchone())
sql = 'select * from user where name="二哈"'
cursor.execute(sql)
print(cursor.fetchone())
# sql = 'select * from %s'%(table_name)
# cursor.execute(sql)
# print(cursor.fetchall())
# 关闭游标关闭
cursor.close()
# 关闭数据库连接
db.close()