一、数据库概述
1.1 、什么是数据库
数据库是持久化数据的一种介质,可以理解成用来存储和管理数据的仓库!
持久化(persistence):把数据保存到可掉电式存储设备中以供之后使用。持久化的大多数时候是将内存中的数据存储在数据库中,当然也可以存储在磁盘文件、XML数据文件中。
1.2、为什么要使用数据库
可将数据持久化到硬盘
可存储大量数据
方便检索
保证数据的一致性、完整性
安全,可共享
通过组合分析,可以产生新数据
1.3、数据库相关概念
DB
数据库( database ):存储数据的“仓库”。它保存了一系列有组织的数据。
DBMS
数据库管理系统( Database Management System )。数据库是通过 DBMS 创建和操作的容器
SQL
结构化查询语言( Structure Query Language ):专门用来与数据库通信的语言。
DBMS分为两类:
–基于共享文件系统的DBMS (Access )
–基于客户机——服务器的DBMS(MySQL、Oracle、SqlServer)
1.4、启动MySQL
管理员模式下启动命令提示符:net start MySQL0906(连接名)
登录MySQL:mysql -u root -p root (-h localhost);
二、SQL语言
2.1、SQL语言
SQL(Structured Query Language)是“结构化查询语言”,它是对关系型数据库的操作语言。它可以应用到所有关系型数据库中,例如:MySQL、Oracle、SQL Server等。SQL常见标准有:sql92和sql99
2.2、SQL语法要求
SQL语句可以单行或多行书写,以分号结尾;
可以用空格和缩进来来增强语句的可读性;
关键字不区别大小写,建议使用大写;
2.3、分类
DDL(Data Definition Language):数据定义语言,用来定义数据库对象:库、表、列等;
DML(Data Manipulation Language):数据操作语言,用来定义数据库记录(数据);
DCL(Data Control Language):数据控制语言,用来定义访问权限和安全级别;
DQL(Data Query Language):数据查询语言,用来查询记录(数据)。
2.4、DQL
1.基础查询
语法:select 查询列表 from 表名
特点:1.查询的结果集是一个虚拟表,并没有真实存在
2.查询列表支持常量、字段(列)、表达式、函数(方法)等
补充:
1.去重 distinct
2.起别名 方式一:使用AS 方式二:使用空格
3.常见函数: database()、version()、user()、ifnull()、concat()、DESC
2.条件查询
语法:
select 查询列表-----③
from 表名 ----①
where 条件表达式;-----②
条件表达式的写法:
情况一:关系表达式
sql中的关系运算符:> < >= <= = <> !=
情况二:逻辑表达式
sql中的逻辑运算符:and、 or、 not【官方标准】
情况三:模糊查询 ★
like、between and、in、is null
in
功能:判断某个字段的值是否属于指定列表中的一个元素
用法:
in(常量值1,常量值2,。。。)
not in(常量值1,常量值2,。。。)
3.排序查询
语法:
select 查询列表——————③
from 表名——————①
where 条件——————②
order by 排序列表 asc|desc;——————④
特点:
1、asc代表的是升序。升序是默认行为。desc代表的是降序。
2、排序列表支持单个字段、表达式、函数、别名,也支持以上的组合
3、order by子句一般放在查询语句的最后!
4.常见函数
函数:类似于java中的”方法“,将完成某个功能的一系列步骤封装起来,对外暴露一个名字,供外界调用
当我们学习别人定义好的方法(函数),只需要关心两件事:
①叫什么(函数名)
②干什么(函数功能)
sql中的函数:肯定有,并且仅有一个返回值
调用语法:
select 函数名(实参列表);
一、数学函数:
abs绝对值
mod取余
floor向下取整
truncate 截断
ceil向上取整
round四舍五入
rand随机数
注意:
sql中的round支持两个重载,规则:先按绝对值四舍五入,然后再添加正负
round(x):只保留整数部位
round(x,d):保留小数点后一位
java中Math.round只支持一个参数,规则:Math.round(x)等价于Math.floor(x+0.5) Math.round(x)
二、字符函数
upper转换成大写
lower转换成小写
length获取字节长度
char_length获取字符长度
substr截取子串
trim去掉前后空格或字符
concat拼接
strcmp比较两个字符串大小(-1,0,1)
instr获取子串第一次出现的索引,如果找不到,返回0;instr(字符串,子串)
注意:sql中起始索引,一般从1开始!
三、日期函数
now当前日期+时间
curdate当前日期
curtime当前时间
datediff两个日期天数差
date_format日期——>字符
str_to_date字符——>日期
四、流程控制函数
1、if函数:if(条件,结果1,结果2):类似于三目运算符
2、case结构
形式1:类似于switch
形式2:类似于多重if
5.聚合函数(分组函数)
本质上就是一种函数,调用语法:select 函数名(实参列表);
函数:
单行函数(常见函数):有几行,最终有几个结果
分组函数(聚合函数):一组中有多行,但最终一个结果,一般用作统计
分组函数:
sum(参数):求和
avg(参数):平均
max(参数):求最大值
min(参数):求最小值
count(参数):统计个数
count(*):回在给定的选择中(当前条件下的表)被选的行数
6.分组查询
语法:
select 查询列表—④
from 表名—①
where 分组前条件—②
group by 分组的字段—③
having 分组后条件—⑤
order by 排序列表—⑥
特点:
1、查询列表往往是:分组函数和分组后的字段
换句话说,和分组函数一同查询的字段,一般就是分组后的字段
2、分组查询的筛选有两种:
分组前筛选和分组后筛选
连接关键字 位置 筛选的结果集
分组前筛选 where group by前面 原始表
分组后筛选 having group by后面 分组后的查询结果(虚拟表)
结论:分组函数做条件 肯定是 分组后筛选条件!!!
3、分组查询可以通过单个字段,也可以通过多个字段,中间用逗号隔开
7.连接查询
理解:查询语句中涉及到的字段来自于多张表,将这种查询称为多表连接查询
语法:select 查询列表 from 表名1,表名2;
引入案例:
select name,boyname from beauty,boys;
select name,boyname from beauty,boys where boyfriend_id
= boys.id
;
笛卡尔乘积:
现象:表1和表2连接,结果为两表的完全连接结果,数据不正确
表1m行,表2 n行,结果为:m*n 行
产生原因:没有有效的连接条件
解决办法:添加两个表的连接条件
★ 找到两个表的关联关系。两个表的关联列的意思肯定是一样,但名称不一定一样!一般通过主外键列进行关联。
★连接查询的分类 :
sql92语法:
内连接:1.等值连接
2.非等值连接
3.自连接
外连接(支持的不太好,MySQLl压根不支持)
sql99语法:
内连接
等值连接
非等值连接
自连接
外连接
左外连接
右外连接
全外连接(mysql不支持)
*/
---------------------------------Sql92语法--------------------------------
#内连接
一、等值连接
语法:
select 查询列表
from 表名1 别名1,表名2 别名2
where 别名1.关联列 = 别名2.关联列
and 筛选条件
group by 分组字段
having 分组后的筛选条件
order by 排序;
特点:
1、多表连接时,一般为表起别名,提高语句的简洁性
a 、别名要短于 表名
b 、一旦为表起了别名,则只能使用别名限定,不能使用表名限定了!
2、表是否可以调换顺序
答案:可以!不分主次表!
3、等值连接查询,查询的结果为两个表的交集部分
4、n表连接,至少需要n-1个连接条件
二、非等值连接
语法:
查询列表
from 表名1 别名1,表名2 别名2
where 非等值的连接条件
and 筛选条件
group by 分组字段
having 分组后的筛选条件
order by 排序;
#三、自连接(同一张表的自我连接)
#案例:查询每个员工的员工名和领导名
SELECT 员工表.last_name,领导表.last_name
FROM employees 员工表,employees 领导表
WHERE 员工表.manager_id
= 领导表.employee_id
;
------------------------SQL99语法--------------------------
#内连接
一、等值连接
语法:
select 查询列表
from 表1 别名
inner join 表2 别名 on 连接条件
inner join 表3 别名 on 连接条件
【where 筛选条件】
【group by 分组】
【having 分组后筛选】
【order by 排序列表】
区别:
①sql99语法,使用join连接,并且通过on添加连接条件,语义性更强!
连接条件和筛选条件进行了分离,提高维护性和分离性!
特点:
1、多表连接时,一般为表起别名,提高语句的简洁性
a 、别名要短于 表名
b 、一旦为表起了别名,则只能使用别名限定,不能使用萍限定了!
2、表是否可以调换顺序
答案:可以!不分主次表!
3、等值连接查询,查询的结果为两个表的交集部分
4、n表连接,至少需要n-1个连接条件
二、非等值连接
三、自连接
#外连接
语法:
select 查询列表
from 表 别名1
left|right|full 【outer】 join 表 别名2 on 别名1.关联列= 别名2.关联列
left|right|full 【outer】 join 表 别名3 on 别名1.关联列= 别名3.关联列
WHERE 筛选条件
GROUP BY 分组
HAVING 分组后条件
ORDER BY 条件;
功能:查询主表中的所有记录,如果从表有和主表匹配的信息,则显示匹配信息。否则显示null
一般适合查询主表中有,但从表中没有的记录
外连接的结果=内连接结果+主表有从表没有的!
特点:
1、左连接 left join,左边的表就是主表
右连接 right join,右边的表就是主表
从一定角度上讲,左连接和右连接可以通过调换两表顺序,最终实现同样的效果!
8.子查询
概念:出现在其他语句内部的select语句,称为子查询或内查询
其他语法:可以是select语句,也可以是create、insert、update等。只是select语句出现的较多
外面如果是select语句,称为主查询或外查询
位置:
子查询可以放在select语句中的select后面、from后面、where或having后面、exists后面
分类:(放在where或having后面)
单行子查询:子查询的结果只有一行
多行子查询:子查询的结果可以有多行
特点:
①子查询一般需要使用小括号括起来,为了提高阅读性
②子查询一般放在条件的右侧
③子查询优先于主查询执行,主查询使用到了子查询的结果
④单行子查询一般搭配单行操作符使用
单行操作符:> < = <> >= <=
多行子查询一般搭配多行操作符使用
多行操作符:in/not in、any、all
一、单行子查询
注意:
单行子查询的结果肯定是一行一列,不能是多行,也不能是空值
#案例:返回公司工资最少的员工的last_name,job_id和salary
SELECT last_name,job_id,salary
FROM employees
WHERE salary = (
SELECT MIN(salary)
FROM employees);
注意:分组函数查询出来是一个值,后面并不能跟查询出来多字段的值
二、多行子查询
in/not in:判断某个字段是否属于子查询结果的某个值
any/some:一般搭配条件运算符使用 【用的较少】
where sal>any(1,2,3,4)
all: 一般搭配条件运算符使用 【用的较少】
where sal > all(1,2,3,4)
#案例:返回其它部门中比job_id为‘IT_PROG’部门任一工资低的员工的员工号、姓名、job_id 以及salary
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary<ANY(SELECT salary
FROM employees
WHERE job_id = 'IT_PROG')
GROUP BY department_id;
9.分页查询
引入:实际的开发时,一页往往显示不全所有数据,则用到了分页查询
语法:
select 查询列表⑥
from 表 ①
join 表 ②
on 连接条件③
where 筛选④
group by 分组⑤
having 分组后筛选⑦
order by 排序列表⑧
limit 【起始条目数,】查询的条目数; ⑨
特点:
起始条目数可以省略,默认从1开始。
注意:此时起始索引从0开始
Web中:
公式:
指定页数page,指定条目数size
select * from employees limit (page-1)*size,size;
size=10
page=1 page=2 page=3
limit 0,10 limit 10,10 limit 20,10
#案例2:查询第11条——第20条的员工信息
SELECT *
FROM employees
LIMIT 10,10;
10.合并查询(联合查询)
引入:一个结果集的查询的数据来自于多张表。但多张表之间没有任何关联关系。
语法:
select 查询列表 from 表1 union
select 查询列表 from 表2 union
…
select 查询列表 from 表n
特点:
①要求实现union的多条查询语句的查询列数必须一致,列名无要求,列的意义无要求,但建议一致!
②union默认实现的是去重查询。如果不想去重,则使用union all
#案例1:查询所有国家的用户信息
SELECT id 编号,cname 姓名,cgender 性别 FROM chinese UNION
SELECT uid,uname,uname,
2.5、DDL
一、库的管理
1.创建库
语法:
create database [if not exists]库名
2.删除库
语法:
drop database[if exists]库名
二、表的管理
1.创建表★
create table [if not exists]表名(
字段名 数据类型 [约束],
字段名 数据类型 [约束],
…
);
2.修改表【了解】
alter table 表名 [change|modify|drop|add] column 字段名 字段类型;
#①修改表名
alter table 表名 rename to 新表名;
#②修改列名
alter table 表名 change column 列名 新列名 新数据类型
#③修改字段类型
alter table 表名 modify column 列名 新数据类型
#④添加新列
alte table 表名 add column 列名 数据类型
3.删除表★
drop table if exists 表名
4.复制表
#①仅仅只是复制了表的结构
create table 新表名 like 表名
#②复制了表的结构+数据
creat table 新表名 select * from 表名;
#③复制了表中的某些列,并不要数据
create table 新表名
select 列名,列名from 表名 where 0;
2.6、DML
Data Manipulation Language数据操纵语言
关键字:insert、update、delete
一、插入(insert)
1.插入单行
insert into 表名(字段名,字段名,字段名…)
values(值1,值2,值3…);
2.插入多行
方式一:
insert into 表名(字段名,字段名,字段名…)
values(值1,值2,值3…),(值1,值2,值3…)…;
方式二:
支持子查询
INSERT INTO stuinfo
SELECT 9,'贾玲','女','1985-1-1',13 UNION ALL
SELECT 10,'袁姗姗','女','1985-1-1',13 UNION ALL
SELECT 11,'宋丹丹','女','1985-1-1',13 UNION ALL
SELECT 12,'李宇春','女','1985-1-1',13
特点:
①要求值和字段的类型、约束一致。(类型可以不完全一致,但一定要兼容)
推荐: 1.数值型不用引号 2.日期型和字符型需要使用单引号
②非空字段必须显式的插入值。
可以为空的字段,可以不用显式的插入值
③字段和值的个数必须一致
④字段列表可以省略,默认是所有字段
补充:设置自增长列
create table studio(
id int primary key auto_increment
);
insert值的时候可以省略这一项,这项从1开始自增。
二、修改(update)
1.单表修改
update 表名 set 字段名 = 新值,字段名=新值 where 条件
2.多表修改
#案例1:修改专业名是html的学员的座位号 =10,专业名改为网页
#sql92
UPDATE stuinfo s,major m
SET s.seat = 10,m.majorname
=‘网页’
WHERE s.majorid
=m.id
AND m.majorname
=‘html’;
#sql99【推荐】
UPDATE stuinfo s
JOIN major m ON s.majorid
=m.id
SET s.seat = 1,m.majorname
=‘BigData’
WHERE m.majorname
=‘大数据’;
三、删除(delete)
方式一:使用delete
语法:
单表删除:★
delete from 表 where 条件;
多表级联删除:【了解】
sql92:
delete 表1,表2 from 表1 别名,表2 别名 where 连接条件 and 筛选条件;
sql99:思考
方式二:使用truncate
语法:truncate table 表
#【面试题】delete和truncate的对比
1.delete可以添加where条件
truncate不可以添加where条件
2.truncate效率较高
3.delete删除后,返回受影响的行数
truncate删除后,没有返回受影响的行数
4.delete删除带自增长列的表,再插入时,自增长列的值从断点处开始新增
truncate删除带自增长列的表,再插入时,自增长列的值从1开始新增
5.delete支持事务的回滚
truncate不支持事务的回滚
6.delete属于DML,truncate属于DDL
2.7、事务
理解:一组具有一定特点的sql语句,称为事务
主要特点:要么全部执行,要么全部不执行
一组sql语句包含1条或多条
ACID四大特性:
A原子性:一个事务不可再分割,要不全部执行,要不全部失败
C一致性:一个事务执行后,将数据从一种状态切换到另一种状态。保证数据是准确。
I隔离性:一个事务的执行,不应该受其他事务的影响
D持久性:一个事务的执行,将持久化到硬盘
事务分类:
1.隐式事务
事务没有明显的开启和结束的标记
比如:一条update、一条delete、一条insert语句
2.显式事务
事务具有明显的开启和结束的标记
步骤1:开启事务
取消DML语句自动提交功能
set autocommit = 0;
start transaction;
步骤2:编写事务的sql语句
update account set balance = 5000 where username = '赵丽颖';
update account set balance = 15000 where username = '冯绍峰';
步骤3:结束事务
提交:
commit;
回滚:
rollback;
Tips: 事务的语句只支持insert、update、delete、select。
案例:赵丽颖给冯绍峰转5000块
update account set balance = 5000 where username = '赵丽颖';
update account set balance = 15000 where username = '冯绍峰';
*/
SHOW VARIABLES LIKE ‘auto%’
#步骤1:开启事务
#取消DML语句自动提交功能
SET autocommit = 0;
START TRANSACTION;
#步骤2:编写事务的sql语句
UPDATE account SET balance = 5000 WHERE username = '赵丽颖';
UPDATE account SET balance = 15000 WHERE username = '冯绍峰';
#步骤3:结束事务
#提交:
#commit;
--------------------或者---------------------
#回滚:
ROLLBACK;
#演示delete和truncate是否支持事务回滚
#演示delete
SET autocommit=0;
START TRANSACTION;
DELETE FROM account;
ROLLBACK;
#演示truncate
SET autocommit=0;
START TRANSACTION;
TRUNCATE TABLE account;
ROLLBACK;