MySQL
关系型数据库:(SQL)
-
MySQL,Oracle,SQL serve,SQLlite
-
通过表和表之间,行和列之间的关系进行数据的储存
非关系数据库:(NoSQL NO是not only的意思)
- Redis,MongDB
- 对象存储,通过对象的自身属性
DBMS:数据库管理系统 ,用于管理数据库的软件,维护,获取数据。
MYSQL官网下载,安装,配置环境变量,配置文件my.ini,下载可视化编辑软件
SQLyog,这些都可以在网上找到。
数据库的连接
命令行连接
mysql -u root -p --连接数据库
flush privileges; --刷新权限
create database school --创建数据库school
CREATE TABLE `school`.`student` ( `id` INT(10) NOT NULL AUTO_INCREMENT COMMENT '学生ID', `name` VARCHAR(100) NOT NULL COMMENT '学生姓名', `age` INT(3) NOT NULL COMMENT '学院年龄', PRIMARY KEY (`id`) ) ENGINE=INNODB CHARSET=utf8 COLLATE=utf8_general_ci; --创建student表
show database; --查看所有数据库
use school --切换数据库use+数据库名
show tables; --查看数据库中的所有表
describe student; --describe+表名可查看表的信息如数据类型,大小等等
exit; --退出连接
--,#单行注释
/*
多行数据
*/
数据库xxx语言(CRUD)
DDL 定义
DML 操作
DQL 查询
DCL 控制
操作数据库
操作数据库>操作数据库中的表>操作数据库中的表中的数据
mysql关键字不区分大小写,在java里一般都小写
CREATE DATABASE IF NOT EXISTS westos; --创建数据库westos
DROP DATABASE IF EXISTS hellol; --删除数据库hello
use school; --使用数据库school 如果表名或字段名是一个特殊字符就需要带 `` 符号
show database; --查看所有数据库
数据库的列类型
数值
- tinyint 很小的数据 1字节
- smallint 较小的数据 2字节
- mediumint 中等大小的数据 3字节
- int 标准的整数 4字节 常用
- bigint 较大的数据 8字节
- flaot 浮点数 4字节
- double 浮点数 8字节
- decimal 字符串形式的浮点数 8字节(精度问题)
字符串
- char 固定大小的字符串 0~255
- varchar 可变字符串 0~65535 常用的变量 String
- tinytext 微型文本 2^8-1
- text 文本串 2^16-1 保存大文本
时间日期
- data YYYY-MM-DD 日期格式
- time HH:mm:ss 时间格式
- datetime YYYY-MM-DD HH:mm:ss 最常用的时间格式
- timestamp 时间戳 1970.1.1到现在的毫秒数 也比较常用
null
没有值,未知,注意:不要使用NULL进行运算,结果为NULL
数据库字段属性
- unsigned 无符号整数 声明该列不能为负数
- zerofill 0填充 不足的位数用0来填充 比如int(3)类型的5在数据库中是005
- 自增 在上一条记录的基础上+1,通常用在主键上,可以自定义主键的起始值和步长
- 非空 null not null 设置为not null的话,不赋值会报错,而设置为null时,不赋值则默认为null
拓展:做项目时建议每一个表都必须存在以下五个字段
- id 主键
version
乐观锁- is_delete 伪删除
- gmt_create 创建时间
- gmt_update 修改时间
创建表
--注意:使用英文标点,表的名称 和 字段 尽量使用 ` `括起来
CREATE TABLE IF NOT EXISTS `teacher`(
`id` INT(3) NOT NULL AUTO_INCREMENT COMMENT '学号',
`name` VARCHAR(30) NOT NULL DEFAULT '匿名' COMMENT '姓名',
`pwd` VARCHAR(20) NOT NULL DEFAULT '123456' COMMENT '密码',
`sex` VARCHAR(2) NOT NULL DEFAULT '男' COMMENT '姓名',
`birthday` DATETIME DEFAULT NULL COMMENT '出生日期',
`address` VARCHAR(100) DEFAULT NULL COMMENT '家庭住址',
`email` VARCHAR(50) DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY(`id`)
)ENGINE = INNODB DEFAULT CHARSET = utf8
show create database school --查看创建数据库的语句
show create table student --查看student数据表的定义语句
-- COMMENT 注释,ENGINE引擎 ,CHARSET字符集
关于数据库的引擎
INNODB 默认使用
MYISAM 早期使用的
MYISAM | INNODB | |
---|---|---|
事务支持 | 不支持 | 支持 |
数据行锁定 | 不支持 | 支持 |
外键约束 | 不支持 | 支持 |
全文索引 | 支持 | 不支持 |
表空间大小 | 较小 | 较大,约为2倍 |
常规使用操作:
MYISAM 节约空间,速度较快
INNODB 安全性高,事务的处理,多表多用户操作
设置数据库的字符集编码
CHARSET = utf8
不设置的话,默认是一个不支持中文的字符集编码
修改和删除表
-- 重命名:ALTER TABLE 旧表名 RENAME AS 新表名
ALTER TABLE teacher RENAME AS teacher1
-- 添加字段:ALTER TABLE 表名 ADD 字段名 列属性
ALTER TABLE teacher ADD age INT(3)
-- 修改表的字段 (重命名,修改约束)
-- ALTER TABLE 表名 MODIFY 字段名 属性
ALTER TABLE 表名 MODIFY age VARCHAR(11) -- 修改约束
-- ALTER TABLE teacher CHANGE 旧字段名 新字段名 I新属性
ALTER TABLE teacher CHANGE age age1 INT(3) -- 重命名
-- 删除表的字段: ALTER TABLE 表名 drop 字段名
ALTER TABLE teacher DROP age1
--删除表 drop table if exists 表名
drop table if exists teacher
MySQL数据管理
外键(了解即可)
-- 样例
key `FK_gradeid` ('gradeid')
constraint `FK_gradeid` foreign key (`gradeid`) reference `grade` (`gradeid`)
--创建表的时候没有外键关系要添加alter table 表名 add constrant 约束名 foreign key (作为外键的列) references 参考的表名(那个字段)
alter table `teacher` add constrant `FK_gradeid` foreign key (`gradeid`) references `grede`(`gredeid`)
以上操作都是物理外键,不建议使用,避免数据库造成过多困扰,
最佳时间:数据库就是单纯的表,用逻辑外键来实现,不用物理外键
DML语言(要熟记)
添加
-- 插入语句
INSERT INTO 表名 ({字段名1,字段名2,字段名3...}) VALUES (值1,值2,值3...)
--插入多个值
INSERT INTO 表名(属性名) values (值1),(值2)
修改
update 表名 set column_name = value where [条件] --(where后在哪里改),不加where即不指定条件的情况下,会改动所有的表
删除
DELETE FROM 表名 [WHERE 条件]
-- TRUNCATE命令会完全清空一个数据库表,表的结构和索引约束不会变
TRUNCATE 表名
delete 和 truncate区别
- 相同点:都能删除数据,都不会删除结构
- 不同:
- TRUNCATE重新设置自增列,计数器会归零
- TRUNCATE不会影响事务
DQL 数据查询语言
-- 查询指定字段
SELECT * FROM 表; --查询所有字段
SELECT 字段 FROM 表; --查询指定字段
--e.g
SELECT * FROM student
SELECT `studentno`,`studentname` FROM student
-- 别名,给结果起一个别名,可以给字段起别名,表也可以起别名
SELECT `studentno` AS `学号`,`studentname` AS `姓名` FROM student AS s;
-- CONCAT(a,b) 连接函数
SELECT CONCAT('姓名:',studentname) AS `新名字` FROM student;
-- 去重 DISTINCT,去除SELECT查询结果中重复的数据
SELECT DISTINCT `studentno` FROM student
SELECT VERSION() -- 查询系统版本(函数)
SELECT 100*3-1 AS 计算结果 --计算结果(表达式)
SELECT @@auto_increment_increment -- 查询自增步长(变量)
-- 学生成绩+1分后查看
SELECT `studentno`,`studentresult`+1 AS `提分后` FROM result;
Where条件字句
作用:检索数据中符合条件的值
运算符 | 语法 | 描述 |
---|---|---|
and && | a and b a&&b | 同真为真 |
or || | a or b a||b | 同假为假 |
Not ! | not a !a | 真假互换 |
-- 查询考试成绩在95~100分之间 AND可以用&&替换
SELECT studentNo, StudentResult FROM result WHERE StudentResult>=95 AND StudentResult<=100;
SELECT studentNo, StudentResult FROM result WHERE StudentResult>=95 && StudentResult<=100;
SELECT studentNo, StudentResult FROM result WHERE StudentResult BETWEEN 95 AND 100;
-- 除了1000号学生之外的同学的成绩
SELECT `studentNo`, `StudentResult` FROM result WHERE studentNo!=1000;
-- ! = not
SELECT studentNo, `StudentResult` FROM result WHERE NOT studentNo = 1000
模糊查询:比较运算符
运算符 | 语法 | 描述 |
---|---|---|
IS NULL | a is null | 若a为null,则为真 |
IS NOT NULL | a is not null | 若a不为null,则为真 |
BETWEEN | a between b and c | 若a在b和c之间,则为真 |
LIKE | a like b | SQL匹配,如果a匹配b则为真 |
IN | a in (a1,a2,a3,a4) | 若a在a1,a2,a3…中的一个,则为真 |
-- 查询姓刘的同学
-- like结合 %(代表0到任意个字符) _(一个字符)
SELECT`StudentNo`,`StudentName` FROM `student`HERE StudentName LIKE'刘%'
--查询姓刘的同学,名字后面只有一个字的
SELECT `StudentNo`, `StudentName` FROM `student`WHERE StudentName LIKE '刘_'
--查询名字中间有嘉字的同学%嘉%
SELECT `StudentNo`, `StudentName` FROM`student` WHERE StudentName LIKE '%嘉%'
-- 查询1001,1002,1003号学员
SELECT `StudentNo`,`StudentName` FROM `student` WHERE StudentNo IN(1001,1002,1003);
联表查询
图片是网上的
-- 联表查询 思路:分析需求,分析查询的字段来自哪些表,确定使用哪种连接查询[7种可选],确定交叉点(外键)
-- INNER JOIN 例如:查询参加了考试的同学(学号,姓名,科目编号,分数)
SELECT s.studentNO,studentName,SubjectNo,StudentResult
FROM student AS s
INNER JOIN result r
WHERE s.studentNo = r.studentNO
SELECT s.studentNO,studentName,SubjectNo,StudentResult
FROM student AS s
INNER JOIN result r
ON s.studentNo = r.studentNO
数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。在使用left jion时,on和where条件的区别如下:
- on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。
- where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。
自连接
--查询商品采购表(id,name,goods_name,price)采购价格比 A 高的所有信息
SELECT b.*
from shopping as a,shopping as b
where a.name='A'
and a.price<b.price
order by b.id
分页和排序
-- 分页 limit 和 排序 order by
-- 排序: 升序是ASC 降序是DESC
-- 分页: 语法 limit 起始页,页面大小
-- 假如显示第二页,页面大小为2的SQL语句为limit 2,2
-- 第N页: limit (n-1)*pageSize,pageSize
-- 例如:查询参加了考试的同学(学号,姓名,科目编号,分数),按学生成绩,降序排序
SELECT s.studentNO,studentName,SubjectNo,StudentResult
FROM student AS s
INNER JOIN result r
ON s.studentNo = r.studentNO
ORDER BY studentResult DESC
LIMIT 2,2
-- 为什么要分页? 可以缓解数据库压力,用户体验更好,也有瀑布流(类似抖音
刷短视频一样可以无限刷)
子查询(嵌套查询)
-- 查询 数据库 结构科目所有考试结果(学号 科目名 成绩)降序排列
-- 方式一:使用联表查询
SELECT StudentNo, r.SubjectName,SubjectResult
FROM result r
INNER JOIN `subject` sub
ON r.SubjectNo=sub.SubjectNo
WHERE subjectName='数据库结构'
ORDER BY SubjectResult DESC;
-- 方式二:使用子查询()
--注意子查询结果必须是一行,否则报错Subquery returns more than 1 row
--解决方法:limit 1
SELECT StudentNo, r.SubjectName,SubjectResult
FROM result r
WHERE subjectNo=(
-- 查询结果为 数据库 对应的编号
SELECT SubjectNo FROM `subject`
WHERE subjectName ='数据库结构-1';
)
ORDER BY SubjectResult DESC;
分组和过滤
-- 查询不同科目的平均分最高分和最低分 平均分大于80
-- 由于按照顺序执行,所以where不能限定分组后计算出的平均值等信息,可以使用having来过滤
SELECT SubjectName,AVG(StudentResult),MAX(StudentResult),MIN(StudentResult)
FROM result r
INNER JOIN `subject` sub
ON r.SubjectNo=sub.SubjectNo
GROUP BY r.SubjectNo
HAVING AVG(StudentResult)>=80;
常用函数
-- 数学运算 0和非数字返回0 null返回null
ABS(-10);-- 绝对值
CEIL(10.1);-- ceil和ceiling 向上取整
FLOOR(10.1);-- 向下取整
RAND();-- 返回0-1随机数
SIGN(NULL);-- 返回参数的符号 负数返回-1 正数返回1
-- 字符串函数
CHAR_LENGTH('fwebw');-- 返回字符串长度
CONCAT('1','2','3');-- 拼接字符串
INSERT('123456',1,3,'0');-- 先把第一个字符串的第1位起的0个字符去除
-- 然后再把第二个字符串插入到对应位置
LOWER('JKKKKi');-- 转小写字母
UPPER('wwsfsdf');-- 转大写字母
INSTR('faesfFSFS','FS');-- 返回第一个字串出现的位置
SUBSTR('123456789',2,4);-- 截取字符串,从第2个字符开始截取4个字符
REVERSE('123465');-- 翻转字符串
REPLACE('123456789123','123','hhh');-- 把s1中s2部分替换为s3(所有s2)
-- 例如:查询姓周的同学并把姓换为邹
SELECT REPLACE(studentName,'周','邹') FROM students
WHERE studentName LIKE '周%';
-- 时间和日期函数
CURRENT_DATE();-- 获取当前日期
CURDATE()-- 获取当前日期
CURRENT_TIME();-- 获取当前时间(时分秒)
SYSDATE();-- 获取系统时间
NOW();-- 获取时间
YEAR(NOW());-- 获取当前年
MONTH(NOW());-- 获取当前月
-- 获取日时分秒同理
-- 系统
SYSTEM_USER();
USER();-- 获取当前用户
VERSION(); -- 获取当前版本信息
聚合函数
COUNT();--计数
SUM();--求和
AVG();--均值
MAX();--最大值
MIN();--最小值
--例如: count 查询数据条数,若有主键 使用主键查效率高
SELECT COUNT(studentname) FROM students;-- 会忽略所有null值
MD5(不可逆)
MD5是不可逆的,即通过加密后的密文是不能够计算出加密前的明文的,但是,因为算法固定,相同明文的MD5秘文是相同的。因此,简单明文的MD5密文可以通过穷举暴力破解。
CREATE TABLE `testmd5`(
`id` INT(10) NOT NULL,
`name` VARCHAR(20) NOT NULL,
`pwd` VARCHAR(50) NOT NULL,
PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;
-- 明文密码
INSERT INTO testmd5 VALUES(1,'张三','123456'),(2,'李四','123456'),(3,'王五','123456');
-- md5密码
UPDATE testmd5 SET pwd=MD5(pwd);
-- 插入时加密
INSERT INTO testmd5 VALUES(4,'hhh',MD5('qwerty'));
-- 验证 由于不可逆,可以把用户提交的密码进行md5运算后和库中比对
SELECT MD5('qwerty')=pwd FROM testmd5 WHERE id=4;-- 1
SELECT MD5('qwe')=pwd FROM testmd5 WHERE id=4;-- 0
事务
一组SQL语句,要么都成功,要么都不成功
事务原则:ACID原则 原子性,一致性,隔离性,持久性
事务的隔离级别:
脏读:指一个事务读取了另外一个事务未提交的数据。
不可重复读:在一个事务内读取表中的某一行数据,多次读取结果不同。
虚读(幻读):是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。
四种隔离级别设置
set transaction isolation level 设置事务隔离级别
select @@tx_isolation 查询当前事务隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL read uncommitted;
SET SESSION TRANSACTION ISOLATION LEVEL read committed;
SET SESSION TRANSACTION ISOLATION LEVEL repeatable read;
SET SESSION TRANSACTION ISOLATION LEVEL serializable;
--或者
set tx_isolation = '隔离级别名称'
设置 | 描述 |
---|---|
Serializable | (串行化)可避免脏读、不可重复读、虚读情况的发生。 |
Repeatable read | (可重复读)可避免脏读、不可重复读情况的发生。 |
Read committed | (读已提交)可避免脏读情况发生。 |
Read uncommitted | (读未提交) 最低级别,以上情况均无法保证。 |