JavaEE: 企业级Java开发 Web
前端:页面展示,数据
后台: 连接数据库JDBC,连接前端(控制视图跳转、给前端传递数据)
数据库: 存数据
数据库(DB,database)
概念:数据仓库,软件,安装在操作系统(window、Linux、mac…)之上。SQL可以存储大量的数据
作用: 存储数据,管理数据
关系型数据库: (SQL)
非关系型数据库: (NoSQL) Not Only
数据库管理系统(DBMS)
MySQL,关系型数据库管理系统
前世: 瑞典MySQL AB公司
今生: Oracle旗下产品
体积小、速度快、总体拥有成本低、招人成本低
中小型网站、或大型网站集群
官网: https://www.mysql.com
安装建议:
教程: https://www.cnblogs.com/winton-nfs/p/11524007.html
为了更好地学习MySQL语句,本次学习将使用SQLyog软件,若想要更方便快捷的软件,则可以使用Navicat Premium 15等可视化软件
mysql -uroot -p123456 --连接数据库
update mysql.user. set authentication_string=password('123456') where user='root' and Host='localhost'; --修改用户密码
flush privileges; --刷新权限
--所有语句都使用“;”结尾
show databases; --查看所有的数据库
mysql> use school -- 切换数据库 use 数据库名
Database changed
show tables; --查看数据库中所有的表
describe student; -- 显示数据库中所有表的信息
create database westos; -- 创建一个数据库
exit; -- 退出连接
-- 单行注释(sql本来的注释)
/* 多行注释
hello
world
*/
数据库 xxx语言 CRUD增删改查 CV程序猿 API程序猿 CRUD程序猿(业务)
DDL 定义、DML 操作、DQL 查询、DCL 控制
数据库---->表---->数据
mysql关键字不区分大小写
创建数据库
`CREATE DATABASE [IF NOT EXISTS] sqldemo2`
删除数据库
DROP DATABASE [IF EXISTS] sqldemo2
使用数据库
-- tab键上面的键,若表名或字段名是一个特殊字符,则需要使用 ``
--USE `sqldemo`
USE sqldemo
查看数据库
-- 查看所有数据库
SHOW DATABASES
学习思路:
数值
tinyint 十分小的数据 1字节
smallint 较小的数据 2字节
mediumint 中等大小的数据 3字节
int 标准的整数 4字节 常用
bigint 较大的数据 8字节
float 浮点数 4字节
double 浮点数 8字节
decimal 字符串形式的浮点数 金融计算时使用
字符串
char 字符串固定大小的 0-255
varchar 可变字符串 0-65535 常用 String
tinytext 微型文本 2^8 -1
text 文本串 2^16-1
时间日期
java.util.Date
null
Unsigned
zerofill
自增
非空 null not null
-- 创建一个学生表(列、字段) 使用sql创建
-- 学号int 密码varchar(20) 姓名、性别varchar(2) 出生年月(datatime) 家庭住址 email
-- 注意! 使用英文的() 表的名称和字段尽量使用``来包含
-- AUTO_INCREMENT 自增
-- 字符串使用单引号来包含
-- 所有语句后加 ,除最后一个外
-- primary key 主键,一般一个表只有一个唯一的主键!
CREATE TABLE IF NOT EXISTS `student`(
`id` INT(4) 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 '性别',
`birth` DATETIME DEFAULT NULL COMMENT '出生日期',
`address` VARCHAR(100) DEFAULT NULL COMMENT '家庭住址',
`email` VARCHAR(20) DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
格式:
CREATE TABLE [IF NOT EXISTS] `表名`(
`字段名` 列类型 [属性] [索引] [注释],
`字段名` 列类型 [属性] [索引] [注释],
`字段名` 列类型 [属性] [索引] [注释],
......
`字段名` 列类型 [属性] [索引] [注释]
)[表类型][字符集设置][注释]
常用命令
SHOW CREATE DATABASE sqldemo -- 查看创建数据库的语句
SHOW CREATE TABLE student -- 查看student数据表的定义语句
DESC student -- 显示表的结构
数据库引擎
MYISAM | INNODB | |
---|---|---|
事务支持 | 不支持 | 支持 |
数据行锁定 | 不支持 | 支持 |
外键约束 | 不支持 | 支持 |
全文索引 | 支持 | 不支持 |
表空间大小 | 较小 | 较大,约为 MYISAM两倍 |
常规使用操作:
在物理空间存在的位置
所有数据库文件都存于data目录下
本质还是文件的存储
MySQL引擎在物理文件上的区别
设置表的字符集编码
CHARSET=utf8
不设置的话, 会是mysql默认的字符集编码(不支持中文)
MySQL的默认编码是Latin1,不支持中文
修改
-- 修改表名 ALTER TABLE 表名 AS 新表名
ALTER TABLE teacher RENAME AS teacher1
-- 增加表的字段 ALTER TABLE 表名 ADD 字段名 列属性
ALTER TABLE teacher1 ADD age INT(11)
-- 修改表的字段(重命名,修改约束!)
-- ALTER TABLE 表名 MODIFY 字段名 列属性[]
ALTER TABLE teacher1 MODIFY age VARCHAR(11) -- 修改约束
-- ALTER TABLE 表名 CHANGE 旧名字 新名字 列属性[]
ALTER TABLE teacher CHANGE age age1 INT(1) -- 字段重命名
-- change 用来字段重命名,不能修改字段类型和约束
-- modify 不用来字段重命名,只能修改字段类型和约束
-- 删除表的字段
-- ALTER TABLE 表名 DROP 字段名
ALTER TABLE teacher1 DROP age1
删除
-- 删除表(若存在再删除)
DROP TABLE IF EXISTS teacher1
所有的创建和删除操作尽量加上判断,以免报错
注意:
方式一: 在创建表的时候,增加约束(麻烦)
-- 学生表的gradeid字段 要去引用年级表的gradeid
-- 1.定义外键key
-- 2.给外键添加约束(执行引用)
CREATE TABLE IF NOT EXISTS `student`(
`id` INT(4) 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 '性别',
`birth` DATETIME DEFAULT NULL COMMENT '出生日期',
`gradeid` INT(4) NOT NULL COMMENT '学生的年级',
`address` VARCHAR(100) DEFAULT NULL COMMENT '家庭住址',
`email` VARCHAR(20) DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY(`id`),
KEY `FK_gradeid` (`gradeid`),
CONSTRAINT `FK_gradeid` FOREIGN KEY(`gradeid`) REFERENCES `grade`(`gradeid`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
CREATE TABLE `grade`(
`gradeid` INT(4) NOT NULL AUTO_INCREMENT COMMENT '年级id',
`gradename` VARCHAR(50) NOT NULL COMMENT '年级名称',
PRIMARY KEY(`gradeid`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
删除有外键关系的表的时候,必须先删除引用别人的表(从表),再删除被引用的表(主表)
方式二: 创建表成功后,再添加外键约束
-- 创建表的时候没有外键关系
-- ALTER TABLE 表 ADD CONSTRAINT 约束名 FOREIGN KEY(作为外键的列) REFERENCES 表(字段)
ALTER TABLE `student`
ADD CONSTRAINT `FK_gradeid` FOREIGN KEY(`gradeid`) REFERENCES `grade`(`gradeid`);
以上操作均为物理外键,即数据库级别的外键,不建议使用(避免数据库过多造成困扰)
最佳实践
阿里的JAVA规则: 【强制】不得使用外键与级联,一切外键概念必须在应用层解决
数据库意义: 数据存储,数据管理
DML语言: 数据操作语言
Insert
-- 插入语句(添加)
-- insert into 表名 ([字段1,字段2,字段3]) values('值1'),('值2'),('值3')
-- 主键自增 所以可省略 (若不写表的字段,则会一一匹配)
-- 写插入语句时 一定要数据与字段一一对应
INSERT INTO `grade` (`gradename`) VALUES ('大三');
-- 插入多个字段
INSERT INTO `grade` (`gradename`) VALUES ('大二'),('大一');
注意:
update
-- 修改语句
-- update 表名 set colnum_name = value,[colnum_name = VALUE,...] WHERE [条件]
UPDATE `grade` SET `gradename`='已毕业' WHERE `gradeid` =1
-- 不指明条件时 会改动所有表
UPDATE `grade` SET`gradename` = '大三'
条件: where子句 运算符 id等于某个值、大于某个值,在某个区间内修改…
操作符会返回布尔值
delete
-- 删除数据(避免这样写,会全部删除)
DELETE FROM `grade`
-- 删除指定数据
DELETE FROM `grade` WHERE id = 1;
truncate
作用: 完全清空一个数据库表,表的结构和索引约束不会变
-- 清空表
TRUNCATE `grade`
delete与truncate:
测试
CREATE TABLE test(
`id` INT(4) NOT NULL AUTO_INCREMENT,
`col` VARCHAR(20) NOT NULL,
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
INSERT INTO `test` (`col`) VALUES ('1'),('2'),('3')
-- 不影响自增(下一条数据仍从原基础上自增)
DELETE FROM `test`
-- 自增归零
TRUNCATE `test`
delete删除的问题 重启数据库后
Data Query Language 数据查询语言
用于查询操作的建表:
CREATE DATABASE IF NOT EXISTS `school`;
-- 创建一个school数据库
USE `school`;-- 创建学生表
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`(
`studentno` INT(4) NOT NULL COMMENT '学号',
`loginpwd` VARCHAR(20) DEFAULT NULL,
`studentname` VARCHAR(20) DEFAULT NULL COMMENT '学生姓名',
`sex` TINYINT(1) DEFAULT NULL COMMENT '性别,0或1',
`gradeid` INT(11) DEFAULT NULL COMMENT '年级编号',
`phone` VARCHAR(50) NOT NULL COMMENT '联系电话,允许为空',
`address` VARCHAR(255) NOT NULL COMMENT '地址,允许为空',
`borndate` DATETIME DEFAULT NULL COMMENT '出生时间',
`email` VARCHAR (50) NOT NULL COMMENT '邮箱账号允许为空',
`identitycard` VARCHAR(18) DEFAULT NULL COMMENT '身份证号',
PRIMARY KEY (`studentno`),
UNIQUE KEY `identitycard`(`identitycard`),
KEY `email` (`email`)
)ENGINE=MYISAM DEFAULT CHARSET=utf8;
-- 创建年级表
DROP TABLE IF EXISTS `grade`;
CREATE TABLE `grade`(
`gradeid` INT(11) NOT NULL AUTO_INCREMENT COMMENT '年级编号',
`gradename` VARCHAR(50) NOT NULL COMMENT '年级名称',
PRIMARY KEY (`gradeid`)
) ENGINE=INNODB AUTO_INCREMENT = 6 DEFAULT CHARSET = utf8;
-- 创建科目表
DROP TABLE IF EXISTS `subject`;
CREATE TABLE `subject`(
`subjectno`INT(11) NOT NULL AUTO_INCREMENT COMMENT '课程编号',
`subjectname` VARCHAR(50) DEFAULT NULL COMMENT '课程名称',
`classhour` INT(4) DEFAULT NULL COMMENT '学时',
`gradeid` INT(4) DEFAULT NULL COMMENT '年级编号',
PRIMARY KEY (`subjectno`)
)ENGINE = INNODB AUTO_INCREMENT = 19 DEFAULT CHARSET = utf8;
-- 创建成绩表
DROP TABLE IF EXISTS `result`;
CREATE TABLE `result`(
`studentno` INT(4) NOT NULL COMMENT '学号',
`subjectno` INT(4) NOT NULL COMMENT '课程编号',
`examdate` DATETIME NOT NULL COMMENT '考试日期',
`studentresult` INT (4) NOT NULL COMMENT '考试成绩',
KEY `subjectno` (`subjectno`)
)ENGINE = INNODB DEFAULT CHARSET = utf8;
-- 插入学生数据
INSERT INTO `student` (`studentno`,`loginpwd`,`studentname`,`sex`,`gradeid`,`phone`,`address`,`borndate`,`email`,`identitycard`)
VALUES
(1000,'111111','周丹',1,1,'13800001234','北京朝阳','1980-1-1','[email protected]','123456198001011234'),
(1001,'123456','周颖',1,2,'13800002222','广东深圳','1990-1-1','[email protected]','123456199001011233'),
(1002,'123456','杨文瑞',1,1,'13800002222','广东深圳','1990-1-1','[email protected]','1245619001011233'),
(1003,'111111','韩萌',1,3,'13800002222','广东深圳','1990-1-1','[email protected]','13456199001051233'),
(1004,'123456','刘丽侠',1,4,'13800002222','广东深圳','1990-1-1','[email protected]','23456199006011233'),
(1005,'111111','姜嘉航',2,1,'13800002222','广东深圳','1990-1-1','[email protected]','1234561991011233'),
(1006,'123456','郑嘉祥',2,4,'13800002222','广东深圳','1990-1-1','[email protected]','1234561900101123')
-- 插入成绩数据 这里仅插入了一组,其余自行添加
INSERT INTO `result`(`studentno`,`subjectno`,`examdate`,`studentresult`)
VALUES
(1000,1,'2013-11-11 16:00:00',85),
(1000,2,'2013-11-12 16:00:00',70),
(1001,3,'2013-11-11 09:00:00',68),
(1002,4,'2013-11-13 16:00:00',98),
(1000,5,'2013-11-14 16:00:00',58);
-- 插入年级数据
INSERT INTO `grade` (`gradeid`,`gradename`) VALUES(1,'大一'),(2,'大二'),(3,'大三'),(4,'大四'),(5,'预科班');
-- 插入科目数据
INSERT INTO `subject`(`subjectno`,`subjectname`,`classhour`,`gradeid`)VALUES
(1,'高等数学-1',110,1),
(2,'高等数学-2',110,2),
(3,'高等数学-3',100,3),
(4,'高等数学-4',130,4),
(5,'C语言-1',110,1),
(6,'C语言-2',110,2),
(7,'C语言-3',100,3),
(8,'C语言-4',130,4),
(9,'Java程序设计-1',110,1),
(10,'Java程序设计-2',110,2),
(11,'Java程序设计-3',100,3),
(12,'Java程序设计-4',130,4),
(13,'数据库结构-1',110,1),
(14,'数据库结构-2',110,2),
(15,'数据库结构-3',100,3),
(16,'数据库结构-4',130,4),
(17,'C#基础',130,1);
select 语句
SELECT [ ALL | DISTINCT ]
{ * | TABLE.* | [TABLE.FIELD1[AS ALIAS1][...]]}
FROM TABLE_NAME [AS TABLE_ALIAS]
[ LEFT | RIGHT | INNER JOIN TABLE_NAME2] -- 联合查询
[ WHERE ...] -- 指定结果需满足的条件
[ GROUP BY ...] -- 指定结果按照哪几个字段来分组
[ HAVING ...] -- 过滤分组的记录必须满足的次要条件
[ ORDER BY ...] -- 指定查询记录按一个或多个条件排序
[ LIMIT {
[ OFFSET]ROW_COUNT | ROW_COUNTOFFSET OFFSET}]; -- 指定查询的记录从哪条至哪条
-- 查询全部学生
-- select 字段 from 表
SELECT * FROM student
-- 查询指定字段
SELECT `studentno`,`studentname` FROM `student`
-- 别名,给结果起一个名字 AS
SELECT `studentno` AS 学号,`studentname` AS 学生姓名 FROM `student` AS s
-- 函数 Concat(a,b)
SELECT CONCAT('姓名:',`studentname`) AS 新名字 FROM `student`
去重 DISTINCT
作用:去除SELECT查询出来的结果中重复的数据,只显示一条
-- 查询有哪些同学参加了考试
SELECT * FROM result -- 查询全部的考试成绩
SELECT `studentno` FROM result -- 查询哪些同学参加了考试
SELECT DISTINCT `studentno` FROM result -- 去重
数据库的列(表达式)
SELECT VERSION() -- 查询系统版本
SELECT 100*3-1 AS 计算结果 -- 用于计算
SELECT @@auto_increment_increment -- 查询自增的步长
-- 学员考试成绩+1分 查询
SELECT `studentno`,`studentresult`+1 AS '提分后' FROM result
数据库中的表达式: 文本值、列、null、函数、计算表达式、系统变量…
select 表达式 from 表
作用: 检索数据中符合条件的值
搜索的条件由一个或者多个表达式组成 结果为布尔值
逻辑运算符
运算符 | 语法 | 描述 |
---|---|---|
and && | a and b a&&b | 逻辑与, 真真为真 |
or || | a or b a||b | 逻辑或,有真则为真 |
Not ! | not a !a | 逻辑非,真即假、假即真 |
尽量使用英文字母
-- ==========================where=============================
-- 查询考试成绩在 80-100分之间
SELECT `studentno`,`studentresult` FROM `result`
WHERE `studentresult`>=80 AND `studentresult`<=100
SELECT `studentno`,`studentresult` FROM `result`
WHERE `studentresult`>=80 && `studentresult`<=100
-- 模糊查询(区间)
SELECT `studentno`,`studentresult` FROM `result`
WHERE `studentresult` BETWEEN 80 AND 100
-- 除了1000号学生以外的成绩
-- != not
SELECT `studentno`,`studentresult` FROM `result`
WHERE `studentno`!=1002
SELECT `studentno`,`studentresult` FROM `result`
WHERE NOT `studentno`=1002
模糊查询: 比较运算符
运算符 | 语法 | 描述 |
---|---|---|
IS NULL | a is null | 若操作符为null, 结果为真 |
IS NOT NULL | a is not null | 若操作符为not null,结果为真 |
BETWEEN | a between b and c | 若a在b和c之间,结果为真 |
Like | a like b | SQL匹配,若a匹配b,结果为真 |
In | a in (a1,a2,a3…) | 假设a在a1,a2中的某一个值中,结果为真 |
-- 查询考试成绩在 80-100分之间
SELECT `studentno`,`studentresult` FROM `result`
WHERE `studentresult`>=80 AND `studentresult`<=100
SELECT `studentno`,`studentresult` FROM `result`
WHERE `studentresult`>=80 && `studentresult`<=100
-- 模糊查询(区间)
SELECT `studentno`,`studentresult` FROM `result`
WHERE `studentresult` BETWEEN 80 AND 100
-- 除了1000号学生以外的成绩
-- != not
SELECT `studentno`,`studentresult` FROM `result`
WHERE `studentno`!=1002
SELECT `studentno`,`studentresult` FROM `result`
WHERE NOT `studentno`=1002
-- 查询姓周的同学,
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)
-- 查询在广东的学生
SELECT `studentno`,`studentname`,`address` FROM `student`
WHERE `address` LIKE ('广东%')
SELECT `studentno`,`studentname`,`address` FROM `student`
WHERE `address` IN ('广东深圳') -- in(具体的一个或者多个值)
JOIN 对比
-- ================== 联表查询 ================
-- 查询参加了考试的同学(学号,姓名,科目编号,分数)
SELECT * FROM `student`
SELECT * FROM `result`
-- join on 连接查询
-- where 等值查询
/* 思路
1. 分析需求,分析查询的字段来自哪些表(连接查询)
2. 确定使用哪种连接查询? 7种
确定交叉点(两个表中哪个数据是相同的)
判断的条件: 学生表中 studentno = 成绩表中 studentno
*/
SELECT s.`studentno`,`studentname`,`subjectno`,`studentresult`
FROM `student` AS s
INNER JOIN `result` AS r
WHERE s.`studentno` =r.`studentno`
SELECT s.`studentno`,`studentname`,`subjectno`,`studentresult`
FROM `student` AS s
INNER JOIN `result` AS r
ON s.`studentno` =r.`studentno`
-- right join
SELECT s.`studentno`,`studentname`,`subjectno`,`studentresult`
FROM `student` AS s
RIGHT JOIN `result` AS r
ON s.`studentno` =r.`studentno`
-- left join
SELECT s.`studentno`,`studentname`,`subjectno`,`studentresult`
FROM `student` AS s
LEFT JOIN `result` AS r
ON s.`studentno` =r.`studentno`
-- 查询没有考试成绩的同学
SELECT s.`studentno`,`studentname`,`subjectno`,`studentresult`
FROM `student` AS s
LEFT JOIN `result` AS r
ON s.`studentno` =r.`studentno`
WHERE `studentresult` IS NULL
-- 查询参与考试的同学信息(学号,姓名,科目名,成绩)
SELECT s.`studentno`,`studentname`,`subjectname`,`studentresult`
FROM `student` AS s
RIGHT JOIN `result` AS r
ON r.`studentno` = s.`studentno`
INNER JOIN `subject` AS sub
ON sub.`subjectno` = r.`subjectno`
-- 查询学员所属的年级(学号,姓名,年级名称)
SELECT `studentno`,`studentname`,`gradename`
FROM `student` AS s
INNER JOIN `grade` AS g
ON s.`gradeid` = g.`gradeid`
-- 查询科目所属的年级(科目名称,年级名称)
SELECT `subjectname`,`gradename`
FROM `subject` AS sub
INNER JOIN `grade` AS g
ON sub.`gradeid` = g.`gradeid`
操作 | 描述 |
---|---|
inner join | 若表中至少有一个匹配,则返回行(交集) |
left join | 会从左表中返回所以值,即使右表中没有匹配 |
right join | 会从右表中返回所以值,即使左表中没有匹配 |
自连接
自己的表与自己的表连接 *核心:*一张表拆为两种一样的表即可
自连接建表语句:
CREATE TABLE `school`.`category`( `categoryid` INT(3) NOT NULL COMMENT 'id', `pid` INT(3) NOT NULL COMMENT '父id 没有父则为1', `categoryname` VARCHAR(10) NOT NULL COMMENT '种类名字', PRIMARY KEY (`categoryid`) ) ENGINE=INNODB CHARSET=utf8 COLLATE=utf8_general_ci;
INSERT INTO `school`.`category` (`categoryid`, `pid`, `categoryname`) VALUES ('2', '1', '信息技术');
INSERT INTO `school`.`category` (`categoryid`, `pid`, `categoryname`) VALUES ('3', '1', '软件开发');
INSERT INTO `school`.`category` (`categoryid`, `PId`, `categoryname`) VALUES ('5', '1', '美术设计');
INSERT INTO `School`.`category` (`categoryid`, `pid`, `categorynamE`) VALUES ('4', '3', '数据库');
INSERT INTO `school`.`category` (`CATEgoryid`, `pid`, `categoryname`) VALUES ('8', '2', '办公信息');
INSERT INTO `school`.`category` (`categoryid`, `pid`, `CAtegoryname`) VALUES ('6', '3', 'web开发');
INSERT INTO `SCHool`.`category` (`categoryid`, `pid`, `categoryname`) VALUES ('7', '5', 'ps技术');
-- 查询父子信息
SELECT a.`categoryname` AS '父',b.`categoryname` AS '子'
FROM `category` AS a, `category` AS b
WHERE a.`categoryid` = b.`pid`
排序
-- 成绩降序
-- ORDER BY 通过哪个字段来排序
-- 查询参与考试的同学信息(学号,姓名,科目名,成绩)
SELECT s.`studentno`,`studentname`,`subjectname`,`studentresult`
FROM `student` AS s
RIGHT JOIN `result` AS r
ON r.`studentno` = s.`studentno`
INNER JOIN `subject` AS sub
ON sub.`subjectno` = r.`subjectno`
ORDER BY `studentresult` ASC
分页
-- 为什么分页
-- 缓解数据库压力、用户体验 瀑布流
-- 分页 每页3条
-- 语法: limit 起始页,页面的大小
SELECT *
FROM `student`
-- limit 0,3
LIMIT 1,3
-- 第一页 limit 0,3
-- 第二页 limit 1,3
-- 第三页 limit 2,3
-- 第N页 limit (n-1)*pageSize,pageSize
-- [ pageSize:页面大小 ] [ (n-1)*pageSize 起始值 ] [ n 当前页 ] [ 数据总数/页面大小 = 总页数 ]
官网: https://dev.mysql.com/doc/refman/5.7/en/numeric-functions.html
-- =============== 常用函数 =============
-- 数学运算
SELECT ABS(-8) -- 绝对值
SELECT CEILING(9.4) -- 向上取整
SELECT FLOOR(9.4) -- 向下取整
SELECT RAND() -- 返回一个0-1之间的随机数
SELECT SIGN(10) -- 判断一个数的符号 负数返回-1 整数返回1
-- 字符串函数
SELECT CHAR_LENGTH('Java学习路线永远滴神') -- 返回字符串长度
SELECT CONCAT('我','喜欢','学Java') -- 拼接字符串
SELECT LOWER('ASDNOUHasd') -- 转换成小写字母
SELECT UPPER('asdasdqwe') -- 转换成大写字母
SELECT INSTR('Java','v') -- 返回第一次出现的子串的索引
SELECT REPLACE('qweasdzxc','asd','qwe') -- 替换出现的指定字符串
SELECT SUBSTR('Java学习路线永远滴神',9,4) -- 返回指定的子字符串(源字符串,截取位置,截取长度)
SELECT REVERSE('abcdefg') -- 反转
-- 将周姓学生改为邹
SELECT REPLACE(`studentname`,'周','邹')
FROM `student`
WHERE `studentname` LIKE '周%'
-- 时间和日期函数
SELECT CURRENT_DATE() -- 获取当前日期
SELECT CURDATE() -- 获取当前日期
SELECT NOW() -- 获取当前时间
SELECT LOCALTIME() -- 本地时间
SELECT SYSDATE() -- 系统时间
SELECT YEAR(NOW())
-- 系统
SELECT SYSTEM_USER()
SELECT USER()
SELECT VERSION()
函数名称 | 描述 |
---|---|
COUNT() | 计数 |
SUM() | 求和 |
AVG() | 平均值 |
MAX() | 最大值 |
… | … |
-- =========== 聚合函数 ===========
SELECT COUNT(`studentname`) FROM `student`
SELECT COUNT(1) FROM `student`
SELECT COUNT(*) FROM `student`
SELECT SUM(`studentresult`) AS 总和 FROM `result`
SELECT AVG(`studentresult`) AS 平均分 FROM `result`
SELECT MIN(`studentresult`) AS 最低分 FROM `result`
SELECT MAX(`studentresult`) AS 最高分 FROM `result`
-- 查询不同课程的平均分、最高分、最低分 ,(平均分>80)
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`)>=70
什么是MD5
主要增强算法复杂度和不可逆性
MD5不可逆,具体值的MD5是一样的
MD5破解网站的原理: 有一个数据字典,MD5加密后的值、加密前的值
CREATE TABLE `school`.testMD5(
`id` INT(4) 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,'no1','123456'),(2,'no2','123456'),(3,'no3','1234')
-- 加密
UPDATE `testmd5` SET pwd = MD5(pwd) WHERE id = 1
UPDATE `testmd5` SET pwd = MD5(pwd) -- 加密全部
-- 插入时加密
INSERT INTO `testmd5` VALUES(4,'no4',MD5('123456'))
-- 校验
SELECT *
FROM `testmd5`
WHERE NAME = 'no1' AND pwd = MD5('123456')
要么都成功,要么都失败
————————
————————
将一组SQL放在一个批次中去执行
原子性 一致性 隔离性 持久性 (脏读、幻读…)
参考CSDN理解: https://blog.csdn.net/dengjili/article/details/82468576
原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
一致性(Consistency)
事务前后数据的完整性必须保持一致。
隔离性(Isolation)
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响
脏读:
指一个事务读取了另外一个事务未提交的数据。
不可重复读:
在一个事务内读取表中的某一行数据,多次读取结果不同。(这个不一定是错误,只是某些场合不对)
虚读(幻读)
是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。
(一般是行影响,多了一行)
执行事务
-- mysql是默认开启事务自动提交的
SET autocommit = 0 -- 关闭
SET autocommit = 1 -- 开启(默认)
-- 手动处理事务
SET autocommit = 0 -- 关闭自动条件
-- 事务开启
START TRANSACTION -- 标记一个事务的开始,从这之后sql都在同一个事务内
INSERT XX
INSERT XX
-- 提交: 持久化 (成功)
COMMIT
-- 回滚: 回到原来样子 (失败)
ROLLBACK
-- 事务结束
SET autocommit = 1 -- 开启自动提交
SAVEPOINT 保存点名称 -- 设置一个事务的保存点
ROLLBACK TO SAVEPOINT 保存点名 -- 回滚到保存点
RELEASE SAVEPOINT 保存点名 -- 撤销保存点
模拟事务
CREATE DATABASE shop CHARACTER SET utf8 COLLATE utf8_general_ci
USE shop
CREATE TABLE `account` (
`id` INT(4) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(20) NOT NULL,
`balance` DECIMAL(7,2) NOT NULL,
PRIMARY KEY(`id`)
)ENGINE = INNODB DEFAULT CHARSET = utf8
INSERT INTO `account`(`name`,`balance`) VALUES('A',2000.00),('B',10000.00)
-- 模拟转账
SET autocommit = 0 -- 关闭自动提交
START TRANSACTION -- 开启事务
UPDATE `account` SET `balance` =`balance` - 500 WHERE `name` = 'A' -- A减500
UPDATE `account` SET `balance` =`balance` + 500 WHERE `name` = 'B' -- B加500
COMMIT -- 提交事务 --> 持久化
ROLLBACK -- 回滚
SET autocommit = 1 -- 恢复默认值
MySQL官方对索引的定义为: **索引(index)**是帮助MySQL高效获取数据的数据结构
提取句子主干,就可以得到索引的本质:索引是数据结构
基础语法
-- 索引的使用
-- 1.在创建表的时候给字段增加索引
-- 2.创建完毕后,增加索引
-- 显示所有的索引信息
SHOW INDEX FROM `student`
-- 增加一个全文索引 索引名(列名)
ALTER TABLE `school`.`student` ADD FULLTEXT INDEX `studentname`(`studentname`)
-- EXPLAIN 分析sql执行的状况
EXPLAIN SELECT * FROM `student` -- 非全文索引
EXPLAIN SELECT * FROM `student` WHERE MATCH(`studentname`) AGAINST('周')
建表
CREATE TABLE `app_user` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) DEFAULT'' COMMENT'用户昵称',
`email` VARCHAR(50) NOT NULL COMMENT'用户邮箱',
`phone` VARCHAR(20) DEFAULT'' COMMENT'手机号',
`gender` TINYINT(4) UNSIGNED DEFAULT '0'COMMENT '性别(0:男;1:女)',
`password` VARCHAR(100) NOT NULL COMMENT '密码',
`age` TINYINT(4) DEFAULT'0' COMMENT '年龄',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
`update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT = 'app用户表'
创建大数据集
DROP FUNCTION IF EXISTS test;
-- 插入100w 数据
DELIMITER $$ -- 必须要写 标志
CREATE FUNCTION test()
RETURNS INT
BEGIN
DECLARE num INT DEFAULT 1000000;
DECLARE i INT DEFAULT 0;
WHILE i < num DO
INSERT INTO `app_user`(`name`,`email`,`phone`,`gender`,`password`,`age`)
VALUES(CONCAT('用户',i),'[email protected]',CONCAT('18',FLOOR(RAND()*(999999999-100000000)+100000000)),FLOOR(RAND()*2),UUID(),FLOOR(RAND()*100));
SET i = i + 1;
END WHILE;
RETURN i;
END;
SELECT test()
进行查询操作
SELECT test()
SELECT * FROM `app_user` WHERE `name` = '用户999' -- 耗时 0.548 sec
SELECT * FROM `app_user` WHERE `name` = '用户999' -- 耗时 0.627 sec
-- id_表名_字段名
-- create index 索引名 on 表(字段)
CREATE INDEX id_app_user_name ON `app_user` (`name`)
EXPLAIN SELECT * FROM `app_user` WHERE `name` = '用户999' -- 耗时 0.002 sec
索引在小数据量的时候作用不大,但在大数据量时效果明显
sqlyog 可视化管理
SQL命令操作
-- 创建用户
CREATE USER erran IDENTIFIED BY '123456'
-- 修改密码(当前用户)
SET PASSWORD = PASSWORD('111111')
-- 修改密码(指定用户)
SET PASSWORD FOR erran PASSWORD('111111')
-- 用户重命名
RENAME USER erran TO helloWorld
-- 用户授权
-- 除了给别人授权外,其他的权限均可
GRANT ALL PRIVILEGES ON *.* TO helloWorld -- 全部权限, 库.表
-- 查询权限
SHOW GRANTS FOR helloWorld -- 查看指定用户的权限
SHOW GRANTS FOR root@localhost
-- ROOT用户权限 GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
-- 撤销权限
REVOKE ALL PRIVILEGES ON *.* FROM helloWorld
-- 删除用户
DROP USER helloWorld
MySQL数据库备份方式
直接拷贝物理文件
在sqlyog等可视化工具中 手动导出
使用命令行导出 mysqldump 命令行使用
mysqldump -hlocalhost -uroot -p123456 school student >E:/a.sql
槽糕的数据库设计:
良好的数据库设计:
软件开发中,关于数据库的设计
设计数据库的步骤:(个人博客)
为什么需要数据规范化
三大范式
第一范式(1NF)
原子性:保证每一列不可再分
第二范式(2NF)
前提: 满足第一范式
每张表只描述一件事情
第三范式(3NF)
前提: 满足第一范式、第二范式
确保数据表中的每一列数据都和主键直接相关,不能间接相关
规范性与性能的问题
关联查询的表 不得超过三张表