一.什么是MySQL
问题1:之前在Java中有数组、集合等容器来装数据,为什么还要数据库?
因为数组、集合等容器存储的数据是在内存中,内存中的数据一旦断电或程序退出,数据就没有了,无法永久保存。
1.使用数据库的目的之一,为了持久化(永久保存)。、
2.内存容量有限,硬盘容量近乎无限
3.数据生命周期和程序解耦
4.数据库能解决数组 / 集合搞不定的「数据管理问题」
4.1支持多程序 / 多用户共享数据
4.2提供高效的查询能力(索引)
4.3支持事务,保证数据安全性
4.4支持数据约束,保证数据合法性
4.5支持并发操作,解决线程安全问题
问题2:之前在Java中有FileOutputStream、FileWriter、ObjectOutputStream等可以把数据写到文件中,实现持久化,为什么不直接用它们,还要用数据库呢?
这些IO流可以实现数据的存储,但是后期的数据管理(检索、修改、删除等)不方便,效率低。
所以,使用数据库的目的之二,为了方便管理数据,高效实现增、删、改、查、备份、安全的管理等。而文件存储只是「原始字节 / 字符的持久化」,只是把数据扔到硬盘文件里,没有任何管理能力。
二.什么是关系数据库
1. 核心概念:表、行、列
关系数据库把数据存储在二维表中,结构和你在 Excel 里看到的表格非常像:
- 表(Table):一个表对应一个实体(比如用户表 user、订单表 order),是数据的容器。
- 行(Row):表中的每一行代表一条具体的数据记录(比如一个用户的信息)。
- 列(Column):表中的每一列代表一个数据属性(比如用户的 id、name、phone),每个列都有固定的数据类型(比如整数、字符串、日期)。
2. 核心特性:关系与约束
关系数据库的 “关系” 体现在不同表之间可以通过 “键(Key)” 建立关联,同时通过约束保证数据的正确性:
- 主键(Primary Key):每个表必须有一个唯一标识行的列(比如用户表的 user_id),确保每条记录唯一。
- 外键(Foreign Key):一个表中的列引用另一个表的主键(比如订单表的 user_id 引用用户表的 user_id),用来表示 “订单属于某个用户” 这种关联关系。
- 约束(Constraint):通过唯一约束、非空约束、外键约束等,从底层保证数据的合法性(比如手机号不能重复、订单必须关联一个存在的用户)。
3. 核心操作:SQL
关系数据库使用 SQL(Structured Query Language) 来进行所有操作,包括:
- 增(Insert):插入新数据
- 删(Delete):删除数据
- 改(Update):修改数据
- 查(Select):查询数据,支持多表关联、复杂条件筛选、排序、分组等
三.基本语法
3.1登录连接MySQL服务器的命令
-
-h:主机地址,后面写主机名或IP地址
-
-P(大写):端口号,默认是3306
-
-u:用户名,默认的超级管理员用户名是root
-
-p(小写):密码
3.2SQL操作数据库
3.2.0SQL语法说明
一般默认为ci不区分大小写。(show create table student 查看表的属性)
3.2.1 show databases
3.2.2 创建自己的数据库
3.2.3使用数据库
3.2.4创建表
3.2.5添加数据
3.2.6查看表中的数据
四.数据类型
4.1整数类型
4.1.1整数类型的图片整理一览
4.1.2一个查询code
/*
DataBase中整数类型有:
1.TINYINT 1byte
2.SMALLINT 2byte
3.MEDIUMINT 3byte
4.INT 4byte
int(num) : 不影响数的取值
UNSIGNED : 关键字表示无符号数,关键字一般大写
ZEROFILL : 零填充
*/
create table test1(a tinyint, b int, c int(3), d int(3) unsigned,e int(3) unsigned zerofill);
-- insert into test1 values(200,200,200,200,200); # 错误
insert into test1 values(100,200,200,200,200);
insert into test1 values(1,2,2,2,2);
insert into test1 values(1,20000,20000,20000,20000);
/*insert into test1 values(-1,-20000,-20000,-20000,-20000); # 错误 后面2个不支持负数
insert into test1 values(-1,-20000,-20000,20000,-20000); # 错误 后面2个不支持负数*/
select * from test1;
4.1.3现在int(num)很少用了,只有配合zerofill才有用
只有当你同时使用 ZEROFILL 时,int(3) 才会体现出效果:
4.1.4如果我往无符号数中插入负数呢
4.2小数类型
-
如果decimal没有指定精度要求,默认是取整数。float大约是6-7位,double大约是15-16位。
-
float(M,D),double(M,D),decimal(M,D),如果指定了(M,D),表示整数+小数最多M位,小数点后面是D位。
-
float和double是浮点型,误差要大一些。decimal是定点型,精确度要高一些。
4.2.1如果不给decimal指定M,D那么默认为整形
4.2.2如果超过范围怎么办
4.2.2.1如果是整数位超过了 -- 报错
4.2.2.2如果是小数位超过了 -- 第D+1位四舍五入
4.2.3谁精度高
4.2.4code
/* Java中的小数类型:float double BigDecimal
MySQL中的小数类型 : float,double,decimal
* BigDecimal bd = new BigDecimal("number");
*
* BigDecimal方法:
* 1. add(BigDecimal val) //加
* 2. subtract(BigDecimal val) //减
* 3. multiply(BigDecimal val) //乘
* 4. divide(BigDecimal val) //除
* 4.1除不尽时,会报异常
* .divide(BigDecimal val, int scale, int roundingMode)
* 4.2 roungdingMode的类型
* 1.CEILING //向上取整
* 2.FLOOR //向下取整
* 3.HALF_UP //四舍五入
* 4.HALF_EVEN //偶数就进位,一半概率
* 5. remainder(BigDecimal val) //求余数
*
BigDecimal bd = new BigDecimal("898877415.6023154060879859845612358874056123877989564132564894");
BigDecimal bd2 = new BigDecimal("8568498465321564898765321648994");
System.out.println(bd.add(bd2));
*/
create table t2(a float,b double,c decimal);
insert into t2 values(3.14,3.14,3.14);
SELECT * from t2;
create table t3(a float(5,2),b double(5,2),c decimal(5,2));
-- M : 代表整数加小数一共几位
-- D : 代表小数点后最多几位,如果超过了,小数点的数据会省略掉
-- 这里(5,2)表示,整数加小数最多5位,小数点后最多两位,如果超过了,小数点的数据会省略掉
SELECT * from t3;
4.3日期时间类型
4.3.1日期之间用- 时间之间用:
4.3.2除了年份year,其余的当字符串输入,要加''
4.3.3DATETIME和TIMESTAMP的区别 - timestamp可以根据时区调整时间值
eg:设置位东9区
eg:设置为东10区
4.4字符串类型
4.4.1MySQL字符串分类
4.4.1.1.文本字符串
普通文本,例如:用户名,地址,字符串等等信息。
1) 文本字符串类型一览
2) CHAR & VARCHAR
2).1 和java的对应关系
2).2 区别
char是定长字符串,varchar是变长字符串
2).3 什么时候用谁?
2).4 VARCHAR必须指定(M) -- 不然报错
3) TEXT
4) ENUM 枚举类型
4) .1 枚举是单选,集合可以多选
eg1:选单个爱好
eg2:选多个爱好
4).2 通过数字索引来找到枚举项和集合项
#set 输入1对应第一个,输入2对应第二个,输入3对应前2个,输入4对应第三个,输入7对应前三个,......。即element的index为2^n-1,要找前多少个就是:∑(2^n-1)
4.4.1.2.二进制字符串
存二进制的字符串,例如:一般用于存储二维码,图片等等。
二进制字符串类型一览
五.运算符
5.1算术运算符
5.1.1select直接查看算术运算的结果
5.1.2查看员工姓名,原薪资,和如果涨薪水1000的结果
5.1.3用\整数除整数得到的是小数,用div得到的是整数
5.1.4MySQL中+无法对字符串拼接,concat是字符串的拼接
5.2比较或关系运算符
5.2.1 = 是否相等
5.2.1.1 = -查看两个数值是否相等
5.2.1.2 = -查询叫陈浩的人的员工
5.2.2 > 大于
5.2.2.1 > -查询薪资大于15000的员工
5.2.3 != <> 不等于
5.2.3.1 <> != -查询部门id不是1的员工信息
5.2.4 between and
5.2.4.1 between and -查询薪资区间在10000~15000的员工
5.2.5 in
5.2.5.1 in-查询韩庚年、陈浩、陆风、贾宝玉这几个人的信息
5.2.6 like
5.2.6.1 like-查询姓名中包含'冰'这个字,不清楚这个字是名字中的第几个字
5.2.6.2 like-查询姓名中包含'冰'这个字,且它是第3个字
5.2.6.3 like-查询姓名中包含'冰'这个字,且它是第2个字
code:
/*
比较或关系运算符
Java中比较或关系运算符:>,<,>=,<=,==,!=
MySQL中比较或关系运算符:>,<,>=,<=,=, !=,<>,
is , is not(针对NULL值判断)
between x and y (用于区间范围的判断)或 not between x and y
in (值列表) 和not in(值列表) 集合元素的判断
like 配合 %和_实现模糊查询
结果0代表false
1(非0)代表true
*/
#查看1=2吗
select 1=2;
#查看1=1吗
select 1=1;
#查询姓名为陈浩的员工信息
select * from t_employee where ename == '陈浩'; # 错误,没有==
select * from t_employee where ename = '陈浩';
#查询薪资大于15000的员工信息
select * from t_employee where salary > 15000;
#查询部门编号不是1的员工
select * from t_employee where did != 1;
select * from t_employee where did <> 1;
#对于null值的判断不能使用=和!=
#查询奖金比例 commission_pct 不为NULL
select * from t_employee where commission_pct != null; # 错误
select * from t_employee where commission_pct is not null;
#查询奖金比例 commission_pct 为NULL
select * from t_employee where commission_pct = null; #错误
select * from t_employee where commission_pct is null;
#查询薪资在[10000, 15000]之间
select * from t_employee where salary between 10000 and 15000;
#查询韩庚年、陈浩、陆风、贾宝玉这几个人的信息
select * from t_employee where ename in('韩庚年','陈浩','陆风','贾宝玉');
#查询姓名中包含'冰'这个字,不清楚这个字是名字中的第几个字
select * from t_employee where ename = '冰'; #表示名字只有1个字,且是'冰'
select * from t_employee where ename like '冰'; # ename like '冰'等价于ename = '冰'
select * from t_employee where ename like '%冰%';
#查询姓名中包含'冰'这个字,且它是第3个字
select * from t_employee where ename like '__冰';
#查询姓名中包含'冰'这个字,且它是第2个字
select * from t_employee where ename like '_冰_';
5.3逻辑运算符
5.3.1与 && AND
5.3.2或 || OR
5.3.3非 ! NOT
5.3.4异或(二者满足一个) NOR
六.函数
6.1函数的分类:
6.1.1系统预定义的函数
(1)多行函数:多行合并起来一起计算,结果行数会减少
核心:对表中「每一行的单个字段」单独处理,输入一行、输出一行,最终结果的行数和原始表完全一致。
(2)单行函数:每一行独立计算,结果行数不变
核心:把「多行的同一个字段」合并成一组计算,输入多行、输出一行,最终结果行数远少于原始表。
eg:查询最高薪资
6.1.2用户自定义的函数
6.2函数
6.2.1分组函数
group by按什么分组
6.2.2多行函数
count函数都是多行聚合函数,会把表中多行数据合并统计,最终只返回 1 行结果(统计的行数)。
6.2.3单行函数
6.2.3.1数学函数
6.2.3.1.1 ceiling 向上取整
6.2.3.1.2 floor 向下取整
6.2.3.1.3 round(x,y) 对x取y位,对y+1位进行四舍五入
查询平均工资,保留两位四舍五入
6.2.3.1.4 format(x,y)对x取小数点后y位对y+1位直接截掉
6.2.3.1.5 truncate(x,y)对x取小数点后y位对y+1位直接截掉
6.2.3.2 字符串处理函数
6.2.3.2.1 拼接字符串
6.2.3.2.2 求字符串的长度
6.2.3.2.3求sub字符在字符串中的位置
6.2.3.2.4 求字符串左边/右边的多长的字符
6.2.3.2.5 去掉字符串的前/后/前后空格/字符串S
6.2.3.2.6 字符串比较函数
6.2.3.2.7 字符串截取
截取从index开始多长的字符串字符串
截取第二个',' 符号前的2个单词
截取倒数第二个',' 符号后2个单词
6.2.3.3 时间函数
6.2.3.3.1 day(),month()提取date的日,月部分。而year是数据类型!
6.2.3.3.2获取当前日期/时间/日期时间
查询本月过生日的员工
6.2.3.4 加密函数
6.2.3.4 条件判断函数
6.2.3.4.1 if 相当于Java的三元运算符
6.2.3.4.2 ifnull
6.2.3.4.3 case when 和case exprEqual when then
示例 1:等值判断式 CASE
适用于 “字段等于固定值” 的场景。sqlSELECTb_name,note,CASE noteWHEN 'novel' THEN ' 小说 'WHEN 'law' THEN ' 法律 'ELSE ' 其他类型 'END AS 类型FROM books;
- 这里 note 是 expr,它会和 'novel'、'law' 做等值比较。
- 它等价于 CASE WHEN note = 'novel' THEN '小说' WHEN note = 'law' THEN '法律' ...,只是写法更简洁。
示例 2:条件判断式 CASE
适用于 “字段满足范围 / 复杂条件” 的场景。sqlSELECTb_name,num,CASEWHEN num >= 30 THEN ' 滞销 'WHEN num > 0 AND num < 10 THEN ' 畅销 'WHEN num = 0 THEN ' 无货 'ELSE ' 正常 'END AS 库存FROM books;
- 这里没有 CASE 后的 expr,直接判断 num >= 30 这类布尔条件。
- 支持 >、<、AND、OR、LIKE 等复杂逻辑,是处理范围、多条件的唯一选择。
七.一些其他关键字
7.1 as - 起别名(as可以省略)
不起别名的结果:
7.2 group by按什么分组
八.SQL语句
8.1SQL分类
SQL是操作关系型数据库的标准的语言。SQL语句根据功能的不同通常会分为如下几种:
-
操作库和表结构的语句,称为DDL语句。数据定义语句(Data Define Language),例如:创建(create),修改(alter),删除(drop)等
-
操作表中的数据的语句,称为DML语句(Data Manipulation Language 的缩写)。数据操作语句,例如:增(insert),删(delete),改(update),查(select)
-
控制权限的语句,称为DCL语句,数据控制语句,例如:grant,revoke等
-
TCL语句:事务控制语句,例如:commit,rollback等
-
其他语句:USE语句,SHOW语句,SET语句等。这类的官方文档中一般称为命令。
8.2 insert 添加语句
8.3 update 修改表的元素
8.4 delete删除
8.4.1 delete和truncate的区别:
(1)delete清空表是逐行删除数据,当数量量比较大的时,相对较慢。
truncate截断表是把整个表drop掉,然后建一张新的,相对快。
(2)delete清空表是支持事务,可以回滚撤销。
truncate截断表不支持事务,无法回滚撤销。
8.5关联查询
8.5.1 内连接 INNER JOIN
8.5.2 左外连接/左连接
8.5.3右外连接/右连接
8.5.4 全外连接