Mysql数据库
Qcrale Mysql
-
SQL(结构化语言)
-
定义了所有数据库的规则
-
操作所有的关系数据库
-
通用语法
三种注释
- 单行注释 -- 注释内容或者(#注释内容)
- 多行注释 /* 注释 */
-
-
Sql分类
-
DDL操作数据库、表
-
操作数据库(CRUD)
- 1. C(create)创建 - create database 数据库名称; -- 创建数据库 - create database if not exists 数据库名称 character set utf-8;-- 创建数据库,并判断存在,设置字符集 2. R(Retrieve):查询 - show databases; -- 查询数据库 - show create database 数据库名称; -- 查询数据库创建语句 3. U(update):修改 - alter database 数据库名 character set 字符集名称;-- 修改数据库字符集 4. D(Delete):删除 - drop database 数据库名称;-- 删除数据库(危险) - drop database if exists 数据库名称; -- 比较安全 5. 使用数据库 - select database();-- 查询当前使用的数据库 - use database 数据库名称;-- 使用数据库 - 操作表 1. C(create)创建 - 创建表 create table 表名( 列名1 数据类型, ... 列名i 数据类型 );-- 注意最后一列不需要加 , 日期数据类型 data;年月日 datetime;日期年月日时分秒 timestamp;时间错类型,自动给你当前系统的日期,年月日时分秒 - create table 表名 like 被复制的表名;-- 复制表 1. R(Retrieve):查询 - show tables;-- 查询某个数据库中所有的表名称 - desc 表名;(describe 表名) -- 查询表结构 2. U(update):修改 - alter table 表名 rename to 新的表名;-- 修改的表名 - alter table 表名 character set 字符集名称;-- 修改的表的字符集 - alter table 表名 add 列名 数据类型;-- 添加一列 - alter table 表名 change 列名 新列名 新数据类型;-- 修改列名称,类型 alter table 表名 modify 列名 新数据类型 - 删除一列 alter table 表名 drop 列名; 3. D(Delete):删除 - drop table 表名;-- 删除表 - drop table if exists 表名;--比较安全 4. 使用数据表
客户端图形化工具
-
-
DML:增删改查表中数据
- 添加数据 - 语法: insert into 表名(列名1,列名2,列名3,列名4,列名n) values(值1,值2,值3,值4,值n); 这个比较好,以后查询开发人员看得懂 - 列名和值要一一对应 - 如果表名后,不定义列名,则默认给所有的列添加值 insert into 表名 values(值1,值2,值3...值n); - 除了数字类型,其它的都要加单引号 ‘ ’ - 删除数据 - delete from 表名[where 条件]; 不加条件会删除表的所有记录 delete from 表名; -- 不推荐使用,有多少条记录会执行多少次 - TRUNCATE TABLE 表名;-- 推荐使用,效率高,先删除表,在创建一张一样的表 - 修改数据 - update 表名 set 列名1 = 值1, 列名2 = 值2, 列名3 = 值3 [where 条件]; 不加条件会修改表的所有记录不
-
DQL:查询表中的数据
* select * from 表名; * 语法 select 字段列表 from 表名列表 where 条件列表 group by 分组字段 having 分组之后的条件 order by 排序 limit 分页限定 2. 基础查询 1. 多个字段 select 字段名1,... from 表名; * 注意: * 查询所有字段用*代替字段列表 2. 去除重复 * distinct * select distint 字段 from 表名; 3. 计算列 * 一般可以用四则运算计算一些列值 * ifnull(表达式1,表达式2): * 表达式1,:哪个字段需要判断是否为null * 如果该字段为null后的替代值 * select name,math,english,math + ifnull(english,0) from 表名; 4. 起别名 * as:as也可以省略 * * select name,math,english,math + ifnull(english,0) as allcorse from 表名; 3. 条件查询 1. where字句后跟条件 2. 运算符 > < <= >= = (<> == ! 不等于) select * from student where age >= 20; DETWEEN...AND select * from student where age between 20 and 30;-- 大于20小于等于 like: 模糊查询 * 占位符 * _:当个任意字符 * %:多个任意字符 select * from student where name like '马%';-- 查询姓马的学生 select * from student where name like '_化%';-- 第二个字是化的人 select * from student where name like '___';-- 姓名是三个字的人 select * from student where name like '%马%';-- 姓名中有马的人 IS BULL select * from student where english = NULL;-- 错误,null值不可以使用 select * from student where english is null;-- 英语成绩为null and && select * from student where age >= 20 and age <=30; select * from student where age between 20 and 30;-- 大于20小于等于30 or || select * from student where age = 20 or age = 10 or age = 25; select * from student where age in (20,10,25); not ! 4. 查询语句的使用 1. 排序查询 * 语法: order by 字句 * order by 排序字段1 排序方式1,排序字段2 排序方式2..; * 有先后顺序 * 排序方式: * ASC:升序 * DESC:降序 selcet * from student order by math desc;-- 数学成绩 selcet * from student order by math asc, english asc;-- 数学成绩一样的话,就按英语成绩排名 2. 聚合函数 将一列数据作为一个整体,进行纵向的计算 1. count:计算个数 select count(name) from student; select count(ifnull(english,0)) from student; 1. 一般选择非空的列:主键 2. COUNT(*) 不推荐 2. max:是计算最大值 select max(math) from student; 3. min:计算最小值 select min(math) from student; 4. sum: 求和 select sum(math) from student; 5. avg: 求平均值 select avg(math) from student; * 注意:聚合函数计算会排除非空null的值 * 解决方案: 1. 选择不包含非空的进行计算 2. IFNULL函数 3. 分组查询 1. 语法:group by 分组字段; select from student group by sex;-- 性别分组 2. 注意: 1. 分组之后查询的字段:分组字段,聚合函数 2. where和having的区别 1. where在分组之前进行限定,如果不满足就不参与分组 having在分组之后进行限定,如果不满足,则不会被查询出来 2. where后不可以跟聚合函数,having可以进行聚合函数的判断 select sex, avg(math), count(id) from student group by sex;-- 男女平均分人数成绩 select sex, avg(math), count(id) from student where math > 70 group by sex;-- 男女平均分人数成绩,分数低于70不计 select sex, avg(math), count(id) from student where math > 70 group by sex having count(id) > 2;-- 男女平均分人数成绩,分数低于70不计,人数大于2 select sex, avg(math), count(id) 人数 from student where math > 70 group by sex having 人数 > 2 4. 分页查询 1. 语法:limit 开始的索引,每页查询条数 select * from student limit 0,3;-- 每页现实三条记录 第一页 select * from student limit 3,3;-- 每页现实三条记录 第二页 select * from student limit 6,3;-- 每页现实三条记录 第三页 2. 公式:开始的索引 = ( 当前页码 -1 )* 每页显示的条数 3. limit是Mysql的方言 5. 约束 * 概念:对表中的数据进行限定,保证数据的正确性、有限性、完整性。 * 分类: 1. 主键约束:primary key 1. 注意 1. 含义:非空且唯一 2. 一张表只有一个字段为主键 3. 主键就是表中记录的唯一标识 2. 创建表添加主键约束 id int primary key 3. 删除主键 alter table stu modify id int;---错误 alter table stu drop primary key;--- 正确 4. 创建完之后再添加主键 alter table stu modify id int primary key; 5. 自动增长 * 概念:如果是数值类型,使用auto_increment 可以完成自动增长 1. 语句: id int primary key auto_increment; 2. 删除 alter table stu modify id int; 3. 添加 alter table stu modify id int auto_increment; 2. 非空约束:not null 1. 创建表时,添加非空约束 name varchar(20) not null; alter table stu modify name varchar(20);-- 删除name的非空约束 2. 创建表完成后再添加 alter table stu modify name varchar(20) not null;-- 添加非空约束 3. 唯一约束:unique 某一列的值不能重复添加 1. 创建表时添加唯一约束 number varchar(20) unique; * 删除唯一约束 -- 错误 alter table stu modify number varchar(20);-- 删除唯一约束 alter table stu drop index number;-- 删除唯一约束,正确 2. 创建表完成后再添加 alter table stu modify number varchar(20) unique;-- 添加唯一约束 3. 注意: * 唯一约束可以有null,但是只有一个记录为null 4. 外键约束:foreign key 防止数据出错 让表与表之间产生关系,并保证数据正确性 1. 在创建表时添加外键 语法:外键列constraint 外键名称 foreign key (外键列名称) references 主表名称(主表列名称) 2. 删除外键 alter table employee drop foreign key em_fk; 3. 添加外键 alter table 表名 add constraint 外键名称 foreign key (外键列名称) references 主表名称(列名称); 4. 级联操作 * 先设置employee的部门id为null再改department表的部门id,在修改employee的部门id * 最好的操作激素hi,需要添加外键的时候,设置级联更新 * 级联更新和级联删除 alter table 表名 add constraint 外键名称 foreign key (外键列名称) references 主表名称(列名称) on update cascade on delete cascade; * 用的非常谨慎
数据库设计
-
多表之间的关系
1.分类:
1. 一对一
* 如: 人和身份证的关系
* 分析 一个人只有一个身份证 ,一个身份证只能对应一个人
2. 一对多
* 如 部门和员工
* 分析:一个部门有多个员工,一个员工只能对应一个部门
3. 多对多
* 如: 课程和学生
* 分析 一个学生可以选择多个课程,一个课程有很多个学生由选择2.实现
1.一对多(多对一)
* 如:部门和员工
* 实现方式:在多的一方建立外键,指向一的一方的主键
2. 多对多 * 如: 课程和学生
* 实现方式:多对多的关系实现需要借助第三张表。中间表至少包含两个字段,这两个字段作为第三张表的外键,分别指向两张表的主键
3. 一对一
- 如:学生和身份证的关系
- 实现方式:一对一关系的实现,可以在任意一方添加唯一外键指向另一方的主键。
- 案例:
- 如:学生和身份证的关系
-
数据库设计的范式
-
概念:设计数据库时,需要遵循的一些规范 要遵循后边的范式,必须要遵循前边的所有范式要求
*设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。
目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。 -
分类:
- 第一范式(1NF):数据库表的每一列都是不可分割的原子数据项
- 第二范式(1NF)在1NF的基础上,非码属性必须完全依赖于主码(在1NF基础上消除非主属性对主码的部分函数依赖)
- 几个概念:
-
函数依赖;A--->B,如果通过A属性(属性组)的值,可以确定唯一B属性的值。则称B依赖于A 例如:学号-->姓名。 (学号,课程名称)--->分数
-
完全函数依赖,A--->B 如果A是一个属性组,则B属性值的确定需要依赖于A属性组中所有的属性值。 例如:(学号,课程名称)--->分数
-
部分函数依赖 A--->B 如果A是一个属性组,则B属性值的确定只需要A属性组某些值即可。例如:(学号,课程名称)--->姓名
-
传递函数依赖:A---->B ,B---->C,如果通过A属性(属性组)的值,可以确定唯一B属性的值,在通过B属性(属性组)的值可以确定唯一C属性的值,则称C传递函数依赖于A
例如:学号--->系名 ,系名---->系主任
-
码:如果一张表,一个属性或属性组,被其他所有的属性所完全依赖,则称这个属性(属性组)为该表的码
例如:该表中码为:(学号,课程名称)
- 主属性 码属性组中的所有属性
- 非主属性 除了码属性组的属性
-
- 第三范式 (3NF) 在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)
数据库的备份和还原
- 命令行:
- 语法: mysqldump -u用户名 -p密码 数据库名称 >保存地址路径
- 还原:
-
- 登录数据库
- 创建数据库
- 使用数据库
- 执行文件。sourse文件路径
-
- 图形化工具:
多表查询
* 查询的语法 select 数据 from 表 where... * 笛卡尔积: * 有两个集合A,B,取得这两个集合的所有组成情况。 * 要完成多表查询,需要消除无用的数据 * 多表查询的分类 1. 内连接查询: 1. 隐式内连接:使用where条件消去数据 select * from 表1,表2 where 表1.id = 表2.id; select t1.name, t1.gender, t2.name from emp t1, dept t2 where t1.id = t2.id; 2. 显式内连接 * 语法:select 字段列表 from 表名1 [inner] join 表名2 on 条件; * 例如: select * from 表1 inner join 表2 on 表1.id = 表2.id; select * from 表1 join 表2 on 表1.id = 表2.id; 3. 内连接查询: 1. 从哪些表查询数据 2. 查询条件是什么 3. 查询哪些字段 2. 外链接查询: 1. 左外连接 * 语法:select 字段列表 from 表1 left [outer] join 表2 on 条件; * 查询的是左表所有数据以及交集的部分。 * 例如:-- 查询所有员工信息,如果员工有部门,则查询部门名称,没有部门,则不显示部门名称 select t1.*, t1.name from emp t1, left join dept t2 on t1.id = t2.id; 2. 右外连接 * 语法:select 字段列表 from 表1 right [outer] join 表2 on 条件; * 查询的是右表所有数据以及交集的部分。 3. 子查询: * 概念:查询中嵌套查询,称嵌套 --查询工资最高的员工 1. 查询最高的工资多少 2. 查询工资为9000的员工信息 一条语句 * select * from emp where emp.salary = (Select MAX(salary) from emp); * 子查询不同情况 1. 子查询的结果是单行单列的 * 子查询可以作为条件,使用运算符去 -- 查询员工小于平均工资的人的信息 select * from emp where emp.salary = (Select MAX(salary) from emp); 2. 子查询的结果是单列单行的 子查询可以作为条件 使用运算符 in -- 查询财务部和市场部所有的员工信息 Select id from dept where name = '财务部' or name='财务部'; select * from emp where dept id = 1 or id = 3; 子查询 select * from emp where dept in(Select id from dept where name = '财务部' or name='财务部'); 3. 子查询的结果是多行多列的 * 子查询可以作为一张虚拟表参与查询。 * 查询员工的入职日期是20011-11-11之后的员工信息和部门信息 select * from dept t1,(Select * from emp where emp.'join_data' > '2011-11-11') t2 where t1.id = t2.dept_id; 普通内连接 select * from emp t1,dept t2 where t1.id = t2.id and t1.join_date >2019-11-11;
多表查询练习
事务
-
事务基本介绍
1.概念:
* 如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败。
-
start transaction;
commit;
roolback;
- 操作
- 开启事务:start transaction
- 回滚:rollback
- 提交:commit
- Mysql数据库中事务默认自动提交
- 事务提交的两种方式:
- 自动提交:
- mysql就是自动提交的
- 一条DML(增删改)语句会自动提交一次事务。
- 手动提交:
- Oracle 默认是手动提交事务的
- 需要先开启事务,再提交
- 自动提交:
- 修改事务的默认提交方式
- 查看事务的默认提交方式:select @@autocommit;---1 代表自动提交 0 代表手动提交
- 修改默认提交方式 set @@autocommit = 0;
- 事务提交的两种方式:
-
-
事物的四大特征
- 原子性:是不可分割的最小操作单位,要么同时成功,同时失败。
- 持久性:当事务提交或回滚之后,数据库会持久化的保存数据。
- 隔离性:多个事务之间,相互独立。
- 一致性:事务操作前后,数据总量不变
-
事物的隔离级别(了解)
-
概念:多个事务之间,相互独立的。但是如果多个事物操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题了。
-
存在的问题:
- 脏读:一个事务,读取到另一个事务中没有提交的数据
- 不可重复读(虚读):在同一个事务中,两次读取到的数据不一样。
- 幻读:一个事务操作(DML)数据表中所有的记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改
-
隔离级别:
- read uncommitted:读未提交
- 产生的问题:脏读、不可重复读、幻读
- read committed:读已提交(Oracle)
- 产生的问题:不可重复读、幻读
- repeatable read:可重复读(Mysql默认)
- 产生的问题:幻读
- serializable :串行化
- 可以解决所有的问题
- 注意:隔离级别从小到大安全性越来越高,但是效率越低
- 数据库查询隔离级别:select @@tx_isolation;
- 数据库设置隔离级别:set global transaction isolation level 级别字符串
- read uncommitted:读未提交
-
演示
-
-
set global transaction isolation level read uncommitted;
start transaction;
--转账操作
update account set balance = balance -500 where id =1;
-
-
-
-
-
DCL
-
SQL分类:
- DDL:操作数据库和表
- DML:操作增删改表数据
- DQL:查询表数据
- DCL:管理用户,授权
-
DBA:数据库管理员
-
DCL:管理用户,授权
-
管理用户
-
添加用户
-
创建用户
create user '用户名@主机名' identified by '密码'
create user 'gopan@%' identified by '123456'
-
-
删除用户
drop user '用户名@主机名'
-
修改用户密码:
update user set password('新密码') where user = '用户名'set password for '用户名@主机名' = password('新密码')
- 在mysl数据库中,忘了root的密码?
- cmd --->net stop mysql停止MySQL服务,需要管理员的权限
- 启动mysql服务,使用无验证方式启动,mysqld --skip-grant-tables
- 打开新的cmd窗口,直接输入mysql命令,敲回车。既可以登陆成功
- use mysql
- update user set password = password('你的新密码') where user = 'root';
- 关闭两个窗口
- 打开任务管理器,手动结束mysql.exe的进程
- 启动mysql服务
- 使用新密码登录
- 在mysl数据库中,忘了root的密码?
-
查询用户
-
切换到mysql数据库
use mysql;
-
查询user表
select * from user;
-
-
-
授权
-
查看权限:
- show grants for '用户名@主机名'
-
授予权限:
- grant 权限列表 on 数据库.表名 to ‘用户名@主机名’;
- grant select on db.name to ‘lisi'@'%’;
- 全部权限
- grant all on '.' to ‘zhangsan'@'localhost’;
-
撤销权限:
revoke 权限列表 on 数据库.表名 from ‘lisi’@'localhost'
-
-
-
-