一:mysql安装
1.打开下载的 mysql 安装文件双击解压缩,运行“mysql-5.5.40-win32.msi”。
2.选择安装类型,有“Typical(默认)”、“Complete(完全)”、“Custom(用户自定义)”三个选项,选择“Custom”,
3.点选“Browse”,手动指定安装目录。
4.填上安装目录,我的是“d:\Program Files (x86)\MySQL\MySQL Server 5.0”,按“OK”继续。
5.确认一下先前的设置,如果有误,按“Back”返回重做。按“Install”开始安装。
6.正在安装中,请稍候,直到出现下面的界面, 则完成 MYSQL 的安装
7.安装完成了,出现如下界面将进入 mysql 配置向导
8.选择配置方式,“Detailed Configuration(手动精确配置)”、“Standard Configuration(标准配置)”,我
10.选择mysql数据库的大致用途,“Multifunctional Database(通用多功能型,好)”、“Transactional
11.选择网站并发连接数,同时连接的数目,“Decision Support(DSS)/OLAP(20个左右)”、“Online Transaction
12. 是否启用 TCP/IP 连接,设定端口,如果不启用,就只能在自己的机器上访问 mysql 数据库了,在这个页 面上,您还可以选择“启用标准 模式”(Enable Strict Mode),这样 MySQL 就不会允许细小的语法错误。 如果是新手,建议您取消标准模式以减少麻烦。但熟悉 MySQL 以后,尽量使用标准模式,因为它可以降 低有害数据进入数据库的可能性。按“Next”继续。
13. 就是对 mysql 默认数据库语言编码进行设置(重要),一般选 UTF-8,按 “Next”继续。
14.选择是否将 mysql 安装为 windows 服务,还可以指定 Service Name(服务标识名称),是否将 mysql 的 bin 目录加入到 Windows PATH(加入后,就可以直接使用 bin 下的文件,而不用指出目录名,比如连接, “mysql.exe -uusername -ppassword;”就可以了,不用指出 mysql.exe 的完整地址,很方便),我这里全部 打上了勾,Service Name 不变。按“Next”继续。
15. 询问是否要修改默认 root 用户(超级管理)的密码。“Enable root access from remote machines(是否允 许 root 用户在其它的机器上登 陆,如果要安全,就不要勾上,如果要方便,就勾上它)”。最后“Create An Anonymous Account(新建一个匿名用户,匿名用户可以连 接数据库,不能操作数据,包括查询)”,一般就不用勾了,设置完毕,按“Next”继续。
16.确认设置无误,按“Execute”使设置生效,即完成 MYSQL 的安装和配置
注意:设置完毕,按“Finish”后有一个比较常见的错误,就是不能“Start service”,一般出现在以前有安装 mysql
二: Mysql卸载
1.停止 window 的 MySQL 服务。 找到“控制面板”-> “管理工具”-> “服务”,停止 MySQL 后台服务。
2.卸载 MySQL 安装程序。找到“控制面板”-> "程序和功能",卸载 MySQL 程序。
3.删除 MySQL 安装目录下的所有文件。
4.删除 c 盘 ProgramDate 目录中关于 MySQL 的目录。路径为:C:\ProgramData\MySQL(是隐藏文件,需要显示
三:配置
1.Mysql服务启动:
1)手动;
2)cmd-->service.msc 打开服务窗口;
3)使用管理员身份打开CMD:
net start mysql:启动mysql的服务;
net stop mysql: 关闭mysql服务;
2.Mysql登录
1.mysql -uroot -p密码;
2.mysql -hip -uroot -p连接密码;
3.Mysql退出
1.exit;
2.quit;
4.Mysql目录结构
1.Mysql安装目录:D:\SoftTools\MySQL
配置文件:my.ini;
2.Mysql数据目录:datadir="C:\ProgramData\MySQL\MySQL Server 5.5\data"
数据库:文件夹;
表:文件;
数据:数据。
四: sql
1.什么是sql?
Structured Query Languag: 结构化查询语言。其实就是定义了操作所有关系型数据库的规则。每一种数据库操作的方式都不一 样。
2.SQL语法:
1)SQL语句可以单行或多行书写,以分号结尾;
2)可使用空格和缩进来增强语句的可读性;
3)Mysql 数据库的sql语句不区分大小写;
4)注释:
a)单行注释:--(空格)注释内容 或者 # 注释内容
b)多行注释: /*注释内容 */
3.SQL分类:
1) DDL:用来定义数据库对象:数据库、表、列等。关键字:create, drop, alter等。
2) DML:用来对数据库中表的数据进行增删改。关键字:insert, delete, update等;
3) DQL: 数据库查询语言,用来查询数据库中表的记录。关键字:select,where等;
4) DCL: 数据库控制语言。
4.DDL:操作数据库、表
1).操作数据库(CRUD):
a)C(Create):创建:
--创建数据库:
--语法:create database 数据库名称:
create database db2;
--创建数据库,判断不存在,如果不存在再创建;
--语法:create database if not exists 数据库名称;
create database if not exists db2;
--创建db4数据库,判断是否存在,并指定字符集为gbk;
create database if not exists db4 character set gbk;
b) R(Retrieve): 查询:
--查询所有数据库名称
show databases;
--查询某个数据库的查询语句
show create database mysql;
c) U(Update): 修改:
--修改数据库的字符集
alter databases 数据库名称 character set 字符集名称;
d) D(delete): 删除:
--删除数据库
drop database 数据库名称;
--判断数据库是否存在
drop database if exists db2;
e) 使用数据库:
--查询当前正在使用的数据库名称;
select database();
--使用数据库
--语法:use 数据库名称;
use mysql;
2)操作表:
a)C(Create):创建:
--创建某张表
--语法:create table 表名(
列名 数据类型1,
列名 数据类型2,
...
列名 数据类型n
);
--注意:最后一列,不需要加逗号(,)
--数据库类型:
1.int:整数类型;
age int,
2.double:小数类型;
score double(5,2),
3.date:日期,只包含年月日,yyyy-MM-dd HH:mm:ss
4.datetime:日期,包含年月日时分秒 yyyy-MM-dd HH:mm:ss
5.timestamp:时间戳类型,包含年月日时分秒 yyyy-MM-dd HH:mm:ss
如果将来不给这个字段赋值,或赋值为null,则默认使用当前的系统时间,来自动赋值。
6.varchar:字符串
name varchar(20);姓名最大字符;
create table 't_stu'(
'id' int(11) NOT NULL AUTO_INCREMENT,
'name' varchar(50) DEFAULT NULL COMMENT '学生姓名',
'age' int(5) DEFAULT NULL COMMENT '学生年龄',
'score' double(4,1) DEFAULT NULL COMMENT '学分',
'birthday' date DEFAULT NULL COMMENT '出生日期'
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='学生信息管理';
--复制表
create table 表名 like 被复制的基表;
b) R(Retrieve): 查询:
--查询某个数据中所有表的名称
show tables;
--查询表结构
--语法:desc 表名;
desc test;
c) U(Update): 修改:
--1.修改表名
--语法:alter table 表名 rename to 新的表名;
alter table t_stu rename to t_student;
--2.修改表的字符集
--语法:alter table 表名 character set 字符集名称;
alter table t_student character set gbk;
--3.添加一列
--语法:alter table 表名 add 列名 数据类型;
alter table t_student add gender int(11) default null comment '学生性别';
--4.修改列名称
--语法:alter table t_student change 列名 新列名 新数据类型;
alter table t_student change sex varchar(10);
--语法:alter table t_student modify 列名 新数据类型;
alter table t_student modify sex varchar(10);
--5.删除列:
--语法:alter table 表名 drop 列名;
alter table t_student drop sex;
d) D(delete): 删除:
--删除数据表
--drop table 表名;
drop table student;
--drop table if exists 表名;
drop table if exists student;
5.DQL:增删改表中数据
1)添加数据:
--语法:insert into 表名(列名1,列名2,...列名n) values(值1,值2,...值n);
insert into t_student (id,name,age,score) value(1,"张三",19,85);
--注意: 1.列名和值要一一对应。
2.如果表名后,不定义列名,则默认给所有列添加值
insert into 表名 values(值1,值2,...,值n);
3.除了数字类型,其他类型需要使用引号(单双都可以)引起来。
2)删除数据
--删除数据
delete from t_student where id=2;
--删除表,然后创建一个一模一样的空表
Truncate table t_student;
--注意:1.如果不添加条件,则删除表中所有记录。
2.如果要删除所有记录
方式一:delete from 表名;--不推荐使用,有多少条记录就会执行多少次删除操作;
方式二:truncate table 表名;--推荐使用,效率更高,先删除表,然后再创建一张一模一样的表;
3)修改数据;
--语法:update 表名 set 列名1=值1,列名2=值2,.....[where条件];
UPDATE t_student SET age=20, score=100 WHERE id=2;
--注意:
1.如果不加任何条件,则会将表中所有记录全部修改。
6.DQL:查询表中的记录
--语法:
select 字段列表 from 表列表 where 条件列表 group by 分组字段 having 分组之后的条件 order by 排序 limit 分页限定
--基础查询:
--1.多个字段查询
--语法:select 字段名1,字段名2,.... from 表名;
--注意:如果查询所有字段,则可以使用‘*’来替代字段列表,但是不推荐使用,执行效率低,可读性差;
SELECT NAME,age FROM t_stu;
--2.去除重复
--语法:select distinct 字段名1,字段名2,.... from 表名;
SELECT DISTINCT address FROM t_stu;
--3.计算列
--一般可以使用四则运算来计算一些列的值。(一般只会进行数值性的计算)
--Ifnull(表达式1,表达式2):
--表达式1:那个字段需要判断是否为null;
--表达式2:该字段为null后的替换值。
SELECT NAME,math,english,math+ IFNULL(english,0) FROM t_stu;
--4.起别名:
--AS:as也可以省略;
SELECT NAME AS '姓名',math AS '数学',english AS '英语', math+ IFNULL(english,0) AS '总分'FROM t_stu;
--条件查询:
1.where字句后跟条件;
2.运算符
/*
>、<、<=、>=、=、<>
between...and
in(list集合)
like:模糊查询
_:表示单个任意字符;
%:表示多个任意字符;
is null
and 或 &&
or 或 ||
not 或 !
*/
-- 运算符
-- 查询年龄的大于20岁
SELECT * FROM t_stu WHERE age>20;
-- 查询年龄大于等于20岁
SELECT * FROM t_stu WHERE age>=20;
-- 查询年龄不等于20岁
SELECT * FROM t_stu WHERE age!=20;
SELECT * FROM t_stu WHERE age<>20;
-- 查询大于等于20小于等关于30
SELECT * FROM t_stu WHERE age>=20 && age<=30;
SELECT * FROM t_stu WHERE age>=20 AND age<=30;
SELECT * FROM t_stu WHERE age BETWEEN 20 AND 30;
-- 查询22岁,19岁,25岁的信息
SELECT * FROM t_stu WHERE age=22 OR age=19 OR age=25;
SELECT * FROM t_stu WHERE age IN(22,19,25);
-- 查询英语缺考的学生
-- null值不能使用=或者!=判断;
SELECT * FROM t_stu where english =null;
select * from t_stu where english is null;
-- 查询英语成绩不为null的学生
select * from t_stu where english is not null;
-- 查询姓马的有哪些人?
SELECT * FROM t_stu WHERE NAME LIKE '马%';
-- 查询第二个字是化的人
SELECT * FROM t_stu WHERE NAME LIKE '_化%';
-- 查询姓名是两个字的人
SELECT * FROM t_stu WHERE NAME LIKE '__';
-- 查询姓名中包含德的值
SELECT * FROM t_stu WHERE NAME LIKE '%德%';
-- 排序查询
-- 语法:order by 字句
order by 排序字段1 排序方式1, 排序字段2 排序方式2,....
-- 排序方式:
ASC:升序,默认的。
DESC:降序;
-- 注意:如果有多个排序条件,则当前边的条件值一样时,才会判断第二个条件;
-- 按照数学成绩排序
SELECT * FROM t_stu ORDER BY math DESC;
-- 按照数学成绩排名,如果数学成绩一样则按照英语成绩排名;
SELECT * FROM t_stu ORDER BY math ASC, english DESC;
-- 聚合函数:将一列数据作为一个整体,进行纵向的计算;
-- 常见函数:
count:计算个数;
1)一般我们选择非空的列:主键;
2)count(*):不建议使用
max: 计算最大值;
min: 计算最小值;
sum: 计算和;
avg: 计算平均值;
注意:聚合函数的计算,会排除null;
解决方案:1.选择不包含非空的列进行计算;
2.IFNULL函数;
-- 计算班级人数
SELECT COUNT(NAME) FROM t_stu;
SELECT COUNT(IFNULL(english,0)) '班级总人数' FROM t_stu;
SELECT COUNT(*) FROM t_stu;
SELECT * FROM t_stu;
-- 计算数学成绩的最大值;
SELECT MAX(math) FROM t_stu;
-- 计算数学成绩的最小值
SELECT MIN(math) FROM t_stu;
-- 计算数学成绩的总和;
SELECT SUM(math) FROM t_stu;
-- 计算数学成绩的平均分
SELECT AVG(math) FROM t_stu;
-- 分组查询
-- 语法:group by 列名;
-- 注意:1.分组之后查询的字段:分组字段、聚合函数
2.where和Having的区别:
1)位置不同:where在分组之前进行限定,如果不满足条件,则不参与分组;having在分组之后进行限定,如果不满足条件则不会被查询出来;
2)where后不可以跟聚合函数,having可以进行聚合函数的判断;
-- 按照性别分组,分别查询男女同学的平均分
SELECT sex,AVG(math),COUNT(id) FROM t_stu GROUP BY sex;
-- 按照性别分组。分别查询男、女同学的平均分,要求:分数低于70的人,不参与分组
SELECT sex,AVG(math),COUNT(id) FROM t_stu WHERE math>70 GROUP BY sex;
-- 按照性别分组。分别查询男、女同学的平均分,要求:分数低于70的人,不参与分组,分组之后,人数要求大于2人
SELECT sex,AVG(math),COUNT(id) '人数' FROM t_stu WHERE math>70 GROUP BY sex HAVING COUNT(id)>2;
SELECT sex,AVG(math),COUNT(id) mannum FROM t_stu WHERE math>70 GROUP BY sex HAVING mannum>2;
-- 分页查询
-- 语法: limit(开始索引,每页查询条数)
-- 公式,开始的索引=(当前页码-1)*每页条数;
-- 分也是mysql3特有的‘方言’;
-- 每页显示三条记录
SELECT * FROM t_stu LIMIT 0,3;-- 第一页
SELECT * FROM t_stu LIMIT 3,3;-- 第二页
SELECT * FROM t_stu LIMIT 6,3;-- 第三页
7.Mysql约束:
1)概念:对表中数据进行限定,保证数据的正确性、有效性和完整性。
2)分类:
a)主键约束:primary key;
b)非空约束:not null;
c)唯一约束: unique
d)外键约束:forgin
-- 非空约束:not null
-- 1.方式一:创建表时添加约束
CREATE TABLE student(
id INT(11),
NAME VARCHAR(32) NOT NULL
);
-- 2.方式二:创建表完,添加非空约束
ALTER TABLE student MODIFY NAME VARCHAR(32) NOT NULL;
-- 3.删除约束
ALTER TABLE student MODIFY NAME VARCHAR(32);
-- 唯一约束:unique,某一列的值不能重复
-- 1.方式一:在创建表时,添加条件唯一约束
CREATE TABLE stu(
id INT(11),
phone_num VARCHAR(50) UNIQUE
);
-- 注意:唯一约束可以为null值,但是只能有一列为null;
-- 2.方式二:在创建之后,添加条件唯一约束
ALTER TABLE stu MODIFY phone_num VARCHAR(20) UNIQUE;
-- 3.删除唯一约束
ALTER TABLE stu DROP INDEX phone_num;
-- 4.主键约束:primary key
-- 1.注意:
1)含义:非空唯一;
2)一张表只能有一个字段为主键;
3)主键就是表中记录的唯一标识;
-- 1.方式一:创建表时,添加主键约束;
CREATE TABLE stu(
id INT(11) PRIMARY KEY,
NAME VARCHAR(32) NOT NULL
);
-- 2.方式二:创建完表后,添加主键
ALTER TABLE stu MODIFY id INT PRIMARY KEY;
-- 3.删除主键
ALTER TABLE stu DROP PRIMARY KEY;
-- 外键约束:foreign key,让表与表产生关系,从而保证数据的正确性;
-- 1.语法:
create table 表名(
...
外键列
constraint 外键名称 foreign key (外键名称) references 主表名称(主表列名称)
);
-- 创建部门表(id,dep_name,dep_location)
-- 一方,主表
CREATE TABLE department(
id INT PRIMARY KEY AUTO_INCREMENT,
dep_name VARCHAR(20),
dep_location VARCHAR(20)
);
-- 创建员工表(id,name,age,dep_id)
-- 多方,从表
CREATE TABLE employee(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20),
age INT,
dep_id INT, -- db1employee外键对应主表的主键
CONSTRAINT emp_dept_fk FOREIGN KEY (dep_id) REFERENCES department(id)
);
-- 添加 2 个部门
INSERT INTO department VALUES(NULL, '研发部','广州'),(NULL, '销售部', '深圳');
SELECT * FROM department;
-- 添加员工,dep_id 表示员工所在的部门
INSERT INTO employee (NAME, age, dep_id) VALUES ('张三', 20, 1);
INSERT INTO employee (NAME, age, dep_id) VALUES ('李四', 21, 1);
INSERT INTO employee (NAME, age, dep_id) VALUES ('王五', 20, 1);
INSERT INTO employee (NAME, age, dep_id) VALUES ('老王', 20, 2);
INSERT INTO employee (NAME, age, dep_id) VALUES ('大王', 22, 2);
INSERT INTO employee (NAME, age, dep_id) VALUES ('小王', 18, 2);
-- 删除外键
-- 语法:ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;
ALTER TABLE employee DROP FOREIGN KEY emp_dept_fk;
-- 添加外键
-- 语法:ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段) REFERENCES 主表名称(主表列名称);
ALTER TABLE employee ADD CONSTRAINT emp_dept_fk FOREIGN KEY (dep_id) REFERENCES department(id);
-- 级联更新
-- 语法:
-- 添加级联操作:ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段) REFERENCES 主表名称(主表列名称)on update cascade;
-- 级联更新:on update cascade;
-- 级联删除:on delete cascade;
---级联更新
ALTER TABLE employee ADD CONSTRAINT emp_dept_fk FOREIGN KEY (dep_id) REFERENCES department (id) ON UPDATE CASCADE;
-- 级联删除
ALTER TABLE employee ADD CONSTRAINT emp_dept_fk FOREIGN KEY (dep_id) REFERENCES department (id) ON DELETE CASCADE;
8.数据库的设计
1)多表之间的关系:
a)分类:
一对一:例如:人和身份证; 分析:一个人只有一张身份证,一张身份证只能对应一个人;
一对多(多对一): 例如:部门和员工; 分析:一个部门有多个员工;
多对多: 例如: 学生和课程; 分析:一个学生可以选择很多门课程,一门课程可以被多个学生选择;
b)实现:
一对多(多对一):例如部门和员工;
实现方式:在多的一方建立外键,指向一的一方的主键;
多对多:例如:学生和课程
实现方式:多对多关系实现需要借助第三张中间表,中间表至少包含两个字段,这两个字段作为
第三张表的外键,分别指向两张表的主键;
一对一:学生和身份证表
实现方式:可以在任意一方添加唯一外键指向另一方的主键;
案例:
-- 线路分类表
CREATE TABLE t_category(
cid INT(11) PRIMARY KEY AUTO_INCREMENT COMMENT '线路分类id',
cname VARCHAR(100) NOT NULL UNIQUE COMMENT '线路名称'
);
-- 线路表
CREATE TABLE t_route(
rid INT(11) PRIMARY KEY AUTO_INCREMENT COMMENT '路线id',
rname VARCHAR(100) NOT NULL UNIQUE COMMENT'路线名称',
price DOUBLE(4,2) NOT NULL COMMENT '价格',
createtime DATE NOT NULL COMMENT '创建时间',
cid INT(11) COMMENT '分类id',
FOREIGN KEY (cid) REFERENCES t_category(cid)
);
-- 用户表
CREATE TABLE t_user(
id INT(11) PRIMARY KEY AUTO_INCREMENT COMMENT'用户id',
username VARCHAR(100) UNIQUE NOT NULL COMMENT'用户名',
PASSWORD VARCHAR(30) NOT NULL COMMENT'密码',
sex INT(5) NOT NULL COMMENT'性别:0是男,1是女',
phone VARCHAR(150) NOT NULL COMMENT'联系电话'
);
-- 中间表
CREATE TABLE t_fav(
rid INT(11) NOT NULL COMMENT'线路id',
uid INT(11) NOT NULL COMMENT'用户id',
-- 创建复合主键
PRIMARY KEY(rid,uid),
FOREIGN KEY(rid) REFERENCES t_route(rid),
FOREIGN KEY(uid) REFERENCES t_user(id)
);
2)数据库的范式
概念:设计数据库时,需要遵循的一些规范;要遵循后边的范式要求,必须先遵循前边所有范式要求。
分类:第一范式:数据库表的每一列都是不可分割的原子数据项;
存在问题:
1)存在非常严重的数据冗余:姓名、系名、系主任;
2)数据添加存在问题:添加新开设的系和系主任时,数据不合法;
3)数据删除存在问题:张无忌毕业了,删除数据,会将系的数据一起删除;
第二范式:在第一范式的基础上,非码属性必须完全依赖于候选码(在第一范式的基础上消除非主属性对主 码的部分函数依赖);
1.重要概念:
1)函数依赖: A——>B,如果通过A属性(属性组)的值,可以确定唯一B属性的值。则称B依赖A; 例如:学号——>姓名; (学号、课程)——>分数;
2)完全函数依赖:A——>B,如果A是一个属性组,则B属性值的确定需要依赖于A属性组中所有属性值; 例如: (学号、课程)——>分数;
3)部分函数依赖:A——>B,如果A是一个属性组,则B属性值的确定只需要依赖A属性组中部分属性值; 例如:(学号、课程)——>姓名;
4)传递函数依赖:A——>B, B——>C 如果通过A属性(属性组)的值,可以确定唯一B属性的值,通过B属性组的值可以确定C唯一的属性值。 例如: (学号)——>(系名); (系名)——>(系主任)
5)码:如果在一张表中,一个属性或属性组,被其他所有属性所完全依赖,则称这个属性(属性值为码); 例如:(学号、课程名称)
6)主属性:码属性组中的所有属性;
7)非主属性:除过码属性组的属性;
第三范式:在第二范式的基础上消除,传递依赖;
9.数据库的备份与还原
1.方式一:命令行
语法:
备份:mysqldump -u用户名 -p密码 > 保存路径;
还原:登陆数据库;
创建数据库;
使用数据库;
执行文件,source 文件路径;
2. 图形化工具:
10.多表查询:
## 多表查询
## 语法:
SELECT 列名列表 FROM 表名列表 WHERE 分组前条件 GROUP BY HAVING 分组后条件 ORDER BY 升序、降序;
SELECT AVG(sal),deptno FROM emp WHERE sal IS NOT NULL GROUP BY deptno HAVING AVG(sal) >2000 ORDER BY AVG(sal);
USE db1;
## 准备数据
# 创建部门表
CREATE TABLE t_dept(
id INT(11) PRIMARY KEY AUTO_INCREMENT COMMENT '部门编号',
NAME VARCHAR(32) DEFAULT NULL COMMENT '部门名称'
)ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
# 添加数据
INSERT INTO dept (NAME) VALUES ('开发部'),('市场部'),('财务部');
# 创建员工表
CREATE TABLE t_emp(
id INT(11) PRIMARY KEY AUTO_INCREMENT COMMENT '员工编号',
NAME VARCHAR(50) DEFAULT NULL COMMENT '员工姓名',
gender INT(2) DEFAULT NULL COMMENT '性别 0:男 1:女',
sal DOUBLE DEFAULT NULL COMMENT '薪资',
join_date DATE DEFAULT NULL COMMENT '入职日期',
dept_id INT(11),
CONSTRAINT emp_dept_id FOREIGN KEY (dept_id) REFERENCES t_dept(id)
)ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
#添加数据
INSERT INTO t_emp(NAME,gender,sal,join_date,dept_id) VALUES('猪八戒',0,3600,'2010-12-02',2);
INSERT INTO t_emp(NAME,gender,sal,join_date,dept_id) VALUES('猪八戒',0,3600,'2010-12-02',2);
INSERT INTO t_emp(NAME,gender,sal,join_date,dept_id) VALUES('唐僧',0,9000,'2008-08-08',2);
INSERT INTO t_emp(NAME,gender,sal,join_date,dept_id) VALUES('白骨精',1,5000,'2015-10-07',3);
INSERT INTO t_emp(NAME,gender,sal,join_date,dept_id) VALUES('蜘蛛精',1,4500,'2011-03-14',1);
-- 笛卡尔积 A、B: 有两个集合A和B,取这两个集合的所有组成情况
SELECT * FROM t_dept,t_emp;
-- 消除无用数据
-- 多表查询分类
## 1.内连接查询
-- 1)隐式内连接:使用where条件来消除多余数据
SELECT * FROM t_emp,t_dept WHERE t_emp.dept_id = t_dept.id;
SELECT
t1.id,t1.name,t2.name
FROM
t_emp t1, t_dept t2
WHERE
t1.dept_id=t2.id;
-- 2)显示内连接
-- 语法:
SELECT * FROM t_emp t1 INNER JOIN t_dept t2 WHERE t1.dept_id=t2.id;
-- 3)内连接查询:1)从哪些表中查询数据;2)条件是什么; 3)查询哪些字段;
## 2. 外连接
-- 1)外连接:
-- 左外连接:select 字段列表 from 表1 left join 表2 on 连接条件;
-- 查询的是左表所有数据以及其交集部分
-- 查询所有员工信息,如果员工有部门,则查询部门名称,没有部门,则不显示。
SELECT t1.* , t2.name
FROM t_emp t1
LEFT JOIN t_dept t2 ON t1.dept_id = t2.id;
-- 右外连接:select 字段列表 from 表1 right join 表2 on 连接条件;
-- 查询的是右表所有数据以及其交集部分
SELECT t1.*, t2.name
FROM t_emp t1
RIGHT JOIN t_dept t2 ON t1.dept_id=t2.id;
## 3. 子查询 查询中的嵌套查询,称为子查询;
-- 可以把它看作一张虚拟表;
-- 查询2021年11月11日之后的员工信息和部门信息
SELECT * FROM t_dept t1,(SELECT * FROM t_emp WHERE join_date > '2011-11-11') t2 WHERE t1.id=t2.dept_id;
-- 查询工资最高的员工
SELECT MAX(sal) FROM t_emp;
-- 查询工资为9000的员工
SELECT * FROM t_emp t1 WHERE t1.sal=(SELECT MAX(sal) FROM t_emp);
-- 子查询不同种情况;
-- 情况一:子查询的结果是单行单列的;
-- 子查询可以作为条件,使用运算符去判断
-- 查询员工工资小于平均工资的人
SELECT * FROM t_emp WHERE t_emp.sal< (SELECT AVG(sal) FROM t_emp);
-- 情况二:子查询的结果是多行单列的;
-- 查询财务部和市场部所有员工的信息
SELECT id FROM t_dept WHERE NAME='财务部'OR NAME='市场部';
SELECT * FROM t_emp WHERE dept_id IN(SELECT id FROM t_dept WHERE NAME='财务部'OR NAME='市场部');
-- 情况三:子查询的结果是多行多列的;
-- 子查询如果结果是多行多列的可以做为一张虚拟表;
-- 查询员工入职日期是2011-11-11之后的员工信息和部门信息
SELECT * FROM t_dept t1,(SELECT * FROM t_emp WHERE t_emp.join_date >'2011-11-11') t2 WHERE t1.id=t2.dept_id;
## 多表查询练习
-- 部门表
CREATE TABLE dept (
id INT PRIMARY KEY PRIMARY KEY, -- 部门id
dname VARCHAR(50), -- 部门名称
loc VARCHAR(50) -- 部门所在地
)ENGINE=INNODB DEFAULT CHARSET=utf8;
-- 添加4个部门
INSERT INTO dept(id,dname,loc) VALUES
(10,'教研部','北京'),
(20,'学工部','上海'),
(30,'销售部','广州'),
(40,'财务部','深圳');
-- 职务表,职务名称,职务描述
CREATE TABLE job (
id INT PRIMARY KEY,
jname VARCHAR(20),
description VARCHAR(50)
)ENGINE=INNODB DEFAULT CHARSET=utf8;
-- 添加4个职务
INSERT INTO job (id, jname, description) VALUES
(1, '董事长', '管理整个公司,接单'),
(2, '经理', '管理部门员工'),
(3, '销售员', '向客人推销产品'),
(4, '文员', '使用办公软件');
-- 员工表
CREATE TABLE emp (
id INT PRIMARY KEY, -- 员工id
ename VARCHAR(50), -- 员工姓名
job_id INT, -- 职务id
mgr INT , -- 上级领导
joindate DATE, -- 入职日期
salary DECIMAL(7,2), -- 工资
bonus DECIMAL(7,2), -- 奖金
dept_id INT, -- 所在部门编号
CONSTRAINT emp_jobid_ref_job_id_fk FOREIGN KEY (job_id) REFERENCES job (id),
CONSTRAINT emp_deptid_ref_dept_id_fk FOREIGN KEY (dept_id) REFERENCES dept (id)
)ENGINE=INNODB DEFAULT CHARSET=utf8;
-- 添加员工
INSERT INTO emp(id,ename,job_id,mgr,joindate,salary,bonus,dept_id) VALUES
(1001,'孙悟空',4,1004,'2000-12-17','8000.00',NULL,20),
(1002,'卢俊义',3,1006,'2001-02-20','16000.00','3000.00',30),
(1003,'林冲',3,1006,'2001-02-22','12500.00','5000.00',30),
(1004,'唐僧',2,1009,'2001-04-02','29750.00',NULL,20),
(1005,'李逵',4,1006,'2001-09-28','12500.00','14000.00',30),
(1006,'宋江',2,1009,'2001-05-01','28500.00',NULL,30),
(1007,'刘备',2,1009,'2001-09-01','24500.00',NULL,10),
(1008,'猪八戒',4,1004,'2007-04-19','30000.00',NULL,20),
(1009,'罗贯中',1,NULL,'2001-11-17','50000.00',NULL,10),
(1010,'吴用',3,1006,'2001-09-08','15000.00','0.00',30),
(1011,'沙僧',4,1004,'2007-05-23','11000.00',NULL,20),
(1012,'李逵',4,1006,'2001-12-03','9500.00',NULL,30),
(1013,'小白龙',4,1004,'2001-12-03','30000.00',NULL,20),
(1014,'关羽',4,1007,'2002-01-23','13000.00',NULL,10);
-- 工资等级表
CREATE TABLE salarygrade (
grade INT PRIMARY KEY, -- 级别
losalary INT, -- 最低工资
hisalary INT -- 最高工资
)ENGINE=INNODB DEFAULT CHARSET=utf8;
-- 添加5个工资等级
INSERT INTO salarygrade(grade,losalary,hisalary) VALUES
(1,7000,12000),
(2,12010,14000),
(3,14010,20000),
(4,20010,30000),
(5,30010,99990);
-- 需求:
-- 1.查询所有员工信息。查询员工编号,员工姓名,工资,职务名称,职务描述
-- 分析:1)员工编号,员工姓名,工资需要查询emp表 职务名称,职务描述 需要插叙job表
-- 2)查询条件:emp.job_id= job.id;
SELECT
t1.id, -- 员工编号
t1.ename, -- 员工姓名
t1.salary, -- 工资
t2.jname, -- 职务名称
t2.description -- 职务描述
FROM
emp t1, job t2
WHERE
t1.job_id=t2.id;
-- 2.查询员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置
-- 分析:1)员工姓名、工资 emp; 职务名称 职务描述 job; 部门名称、部门位置 dept
-- 2) 条件: emp.job_id= job.id and emp.dept_id=dept.id;
SELECT
t1.ename, t1.salary, t2.jname, t2.description, t3.dname, t3.loc
FROM
emp t1, job t2, dept t3
WHERE
t1.job_id =t2.id AND t1.dept_id=t3.id;
-- 3.查询员工姓名,工资,工资等级
-- 分析:1)员工姓名、工资 emp; 工资等级 salaydrade
-- 2) 条件 emp.salary between salarygrade.losalary and salarygrade.hisalary
SELECT
t1.ename,
t1.salary,
t2.grade
FROM
emp t1, salarygrade t2
WHERE
t1.salary BETWEEN t2.losalary AND t2.hisalary;
-- 4.查询员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级
-- 分析:1)员工姓名、工资 emp; 职务名称、职务描述 job; 部门名称、部门位置 dept 工资等级 salarygrade
-- 2) emp.job_id= job.id and emp.dept_id=dept.id and emp.salary between salarygrade.losalary and salarygrade.hisalary
SELECT
t1.ename,
t1.salary,
t2.jname,
t2.description,
t3.dname,
t3.loc,
t4.grade
FROM
emp t1, job t2, dept t3, salarygrade t4
WHERE
t1.job_id =t2.id
AND t1.dept_id = t3.id
AND t1.salary BETWEEN t4.losalary AND t4.hisalary;
-- 5.查询出部门编号、部门名称、部门位置、部门人数
-- 1)分析:部门编号、部门名称、部门位置 dept 部门人数 emp表
-- 使用分组查询。按照emp.dept_id完成分组,查询count(id)
-- 使用子查询将第二部的查询结果,和dept表进行关联;
SELECT
t1.id, t1.dname, t1.loc, t2.total
FROM
dept t1,
(SELECT
dept_id,COUNT(id) total
FROM
emp
GROUP BY dept_id) t2
WHERE t1.id = t2.dept_id;
-- 6.查询所有员工的姓名及其直接上级的姓名,没有领导的员工也需要查询
-- 1)分析:员工姓名 emp 直接上级姓名 emp ,emp表的id 和 mgr是自关联
-- 2)条件:emp.id = emp.mgr
-- 3) 查询左表的所有数据,和交集数据 使用左外连接查询
/* select
t1.ename,
t1.mgr,
t2.id,
t2.ename
from
emp t1, emp t2
where
t1.id = t2.mgr;
*/
SELECT
t1.ename,
t1.mgr,
t2.id,
t2.ename
FROM emp t1
LEFT JOIN emp t2 ON t1.id=t2.mgr;
事务
1. 概念:如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败;
2. 操作:
1)开启事务:start transaction;
2) 回滚:rollback;
3) 提交:commit;
-- 0.开启事务
START TRANSACTION;
-- 1.张三账户 -500
UPDATE t_account SET amount=amount-500 WHERE NAME='张三';
-- 2.李四账户 +500
UPDATE t_account SET amount=amount+500 WHERE NAME='李四';
-- 发现执行没有问题,提交事务
COMMIT;
-- 发现出现问题,回滚事务
ROLLBACK;
## Mysql数据库中事务默认自动提交
-- 事务提交的两种方式:
-- 自动提交:
-- Mysql就是自动提交的,
-- 一条DML(增删改语句)会自动提交一次;
-- 手动提交
-- Oracle数据库默认是手动提交事务;
-- 需要先开启事务,再提交;
-- 修改默认的提交方式:
-- 查看事务的默认提交方式:select @@autocommit; --1 代表自动提交 0 代表手动提交
-- 修改默认提交方式:set @@autocommit =0;
3. 事务的四大特征:
1)原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败;
2)持久性:当事务提交或回滚后,数据库会持久化的保存数据;
3)隔离性:多个事务之间,相互独立。
4)一致性:事务操作前操作后,数据总量部不变;