一:数据库相关概念
1.数据库(DataBase)
管理和存储数据的仓库
2.数据库管理系统(DataBase Management System)
管理数据库的软件
常见的数据库管理系统有:
--Oracle:收费的大型数据库,Oracle 公司的产品
--DB2: IBM 公司的大型收费数据库
--Microsoft SQL Server : MicroSoft 公司收费的中型数据库。C#、.net 等语言常使用
--MySQL: 开源免费的中小型数据库,被Oracle收购
--PostgreSQL: :开源免费中小型的数据库
--MariaDB: 开源免费的中小型数据库
-- SQLite: 嵌入式的微型数据库 (如:作为Android的内置数据库)
3.SQL(Structured Query Language)
结构化查询语言,操作关系型数据库的编程语言, 定义了操作所有关系型数据库的统一标准(即可以使用SQL操作所有的关系型数据库管理系统)
4.关系型数据库
关系型数据库的定义:
是建立在关系模型基础上的数据库, 是由多张能相互连接的二维表组成的数据库
关系型数据库的优点:
1. 都是使用表结构,易于维护
2.使用通用的SQL语言操作,可用于复杂查询
3.数据存在磁盘中,安全
5.MySQL数据模型
1. MySQL可以创建多个数据库,每个数据库对应磁盘上的一个文件夹
2.在每个数据库可以创建多个表, 每张表都对应磁盘上的一个frm文件
3.每张表可以存储多条数据, 数据会被存储到磁盘中的MYD文件中
二:部署MySQL环境
1.下载安装
MySQL :: Download MySQL Community Server (Archived Versions)
链接点进去,选择5.7.24版本,在选择与自己系统位数相同的压缩包下载即可
压缩包下载完成后,解压到你想要解压的目录即可
2.MySQL配置
-1- 在环境变量中添加MySQL路径
(原因是在为了在任何一个命令提示符中可以直接调用MySQL)
-2- 在安装目录中新建配置文件,设置数据库默认编码集为utf-8和默认存储引擎为INNODB
在安装目录中,新建my.ini文本文件,保存类型选All types, 文本文件内容如下
[mysql]
default-character-set=utf8
[mysqld]
character-set-server=utf8
default-storage-engine=INNODB
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
-3-初始化MySQL
在命令提示符中敲出如下指令
mysqld --initialize -insecure
-4- 安装MySQL服务
在命令提示符中敲出如下指令
mysqld -install
-5- 启动MySQL服务
在命令提示符中敲出如下指令
net start mysql
-6- 修改默认的账户以及密码
mysqladmin -u root password root
3.MySQL登录和退出
-1- 登录
登录参数为: mysql -u用户名 -p密码 -hip地址 -p端口号
ip地址默认本机ip地址, 端口号默认为3306
-2- 退出
exit或者quit
4.卸载
打开菜单,以管理员身份打开命令提示符,分别执行如下步骤
-1- net stop mysql (停止mysql服务)
-2- mysqlld -remove mysql (移除mysql服务)
-3- 删除mysql目录以及相关环境变量
三:SQL概述
1.SQL简介
结构化查询语言,一门操作关系型数据库的编程语言,定义了操作所有关系型数据库的统一标准
2.SQL通用语法
1.SQL语句可以单行或者多行书写,以分号结尾
2.单行注释: -- 注释内容(注意-- 后面要加空格)
3.多行注释: /*注释内容*/
4.MySQL数据库的SQL语句不区分大小写,但关键字建议大写
5.MySQL数据库中独有的注释方式: #注释内容
3.SQL分类
1.DDL(Data Definition Language) 数据定义语言,用来定义数据库, 表, 列
2.DML(Data Manipulation Language)数据操作语言,用来对表中数据进行增删改
3.DQL(Data Query Language) 数据查询语言,用来查询表中数据
4.DCL(Data Control Language) 数据控制语言,用来定义数据库的访问权限以及安全级别
四:DDL(操作数据库,操作数据表,列)
1.DDL操作数据库
-1-创建数据库
create database db1;-- 创建数据库
create database if not exists db1;-- 添加判断条件的创建数据库, 如果数据库不存在,再创建数据库
-2-删除数据库
drop database db2; -- 删除数据库
drop database if exists db2;-- 添加判断条件的删除数据库,如果该数据库存在,再删除数据库
-3-使用数据库
use db3;-- 使用db3这个数据库
-4-查询所有数据库
show databases;-- 查询所有的数据库
-5-查询当前使用的数据库
select database();
2.DDL操作数据表
-1-创建数据表
create table 表名(
字段名1 数据类型1 (约束) (comment 字段1注释),
字段名2 数据类型2 (约束) (comment 字段2注释),
字段名3 数据类型3 (约束) (comment 字段3注释),
字段名n 数据类型n (约束) (comment 字段n注释)
-- 注意最后一行末尾不能加逗号
) (comment 表注释) ;
create table tb_user(
id int comment 'ID,唯一标识',
username varchar(20) comment '用户名',
password varchar(32) comment '密码'
) comment '用户表';
MySQL数据类型如下:
数值类型:
tinyint: 小整数类型,占一个字节
int: 大整数类型,占四个字节 Eg: age int
double:浮点类型 , 使用格式:score double(数字总长度,小数点后保留的位数)
Eg: score double(5,2)
日期类型:
date: 日期值,只包含年月日
datetime: 混合日期值, 包含年月日,时分秒
字符串类型:
char: 定长字符串,存储性能高,浪费空间, Eg: name char(10)
varchar:变长字符串,存储性能低(因为要计算字符的个数),节约空间
Eg: name varcahr(10)
(如果存储的数据字符个数不足10个,那就数据字符个数是几就占几个的空间)
-2-删除数据表
drop table db4; -- 删除数据表
drop table if exists db4; -- 添加判断条件的删除数据表,如果该数据表存在,再删除数据表
-3-修改数据表
-- 修改表名
alter table student rename to stu; -- 将表名student修改为stu
-- 给表添加字段
alter table stu add address varchar(50); -- 给stu表添加address字段,该字段类型是varchar(50)
-- 删除字段
alter table stu drop addr; -- 将stu表中的addr字段删除
-- 修改字段数据类型
alter table stu modify address char(50); -- 将stu表中的address字段的类型改为 char(50)
-- 同时修改字段名称和字段数据类型
alter table stu change address addr varchar(50); -- 将stu表中的address字段名改为 addr,类型改为varchar(50)
-4-查询数据表
show tables; --查询当前数据库下所有表的名称
desc 表名; -- 查询该表的结构
五:DML(操作数据)
1.添加数据
-- 给部分字段添加数据
insert into 表名(字段1,字段2,...) values(值1,值2,...);
insert into stu(id,name) values(1,'张三');
-- 给全部字段添加数据
insert into 表名 values(值1,值2,...);
insert into stu values(1,'张三');
-- 给部分字段批量添加数据
insert into 表名(列名1,列名2,...) values
(值1,值2,...),
(值1,值2,...);
insert into stu (id,name,sex,birthday,score,email,tel,status) values
(2,'李四','男','1999-11-11',88.88,'lisi@.cn','13888888888',1),
(3,'五','女','1996-11-11',58.80,'lisi@.cn','13888877778',1);
-- 给全部字段批量添加数据
insert into 表名 values
(值1,值2,...),
(值1,值2,...);
insert into stu values
(2,'李四','男','1999-11-11',88.88,'lisi@cn','13888888888',1),
(3,'李二','女','1999-11-11',33.48,'lisi@cn','13888888888',1),
(4,'李并','男','1999-11-11',78.18,'lisi@cn','13888888888',1);
2.删除数据
-- 删除表中全部数据
delete from stu;
-- 删除表中部分数据
delete from 表名 where 条件;
delete from stu where name='张三';
注意:如果删除语句中不加where条件,则将整张表的数据都删除,后果很严重
3.修改数据
-- 修改某些字段全部的数据
update stu set birthday='1999-12-12',score=99.99;
-- 修改表中部分数据
update 表名 set 列名1=值1,列名2=值2,... where 条件;
update stu set birthday='1999-12-12',score=99.99 where name ='李四';
注意:如果修改语句不加where条件,则所有数据都将修改,后果很严重
六:DQL(查询数据)
1.查询的完整语法
select 普通字段/聚合函数字段列表
from 表名列表
where 分组前条件列表
group by 分组字段
having 分组后条件列表
order by 排序字段
limit 分页限定
2.查询普通字段
-- 查询去重后的单一字段
select distinc 字段 from表名;
select distinct address from stu;
-- 查询部分字段
select 字段1,字段2,...from 表名;
select name,age from stu;
--查询部分字段并给部分字段起别名
select 字段1 (as) 别名1,字段2 (as) 别名2,...from 表名;
select name as 姓名, math as 数学成绩 from stu;
select name 姓名, math 数学成绩 from stu;
-- 查询所有字段
select * from 表名;
select * from stu;
3.查询聚合函数字段
聚合函数定义: 是将一列数据作为整体,进行纵向计算
聚合函数的分类:
count(字段) 统计某一字段的值的数量
sum(字段) 统计某一字段值的总和
avg(字段) 统计某一字段值的平均值
max(字段) 统计某一字段的最大值
min(字段) 统计某一字段的最小值
聚合函数的语法:
select 聚合函数(字段名) from 表名;
select count(id) from stu;
select count(*) from stu; -- 推荐使用的方式来统计某一字段值的数量
select sum(math) from stu;
select avg(math) from stu;
select max(math) from stu;
select min(math) from stu;
注意:null值不参与所有聚合函数的运算
4.条件查询
select 字段1,字段2,...字段n from 表名 where 条件语句;
字段语句可以使用的运算符:
select * from stu where age>20;
select * from stu where age<20;
select * from stu where age>=20;
select * from stu where age<=20;
select * from stu where age=20;
select * from stu where age!=20;
select * from stu where age<>20;
select * from stu where age between 10 and 20;
select * from stu where hire_date between '1998-09-01' and '1999-09-02';
select * from stu where age in(10,20,30);
-- 模糊查询使用like关键字,可以使用通配符进行占位 - 表示单个任意字符 %代表任意个任意字符
select * from stu where name like'马%'; -- 查询姓'马'的学员信息
select * from stu where name like'_马%'; -- 查询名字中第二个字是'马'的学员信息
select * from stu where name like'%马%'; -- 查询名字中包含 '马' 的学员信息
-- null值的比较需要使用 is 或者 is not,不能使用 = 或者 !=
select * from stu where english is null;
select * from stu where english is not null;
select * from stu where name='zz' and age=18;
select * from stu where name='zz' && age=18;
select * from stu where age=18 or age=20 or age=22;
select * from stu where age=18 || age=20 || age=22;
5.分组查询
select 字段列表 from 表名 where 分组前条件限定 group by 分组字段名 having 分组后条件过滤;
注意:分组后,查询的字段应该为分组字段或者聚合函数所在字段,查询其他字段无任何意义
where和having区别:
1.where 是分组之前进行限定,不满足where条件,则不参与分组,而having是分组之后对结果进行过滤
2.where 不能对聚合函数进行判断,having 可以对聚合函数进行判断
select sex, avg(math) from stu group by sex; -- 查询男同学和女同学各自的数学平均分
select sex,avg(math),count(*) from stu group by sex;-- 查询男同学和女同学各自的数学平均分,以及各自人数
select sex, avg(math),count(*) from stu where math > 60 group by sex; -- 查询分数高于60分的男同学和女同学各自的数学平均分,以及各自人数
select sex,avg(math),count(*) from stu where math >60 group by sex having count(*)>2; --查询分数高于60分并且按照性别分组后分组人数大于2个的男同学和女同学各自的数学平均分,以及各自人数
6.排序查询
select 字段列表 from 表名 order by 排序字段名1 排序方式1,排序字段名2 排序方式2 …;
asc:升序排列(默认排序方式) desc:降序排列
select * from stu order by age; -- 查询学生信息,按照年龄升序排列
select * from stu order by age asc; -- 查询学生信息,按照年龄升序排列
select * from stu order by age desc; --查询学生信息,按照年龄降序排列
select * from stu order by math desc,english asc; --查询学生信息,按照数学成绩降序排列,如果
7.分页查询
select 字段列表 from 表名 limit 起始索引 , 查询条目数;
注意:索引从0开始
select * from stu limit 0,3; -- 查询第一页的数据,每页查询3条数据,即查询0号索引到2号索引的数据
select * from stu limit 3,3; -- 查询第二页的数据,每页查询3条数据,即查询3号索引到5号索引的数据
select * from stu limit 6,3; -- 查询第三页的数据,每页查询3条数据, 即查询6号索引到8号索引的数据
起始索引 = (当前页码 - 1) * 每页显示的条数
七:图形化界面Navicat for MySQL的使用
1.Navicat for MySQL概述
Navicat for MySQL是一套专门为MySQL和MariaDB设计的高性能数据库管理及开发工具
Navicat for MySQL这个前端工具为数据库管理,开发,维护提供了直观
2.Navicat for MySQL的安装
网上自行找教程安装并破解即可使用
3.Navicat for MySQL的使用
-1- 建立与MySQL服务的连接
1.点击连接,选择MySQL
2.填写连接数据库必要的信息(ip,端口,用户名,密码)
-2- 操作数据库
1.修改表结构
选中数据库中需要操作的表,右击选择设计表,就可以了
2.编写SQL语句并执行
可以选择在数据库或者表下新建查询,就可以在查询中编写SQL语句,点击运行按钮或者选中需要运行的SQL语句右键运行
八:约束
1.概念
约束是作用于表中列上的规则,用于限制加入表的数据,约束的存在保证了数据库中数据的正确性、有效性和完整性
2.分类
-1-非空约束,关键字是 not null
保证列中所有的数据不能有null值
-2-唯一约束,关键字是unique
保证列中所有数据各不相同
-3-主键约束,关键字是primary key
主键是一行数据的唯一标识,要求非空且唯一
-4-检查约束,关键字是check
` 保证列中的值满足某一条件,注意MySQL不支持检查约束
-5-默认约束,关键字是default
保存数据时,如果未指定值,则采用默认值
-6-外键约束,关键字是foreign key
外键是用来让两个表的数据之间建立连接,保证数据的一致性和完整性
3.非空约束
-1-添加约束
-- 建完表后添加非空约束
create table 表名(
列名 数据类型 not null,
…
);
-- 建完表后添加非空约束
alter table 表名 modify 字段名 数据类型 not null;
-2-删除约束
alter table 表名 modify 字段名 数据类型;
4.唯一约束
-1-添加约束
-- 创建表时添加唯一约束
create table 表名(
列名 数据类型 unique auto_increment, -- AUTO_INCREMENT: 当不指定值时自动增长
…
);
create table 表名(
列名 数据类型,
…
constraint 约束名称 unique(列名)
);
-- 建完表后添加唯一约束
create table 表名 modify 字段名 数据类型 unique;
-2-删除约束
alter table 表名 drop index 字段名;
5.主键约束
-1-添加约束
-- 创建表时添加主键约束
create table 表名(
列名 数据类型 PRIMARY KEY auto_increment,
…
);
create table 表名(
列名 数据类型,
constraint 约束名称 PRIMARY KEY(列名)
);
-- 建完表后添加主键约束
alter table表名 ADD PRIMARY KEY(字段名);
-2-删除约束
alter table 表名drop foreign key;
6.默认约束
-1-添加约束
-- 创建表时添加默认约束
create table 表名(
列名 数据类型 default 默认值,
…
);
-- 建完表后添加默认约束
alter table 表名 alter 列名 set default 默认值;
-2-删除约束
alter table 表名 alter 列名 drop default;
7.外键约束
-1-添加约束
create table 表名(
列名 数据类型,
…
constraint 外键名称 foreign key(外键列名) references 主表(主表列名)
);
-- 建完表后添加外键约束
alter table 表名 add constraint 外键名称 foreign key (外键字段名称) references 主表名称(主表列名称);
-2-删除约束
alter table 表名 drop foreign key 外键名称;
九:数据库多表设计
1.简介
数据库设计就是根据业务系统的具体需求,结合我们选用的数据库管理系统,为业务系统构造出最优的数据存储模型,也是建立数据库中的表结构以及表与表之间的关联关系的过程(简单来说,就是业务系统中有哪些表,表中有哪些字段,表与表之间有什么关系)
2.常见的表关系
-1- 一对一
如一张用户表对应一张用户详情表
一对一表关系多用于表拆分,将一个实体中经常使用的字段放一张表,不经常使用的字段放另一张表,用于提升查询性能
-2- 一对多
如一个部门表对应多个员工
-3- 多对多
如订单表和商品表之间的关系,一个订单包含多个商品,一个商品对应多个订单
2.一对一表关系
建立两张表一对一关系的实现方式:
在任意一方加入唯一约束的外键,关联另一方主键,
案例:(建立一对一表关系的两张表之间的联系)
-- 编写用户详情表的建表语句
create table tb_user_desc(
id int primary key auto_increment,
city varchar(20),
edu varchar(10),
income int,
status char(2),
desc varchar(1000)
);
-- 在用户表建立一对一表关系的两张表之间的关系
create table tb_user(
id int primary key auto_increment,
photo varchar(100),
nickname varchar(50),
age int,
gender char(1),
desc_id int unique,
-- 添加外键
constraint fk_user_desc foreign key(desc_id) references tb_user_desc(id)
);
3.一对多表关系
建立两张一对多关系的表之间的联系的实现方式:
在多的一张表中加入外键,关联另一方主键
案例:(建立一对多表关系的两张表之间的联系)
-- 删除表
drop table if exists tb_emp;
drop table if exists tb_dept;
-- 部门表
create table tb_dept(
id int primary key auto_increment,
dep_name varchar(20),
addr varchar(20)
);
--在员工表添加外键
create table tb_emp(
id int primary key auto_increment,
name varchar(20),
age int,
dep_id int,
-- 添加外键,使dep_id关联dept表的id主键
constraint fk_emp_dept foreign key(dep_id) references tb_dept(id)
);
4.多对多表关系
建立两张多对多关系的表之间的联系的实现方式:
建立第三张表,第三张表中包含两个外键,分别关联两方主键
案例:(建立多对多表关系的两张表之间的联系)
-- 删除表
drop table if exists tb_order_goods;
drop table if exists tb_order;
drop table if exists tb_goods;
-- 订单表
create table tb_order(
id int primary key auto_increment,
payment double(10,2),
payment_type TINYINT,
status TINYINT
);
-- 商品表
create table tb_goods(
id int primary key auto_increment,
title varchar(100),
price double(10,2)
);
-- 订单商品中间表
create table tb_order_goods(
id int primary key auto_increment,
order_id int,
goods_id int,
count int
);
-- 建完表后,添加外键
alter table tb_order_goods add constraint fk_order_id_ foreign key(order_id) references tb_order(id);
alter table tb_order_goods add constraint fk_goods_id foreign key(goods_id) references tb_goods(id);
十:多表查询
1. 定义
多表查询顾名思义就是从多张表中一次性查询出我们需要的数据
2.多表查询的分类
-1-连接查询
内连接查询:查询A表与B表交集的数据
..隐式内连接: 不加关键字inner join
select 字段列表 from 表1,表2… where 条件;
..显式内连接: 加关键字inner join
select 字段列表 from 表1 (inner) join 表2 on 条件;
外连接查询:
..左外连接查询:查询A表所有数据和A表与B表交集的数据
select 字段列表 from 表1 left (outer) join 表2 on 条件;
..右外连接查询:查询B表所有数据和A表与B表交集的数据
select 字段列表 from 表1 right (outer) join 表2 on 条件;
-2-子查询
查询中嵌套查询,称为子查询
3.内连接查询
-- 隐式内连接
select 字段列表 from 表1,表2… where 条件;
-- 显示内连接
select 字段列表 from 表1 (inner) join 表2 on 条件;
-- 隐式内连接案例
select * from emp,dept where emp.dep_id = dept.did;
select emp. NAME, emp.gender,dept.dname from emp,dept where emp.dep_id = dept.did;
select t1. NAME, t1.gender, t2.dname from emp t1,dept t2 where t1.dep_id = t2.did;
-- 显式内连接案例
select * from emp inner join dept on emp.dep_id = dept.did;
-- 上面语句中的inner可以省略,可以书写为如下语句
select * from emp join dept on emp.dep_id = dept.did;
4.外连接查询
-- 左外连接
select 字段列表 from 表1 left (outer) join 表2 on 条件;
-- 右外连接
select 字段列表 from 表1 right (outer) join 表2 on 条件;
-- 查询emp表所有数据和对应的部门信息(左外连接)
select * from emp left join dept on emp.dep_id = dept.did;
-- 查询dept表所有数据和对应的员工信息(左外连接)
select * from dept left join emp on emp.dep_id = dept.did;
-- 查询dept表所有数据和对应的员工信息(右外连接)
select * from emp right join dept on emp.dep_id = dept.did;
5.子查询
-
子查询语句结果是单列单行,子查询语句作为条件值,使用 = != > < 等进行条件判断
-
子查询语句结果是单列多行,子查询语句作为条件值,使用 in 等关键字进行条件判断
-
子查询语句结果是多行多列,子查询语句作为虚拟表
-- 查询 '财务部' 和 '市场部' 所有的员工信息
select * from emp where dep_id in (select did from dept where dname = '财务部' or dname = '市场部');
-- 查询入职日期是 '2011-11-11' 之后的员工信息和部门信息
select * from (select * from emp where join_date > '2011-11-11' ) t1, dept where t1.dep_id = dept.did;
十一:事务
1.定义
数据库的事务(transaction)包含了一组数据库操作命令,事务把所有的命令作为一个整体一起向系统提交或者撤销操作请求,这组命令要么同时成功,要么同时失败,是不可分割的工作逻辑单元
2. 语法
-- 开启事务
start transaction;
或者begin
-- 回滚事务
rollback;
-- 提交事务
commit;
3.事务的四大特征(ACID)
-1- 原子性(Atomicity):事务是不可分割的最小操作单位,要么同时成功,要么同时失败
-2- 一致性(Consistency):事务完成时,必须所有的数据都保持一致
-3- 隔离性(Isolation):多个事务之间相互隔离,操作不可见
-4- 持久性(Durability):事务一旦提交或者回滚,对数据库中的数据的更改就是永久的
4.MySQL中的事务
MySQL中事务是自动提交的(也就是说我们不添加事务执行sql语句,MySQL会在sql语句执行完毕后自动提交)
查询事务默认提交的方式的语句如下:
SELECT @@autocommit;
查询的结果为0表示事务默认的提交方式是手动提交,结果为1表示事务默认的提交方式是是自动提交
修改事务默认提交的方式的语句如下:
set @@autocommit = 0; -- 修改事务默认的提交方式是手动提交
set @@autocommit = 1; -- 修改事务默认的提交方式是自动提交
5. 案例
完成如下转账案例
张三和李四账户中各有1000块钱,现李四需要转换500块钱给张三,具体的转账操作为
第一步:查询李四账户余额
第二步:从李四账户金额 -500
第三步:给张三账户金额 +500
数据准备:
DROP TABLE IF EXISTS account;
-- 创建账户表
CREATE TABLE account(
id int PRIMARY KEY auto_increment,
name varchar(10),
money double(10,2)
);
-- 添加数据
INSERT INTO account(name,money) values('张三',1000),('李四',1000);
不加事务演示问题:
-- 转账操作
-- 1. 查询李四账户金额是否大于500
-- 2. 李四账户 -500
UPDATE account set money = money - 500 where name = '李四';
出现异常了... -- 此处不是注释,在整体执行时会出问题,后面的sql则不执行
-- 3. 张三账户 +500
UPDATE account set money = money + 500 where name = '张三';
整体执行结果肯定会出问题,我们查询账户表中数据,发现李四账户少了500。
添加事务解决数据问题:
-- 开启事务
BEGIN;
-- 转账操作
-- 1. 查询李四账户金额是否大于500
-- 2. 李四账户 -500
UPDATE account set money = money - 500 where name = '李四';
出现异常了... -- 此处不是注释,在整体执行时会出问题,后面的sql则不执行
-- 3. 张三账户 +500
UPDATE account set money = money + 500 where name = '张三';
-- 提交事务
COMMIT;
-- 回滚事务
ROLLBACK;
上面sql中的执行成功进选择执行提交事务,而出现问题则执行回滚事务的语句。
以后我们肯定不可能这样操作,而是在java中进行操作,在java中可以抓取异常,没出现异常提交事务,出现异常回滚事务。