学习思路:对照sqlyog可视化历史记录查看SQL
固定的语法或关键字必须记住

初识mysql 如何删除数据库数据

sc delete mysql删除数据库数据

1.1sqlyog软件基本使用

每一个sqlyog的执行操作本质上是一段sql语句

1.2命令行操作

链接数据库 mysql -uroot -p密码
exit 退出连接
–是注释
所有的语句都使用分号结尾
flush privileges; 刷新权限

1.1基本查看动作

show databases; 查看所有数据库
use 数据库名 切换数据库
show tables --查看数据库中的所有表
describe --查看数据库中的所有表

1.2创建基本操作

create database westos;//创建一个名叫westos的数据库

1.3数据库 xxx语言

DDL 数据库定义语言
DML 数据库操作语言
DQL 数据库查询语言
DCL 数据库控制语言

2.操作数据库

操作数据库>操作数据库中的表>操作数据库表中的数据
mysql不区分大小写

2.1操作数据库(了解就好)

1.创建数据库
CREATE DATABASE IF NOT EXISTS westos; 2.删除数据库
DROP DATABASE IF EXISTS hello; 3.使用数据库
USE school;
如果表名是一个特殊字符则需要带``
4.查看所有的数据库
SHOW DATABASES; 对比sqlylg的可视化操作

2.2数据库的列类型

数值

从小到大

  • tinyint 1个字节
  • smallint 2个字节
  • mediumint 中等大小的数据 3个字节
  • int 标准的整数 4个字节常用
  • bigint 较大的数据 8个字节
  • float 浮点数 4个字节
  • double 浮点数 8个字节(精度问题)
  • decimal 字符串形式的浮点数 金融计算的时候一般使用

字符串

  • char 字符串固定大小 0-255
  • varchar 可变字符串 0-65535 常用的变量 对标java String
  • tinytest 微型文本 神通数据库创建表空间java_后端
  • test 文本串 神通数据库创建表空间java_神通数据库创建表空间java_02

时间日期
类似java,util.Data

  • data YYYY-MM-DD 日期
  • HH:mm:ss 时间格式
  • datatime YYYY-MM-DD HH:mm:ss 最常用的时间格式
  • timestamp 时间戳 1970.01.01 到现在的毫秒数 也较为常用
  • year 年份表示

null

没有值,位置

2.3数据库的字段属性==(重点)==

神通数据库创建表空间java_sql_03

Unsigned:

  • 无符号的整数
  • 声明了该列不能声明为负数

zerofill:

  • 0填充的
  • 不足的位数使用0来填充

自增:

  • 通常理解为自动在上一条记录的基础上加1(默认)
  • 通常用来设置唯一的主键 index 并且必须是整数类型
  • 可以自定义设置主键的起始值和步长

非空 NULL not null

  • 假设设置为not null,如果不给它赋值,就会报错
  • 如果不填写值,默认是null

默认:default

  • 设置默认值
  • 如果不改变该列的值,则会有默认的值

拓展

神通数据库创建表空间java_后端_04

2.4创建数据库表

注意点表的名称和字段尽量使用``起来
字符串使用单引号括号起来
所有语句前加, 最后一个语句不加
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 '性别', 
`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;

格式

CREATE TABLE IF NOT EXISTS `表名`(
	`字段名` 列类型 【属性】【索引】【注释】,
	`字段名` 列类型 【属性】【索引】【注释】,
	...
	`字段名` 列类型 【属性】【索引】【注释】,
)【表类型】【表字符集设置】

常用命令

SHOW CREATE DATABASE school;查看创建数据库的语句

SHOW CREATE TABLE student; 查看创建表的语句

DESC student; 查看表的结构

神通数据库创建表空间java_mysql_05

2.5数据表的类型

INNODB 默认使用
MYISAM 早些年使用

MYISAM

INNODB

事务支持

不支持

支持

数据行锁定

不支持

支持

外键

不支持

支持

全文索引

支持

支持

表空间的大小

较小

较大,约为MYISAM的两倍

  • MYSIAM 节约空间,速度较快
  • INNODB 安全性高,事务的支持,多表多用户操作

物理空间存在的位置

所有的数据库文件都存在data文件下
本质还是文件的存储
MYSQL 引擎在物理文件上的区别

  • innoDB 在数据库表中只有一个*.frm文件,以及上级目录下的ibdata1文件
  • MYSIAM对应文件

*.frm

表结构的定义文件

*.MYD

数据文件(data)

*.MYI

索引文件(index)

设置数据库表的字符集编码

DEFAULT CHARSET=utf8 不设置的话,会是mysql默认的字符编码latin1
在my.ini中配置默认的编码

2.6修改删除表

修改

  • 修改表名
    ALTER TABLE student RENAME AS teacher; 第一个是旧表名,第二个是新表名
  • 增加表的字段
    ALTER TABLE teacher ADD age INT(11); add 一个age字段
  • 修改表的字段
    ALTER TABLE teacher MODIFY age VARCHAR(11); 将age的字段修改为VAECHAR(11); --修改约束
  • 字段重命名
    ALTER TABLE teacher CHANGE age age1 INT(1);
  • 删除表的字段
    ALTER TABLE teacher DROP age;
  • 给创建表的字段设置默认值
    ALTER TABLE student ALTER COLUMN `name` SET DEFAULT '东东';

删除

  • 删除表的字段

ALTER TABLE teacher DROP age;所有的创建和删除操作尽量加上判断,以免报错

注意点

  • 所有字段名使用 ``包裹
  • 注释 - - 或者 /* */
  • sql关键字大小写不敏感,建议大家写小写
  • 所有的符号全部用英文

3MySQL数据管理

3.1外键(了解即可)

方式一,在创建表的时候给主键增加约束

-- 创建grade
··
-- 学生表的gradeid 字段要去引用年级表的gradeid
-- 定义外键key
-- 给这个外键添加约束 references 引用

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 '性别', 
`birthday` DATETIME DEFAULT NULL COMMENT '出生日期', 
`address` VARCHAR (100) DEFAULT NULL COMMENT '家庭住址', 
`email` VARCHAR(50) DEFAULT NULL COMMENT '邮箱',
`gradeid` INT(10) NOT NULL COMMENT '学生的年级',
 PRIMARY KEY(`id`),
 CONSTRAINT `FK_gradeid` FOREIGN KEY (`gradeid`) REFERENCES `grade` (`gradeid`)
 )ENGINE=INNODB DEFAULT CHARSET=utf8;

神通数据库创建表空间java_后端_06

方法二 在创建完表之后再定义外键

ALTER TABLE `student ADD CONSTRAINT `FK_gradeid` FOREIGN KEY(`gradeid`) REFERENCES `grade`(`gradeid`); 公式:
ALTER TABLE 表
ADD CONSTRAINT 约束名 FOREIGN KEY(作为外键的列) REFERENCES 哪个表(哪个字段);
以上的操作都是物理外键,数据库级别的外键,(避免数据库过多造成困扰)
最佳实践

  • 数据库就是单纯的表,只用来存放数据,行代表数据,列代表字段
  • 我们想使用多张表的数据,程序去实现
  • 了解即可,避免使用外键

3.2DML语言(全部记住,背下来)

数据库的意义:数据存储跟数据管理
DML语言: 数据操作语言

  • insert
  • update
  • delete

3.3添加

– 由于主键自增,我们可以省略主键

– insert into 表名(字段1,字段2,字段3) values(‘值1’,‘值2’,‘值3’)

INSERT INTO `grade`(`gradename`) VALUES('大四'); 效果图:

神通数据库创建表空间java_mysql_07


– 不写字段就会一一匹配

– 一般写插入语句一定要数据可字段一一对应

INSERT INTO `grade` VALUES('大四');

– 输入多个字段

INSERT INTO `grade`(`gradename`) VALUES('大一'),('大二');

注意事项:

1字段和字段之间使用,隔开

2字段是可以省略的,但是后面的值要一一对应

3.4修改

update 修改谁 (条件) set 原来的值=新值,… 条件

UPDATE `student` SET `name`='李佳乐' WHERE id = 1; 修改多个属性:用,隔开
修改id等于1的name
不加where会全部进行修改

条件:where 字句 运算符 id等于某个 值,大于某个值,在某个区间内修改…

操作符

意义

范围

结果

=

范围

5=6

false

<> 或者!=

不等于

5!=6

true

>

>=

<

<=

between…and…

在某个范围内闭合区间

and

&&

or

||

用and和or可以进行多个条件判断

  • 尽量带着``
  • 条件,删选的条件,如果没有指令则会修改所有的列
  • value是一个具体的值,也可以是一个变量
  • 新值不一定是一个具体的值,也可以是一个变量(时间CURRENT_TIME)
  • 多个设置的属性之间,使用英文逗号隔开

3.5删除

delete命令

delete from 表名 where 条件
DELETE FROM `student` WHERE id=1;

truncate命令

完全清空一个数据库表,表的结构和索引约束不会变

delete 和truncate区别

相同点:都能删除数据,都不能删除表结构
不同:

  • truncate 重新设置自增列 计数器会归零
  • truncate 不会影响事务
-- 创建一个测试表
CREATE TABLE `test` (
`id` INT(4) NOT NULL AUTO_INCREMENT,
`coll` VARCHAR(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8

-- 插入几个测试数据
INSERT INTO test(coll) VALUES('row1'),('row2'),('row3');

-- 删除表数据(不带where条件的delete)
DELETE FROM test;
-- 结论:如不指定Where则删除该表的所有列数据,自增当前值依然从原来基础上进行,会记录日志.

-- 删除表数据(truncate)
TRUNCATE TABLE test;

-- 结论:truncate删除数据,自增当前值会恢复到初始值重新开始;不会记录日志.

-- 同样使用DELETE清空不同引擎的数据库表数据.重启数据库服务后
-- InnoDB : 自增列从初始值重新开始 (因为是存储在内存中,断电即失)
-- MyISAM : 自增列依然从上一个自增数据基础上开始 (存在文件中,不会丢失)

4、DQL查询数据(最重点)

select 语法

神通数据库创建表空间java_神通数据库创建表空间java_08

4.1DQL

Data Query Language 数据查询语言

  • 所有的查询操作都用到它,Select
  • 简单的查询,复杂的查询他都能做到
  • 数据库中最核心最重要使用频率最高的语言

4.2指定查询字段

– select 字段 from 表

查询全部年级

SELECT * FROM table; 查询指定字段

SELECT 字段 FROM table;

给结果起一个名字,列名字和表名都可以重命名

SELECT 字段 As 字段 FROM table As table2;

函数 Concat(a,b)

在要查询的b前面追加a,

SELECT CONCAT('姓名:',studentname) AS 新名字 FROM student;

效果图:

神通数据库创建表空间java_字段_09

去重复 distinct

SELECT DISTINCT `studentno` FROM result; 去除重复的数据,只显示一条

查看系统版本(函数)

SELECT VERSION();

计算(表达式)

SELECT 100*3-1 AS 计算结果;

查询自增步长(变量)

SELECT @@auto_increment_increment;

让查询出来的值+1

SELECT `studentno`,`studentresult`+1 FROM result;

4.3 where条件字句

作用:检索数据中符合条件的值
搜索的条件由一个或者多个表达式组成 结果 布尔值

逻辑运算符

运算符

语法

描述

and &&

a and b a&&b

逻辑与

or ||

a or b a||b

逻辑或

Not !

not a !a

逻辑非

尽量使用英文字母
实例:
SELECT studentno,`studentresult` FROM result WHERE `studentresult`>=95 AND `studentresult`<=100; 使用between and
SELECT studentno,`studentresult` FROM result WHERE `studentresult` BETWEEN 95 AND 100; 同理可以使用其他逻辑运算符

模糊查询(重点) 比较运算符

运算符

语法

描述

IS NULL

a is null

如果操作符为NULL,结果为真

IS NOT NULL

a is not null

如果操作符为not null,结果为真

between and

a between b and c

若a在b和c之间,则结果为真

like

a like b

SQL 匹配,如果a匹配b,则结果为真

In

a in(a1,a2,a3…)(具体的一个值或者多个值)

假设a在a1,或者a2,其中某一个值中,结果为真

例子 like

– like结合 %(代表0到任意个字符) _(一个字符)

神通数据库创建表空间java_mysql_10


– 查询姓张的同学

SELECT `studentno`,`studentname` FROM student WHERE `studentname` LIKE '张%'; – 查询姓张的后面只有一个字的同学

SELECT `studentno`,`studentname` FROM student WHERE `studentname` LIKE '张_';

同理查询两个字的加两根 _

例子 in

不能用like
– 查询1000 1001 号学员
SELECT `studentno`,`studentname` FROM student WHERE `studentno` IN (1000,1001); – 查询在北京朝阳的学员
SELECT `studentno`,`studentname`,`address` FROM student WHERE address IN ('北京朝阳');

例子 null 和 not null

查询identitycard为空的学员
SELECT `studentno`,`studentname`,`address`,`identitycard` FROM student WHERE `identitycard` IS NULL ;

4.4连表查询

JOIN 对比

神通数据库创建表空间java_sql_11


神通数据库创建表空间java_后端_12

例子 inner join – left join – right join

join(连接的表) on (判断查询) 连接查询
where 等值查询

-- 查询参加了考试的同学(学号,姓名,科目编号,分数)
SELECT * FROM student;
SELECT * FROM result;
/*
思路
1、分析需求,分析查询的字段来自哪种表,(连接查询)
2、确定使用哪种查询?7种。
确定交叉点(这两个表中哪个数据是相同的)
判断条件:学生表中的studentno = 成绩表中的 studentno
*/
SELECT s.`studentno`,`studentname`,`subjectno`,`studentresult`
FROM student AS s
INNER JOIN result AS r
on s.`studentno`=r.`studentno`

操作

描述

inner join

如果表中至少有一个匹配,就返回行

left join

即使右表中没有匹配,也会返回值

right join

会从右表中返回所有值,即使左标中没有匹配

  • left join以左表为基准,全部写入,然后再去右表中查询,右表中如果没有值则记为null;
  • right join同理
  • inner join是两表满足条件才会显示

连表查询三个表

SELECT s.`studentno`,studentname,`subjectname`,studentresult 
FROM student s
RIGHT JOIN result r
ON r.studentno = s.studentno
INNER JOIN `subject` s1
ON r.`subjectno`=s1.`subjectno`

假设存在多张表,先查询两张表,再查寻多张表

自连接

核心:将自己的表和自己的表连接,一张表拆为两张一样的表即可。

SELECT a.`categoryname` AS '父栏目', b.`categoryname` AS '子栏目'
FROM `category` AS a
LEFT JOIN `category` AS b
ON b.`pid`=a.`categoryid`;

4.5 分页和排序

排序

– order by 升序ASC 降序DESC
– order by 通过哪个字段排序,怎么排

排序例子

SELECT s.`studentno`,studentname,`subjectname`,studentresult 
FROM student s
RIGHT JOIN result r
ON r.studentno = s.studentno
INNER JOIN `subject` s1
ON r.`subjectno`=s1.`subjectno`
ORDER BY `studentresult` DESC

降序排

分页 limit

– 为什么要分页?
– 缓解数据库压力。给人更好的体验(瀑布流)

limit 起始值 页面的大小
(n-1)*pagesize,pagesize

4.6子查询

where(这个值是计算出来的)
本质:在where语句中嵌套一个子查询语句

-- 分数不小于80分的学生的学号和姓名

SELECT `studentno` , `studentname`
FROM student
WHERE studentno = ANY(
SELECT `studentno`
FROM result 
WHERE result.`studentresult`>=80
)

5、Mysql函数


官网

5.1常用函数(并没有那么常用)

1数学运算

-- 绝对值
SELECT ABS(-8)
-- 向上取整
SELECT CEILING(9.4)
-- 向下取整
SELECT FLOOR(9.4)
-- 随机数,返回0-1的随机数
SELECT RAND()
-- 判断一个数的符号 负数返回-1 正数返回1
SELECT SIGN(-10)
-- 字符串函数 
-- -- 返回字符串长度
SELECT  CHAR_LENGTH('即使再小的帆也能远航') 
-- -- 拼接字符串
SELECT CONCAT('我','爱','你们')
-- -- 查询,替换
SELECT INSERT('我爱编程helloworld',1,2,'超级热爱')
-- -- 转小写字母
SELECT LOWER('XIAOLIPLUM')
-- -- 转大写字母
SELECT UPPER('xiaoliplum')
-- -- 返回第一次出现子串的索引
SELECT INSTR('xiaolipulm','p')
-- -- 替换出现的指定字符串
SELECT REPLACE('坚持就能成功','坚持','努力')
-- -- 截取字符串
SELECT SUBSTR('坚持就能成功',4,6)
-- -- 反转字符串
SELECT REVERSE('坚持就能成功')
-- 时间跟日期函数(记住)
-- -- 获取当前日期
SELECT CURRENT_DATE()
-- -- 获取当前日期
SELECT CURDATE()
-- -- 获取当前时间
SELECT NOW()
-- -- 获取本地时间
SELECT LOCALTIME()
-- -- 获取系统时间
SELECT SYSDATE()
SELECT ...(NOW()) 可以获取现在的年月日时间
-- 版本号
SELECT VERSION()

5.2聚合函数(常用)

函数名称

描述

count()

计数

sum()

求和

avg()

平均值

max()

最大值

min()

最小值

5.3分组以及过滤

-- 查询不同课程的平均分,最高分,最低分
-- 核心 根据不同的课程分组

SELECT subjectname,AVG(`studentresult`),MAX(`studentresult`),MIN(`studentresult`)
FROM result r
INNER JOIN `subject` sub
ON r.`subjectno`=sub.`subjectno`
GROUP BY r.subjectno

5.4拓展MD5数据库级别加密

UPDATE testmd5 SET pwd=MD5(pwd); 对用户传进来的密码进行加密,与存储在数据库中的md5加密后的密码进行比对

5.5select总结

select 去重 要查的字段 from 表(注意:表和字段可以取别名)
xxx join 要连接的表 on 等值判断
where (具体的值,子查询语句)
group by (通过字段来分组)
Having (过滤后的分组信息,条件和where是一样的,位置不同)
order by (通过哪个字段进行排序)
limit startindex,pagesize

业务层面

6事务

6.1什么是事务?

1、A 1000 B 200
2、A给B转账200 A->800
3、B收到 b->400


将一组sql放在一个批次中去执行

事务原则 原子性 一致性 隔离性 持久性 (脏读,换读)

原子性

两个步骤一起成功或者一起失败,不能只发生其中一个动作

一致性

事务前后数据的完整性要保持一直

持久性

事务一旦提交不可逆,持久化到数据库

隔离性

事务的隔离性是指多个用户并发访问数据库的时候,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,事物之间要相互隔离。

隔离导致的一些问题

1 脏读
指一个事务读取了另一个事务未提交的数据
2 不可重复读
在一个事务内读取表中的某一行数据,多行数据读取结果不同
3 幻读
当读的时候,插入一条id=5的数据,没有读出新插入的id=5的数据,但是插入id=5数据的时候报错。

6.2执行事务

-- mysql 是默认开启事务自动提交的
SET autocommit =0 ; //关闭
SET autocommit =1 ; //执行

-- 手动处理事务
-- 关闭自动提交
SET autocommit=0;
-- 事务开启

 START TRANSACTION -- 标记一个事务 从这个之后的sql 都在同一事务内
 
-- 如果成功,提交
COMMIT 
-- 如果失败,回滚,回到原来的样子
ROLLBACK
 
-- 事务结束

-- 开启自动提交
SET autocommit=1;


SAVEPOINT 保存点名 设置一个事务的保存点
ROLLBACK TO SAVEPOINT 保存点名 -- 回滚到保存点

例子

-- 模拟转账
SET autocommit= 0 ; -- 关闭自动提交
START TRANSACTION -- 开启一个事务
UPDATE account SET money=money-500 WHERE `name` = 'A'
UPDATE account SET money=monney+500 WHERE `name` = 'B'
COMMIT; -- 提交,事务一旦提交就被持久化了
ROLLBACK;-- 回滚
SET autocommit=1; -- 恢复默认值

7、索引


mysql官方对索引的定义为:索引是帮助mysql高效获取数据的数据结构。
索引的本质:数据结构

7.1索引的分类

在一个表中,主键索引只能有一个,唯一索引可以有多个

  • 主键索引 primary key
  • 唯一的标识,主键不可重复,只能有一个列作为主键
  • 唯一索引 unique key
  • 避免重复的列出现,唯一索引可以重复,多个列都可以标识为唯一索引
  • 常规索引 key / index
  • 默认的,index,key关键字设置
  • 全文索引 full text
  • 在特定的数据库引擎下,才有
  • 快速定位数据

索引的使用

1、在创建表的时候给字段增加索引
2、创建完毕后,增加索引

显示所有索引信息
增加一个全文索引
ALTER TABLE `student` ADD FULLTEXT INDEX `studentname` (`studentname`); 前面studentname是索引名,后面studentname是列名

CREATE INDEX id_app_user_name ON app_user(`name`) create index 索引名 on 表(字段)

基础语法

SHOW INDEX FROM student;

-- explain 分析sql执行的状况
EXPLAIN SELECT * FROM student ; -- 常规索引,非全文索引,查了3rows

EXPLAIN SELECT * FROM student WHERE MATCH(studentname) AGAINST('刘');

7.2测试索引

数据生成代码

CREATE TABLE `app_user` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) DEFAULT '',
`eamil` VARCHAR(50) NOT NULL,
`phone` VARCHAR(20) DEFAULT '',
`gender` TINYINT(4) UNSIGNED DEFAULT '0',
`password` VARCHAR(100) NOT NULL DEFAULT '',
`age` TINYINT(4) DEFAULT NULL,
`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-- 插入100万数据.
SET GLOBAL log_bin_trust_function_creators=1; -- 开启创建函数功能
/*
  第一个语句 delimiter 将 mysql 解释器命令行的结束符由”;” 改成了”$$”,
  让存储过程内的命令遇到”;” 不执行
*/
DELIMITER $$
CREATE FUNCTION mock_data()
RETURNS INT
BEGIN
	DECLARE num INT DEFAULT 1000000;
	DECLARE i INT DEFAULT 0;
	WHILE i<num DO
		INSERT INTO `app_user`(`name`,`eamil`,`phone`,`gender`)VALUES(CONCAT('用户',i),'19224305@qq.com','123456789',FLOOR(RAND()*2));
		SET i=i+1;
	END WHILE;
	RETURN i;
END;$$

SELECT mock_data()$$ -- 执行此函数 生成一百万条数据

测试

SELECT * FROM app_user WHERE `name`='用户99999'; -- 执行耗时 : 0.283 sec

神通数据库创建表空间java_mysql_13


查询了995053行

给name创建完索引之后
SELECT * FROM app_user WHERE `name`='用户999'; -- 0sec

神通数据库创建表空间java_后端_14

只查了一行
索引在小数据的情况下用处不大,,在用户量大的时候区别非常明显。

7.3索引原则

  • 索引不是越多越好
  • 不要对进程变动数据加索引
  • 小数据量的表不需要加索引
  • 索引一般加在常用来查询的字段上

索引的数据结构

hash类型的索引
默认是Btree: innodb的默认数据结构

运维级别mysql学习

8、权限管理

8.1、用户管理

sqlyog可视化管理

神通数据库创建表空间java_字段_15


sql命令操作

用户表:mysql.user

本质:对这张表进行增删改查

神通数据库创建表空间java_后端_16

8.2mysql备份

为什么要备份?

  • 保证重要的数据不丢失
  • 数据转移

mysql数据备份的方式

  • 直接拷贝物理文件
  • 在sqlyog这种可视化工具中手动导出
  • 使用命令行导出导入 mysqldump 命令行使用
  • mysqldump -hlocalhost -uroot -p123456 school student>D:/a.sql
  • mysqldump -h主机 -u 用户名 -p 密码 数据库 表1 表2 表3…>物理磁盘位置,文件名
  • source 登陆的情况下,切换到指定数据库 source 备份文件

把数据库给朋友,sql文件给朋友即可。

9、规范数据库设计

9.1为什么需要设计

当数据库比较复杂的时候,我们就需要设计了
糟糕的数据库设计:

  • 数据冗余,浪费空间
  • 数据库插入和删除都会麻烦、异常(屏蔽使用物理外键)
  • 程序的性能差

良好的数据库设计:

  • 节省内存空间
  • 保证数据库的完整性
  • 方便我们开发系统

软件开发中,关于数据库的设计

  • 分析需求:分析业务和需求处理的数据库的需求
  • 概要设计:设计关系图 E-R图

设计数据库的步骤(个人博客)

  • 收集信息,分析需求
  • 用户表(用户登录注销,用户的个人信息,写博客、创建分类)
  • 分类表(文章分类,谁创建的)
  • 文章表(文章的信息)
  • 评论表 (评论的信息)
  • 友链表(友链信息)
  • 自定义表(系统信息,某个关键的字,或者一些主字段) key:value
  • 标识实体(把需求落地到每个字段)

9.2三大范式(了解即可)

为什么需要数据库规范化?

  • 信息重复
  • 更新异常
  • 插入异常
  • 无法正常显示信息
  • 删除异常
  • 丢失有效的异常

三大范式

  • 第一范式:要求一张表中的数据每一列都是不可分割的原子项数据
  • 第二范式(满足第一范式):消除部分依赖,要求一张表中的每一列都完全依赖于主键(针对于组合主键),也就是不会出现某一列只和部分主键相关。
  • 第三范式(满足第二、三范式):消除传递依赖,要求一张表中的每一列都和主键是直接依赖的,不是间接依赖。
    规范数据库设计
    规范性和性能的问题
    关联查询的表不能超过三张表
  • 考虑商业化的需求和目标(成本,用户体验)数据库的性能更加重要
  • 在考虑性能问题的时候,需要适当考虑一下规范性。
  • 故意给某些表增加一些冗余的字段(从多表查询编程单表查询)
  • 估计增加一些计算列(从大数据量变为小数据量的查询:索引)

10.JDBC(重点)

10.1数据库驱动

驱动:声卡、显卡、数据库

神通数据库创建表空间java_后端_17


我们的程序会通过数据库驱动和数据库打交道!

10.2JDBC

对数据库的统一规范JDBC(java操作数据库)

10.3第一个JDBC程序

1、创建一个普通项目
2、导入数据库驱动
3、编写测试代码

package lesson01;

import java.sql.*;

//第一个JDBC程序
import java.sql.*;

public class JdbcFirstDemo {
    public static void main(String[] args) {

        try {
            //1.注册驱动 固定写法,加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //2.创建连接
            // useUnicode=true
            // characterEncoding=utf8
            // useSSL=true
            String url = "jdbc:mysql://localhost:3306/jdbcstudy?serverTimezone=UTC&useSSL=false";
            String username = "root";
            String password = "123456";

            Connection connection = DriverManager.getConnection(url,username , password);
            //3.连接成功,返回数据库对象
            String sql = "select * from users";
            Statement statement = connection.createStatement();
            //4.执行sql
            ResultSet resultSet = statement.executeQuery(sql);
            //5.遍历结果集
            while (resultSet.next()){
                System.out.println("id:"+resultSet.getString("id")+"  name:"+
                        resultSet.getString("name")
                        +"  password: "+resultSet.getString("password"));
            }
            resultSet.close();
            statement.cancel();
            connection.close();

        } catch (Exception e) {

        }

    }
}

DriverManager

//1.注册驱动 固定写法,加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //Connection 代表数据库
			//数据库设置自动提交

URL

String url = "jdbc:mysql://localhost:3306/jdbcstudy?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=utf8";
String url = "jdbc:mysql://localhost:3306/jdbcstudy";

jdbc:mysql://主机名:端口号/数据库名?参数1&参数2&参数3

//oracle  --1521
jdbc:oracle:thin:@localhost:1521:sid

Connection

connection.commit();  //设置提交事务
connection.isReadOnly();//是否只读
connection.setAutoCommit(true);//设置事务自动提交

Statement

statement.executeQuery(sql);//执行查询,返回一个结果集
statement.execute();//执行任何SQL
statement.executeUpdate();//执行更新操作:插入、修改、删除,返回受影响的行数

ResultSet查询的结果集:封装了所有的查询结果

--- 在不知道类型的情况下使用getObject类型
resultSet.getObject(); 

-- 在知道类型的情况下使用对应类型
resultSet.getString();
resultSet.getBigDecimal();
resultSet.getFloat();
resultSet.getDate();
resultSet.getDouble();
resultSet.getInt();
resultSet.getLong();
...
遍历,指针
resultSet.next();//移动到下一个
resultSet.beforeFirst();//移动到第一个
resultSet.afterLast();//移动到最后面
resultSet.previous();//移动到前一行
resultSet.absolute(row);//移动到指定行

释放资源

resultSet.close();
statement.cancel();
connection.close();

10.4、statement

jdbc中的statement 用于向数据库发送SQL语句,想要完成对数据库的增、删、改、查,只需要通过这个对象向数据库发送增删改查语句即可

Statement 对象的 executeUpdate方法,用于向数据库 发送增、删、改的SQL语句,executeUpdate执行完后,将会返回一个整数(即增删改语句导致数据库几行数据发生了变化)

Statement. executeQuery()方法用于向数据库发送 查询语句,executeQuery()方法返回代表查询结果的ResultSet对象。

insert

Statement statement = connection.createStatement();
String sql = "insert into user(...) values(...)"
int num = statement.executeUpdate(sql);
if(num > 0){
    System.out.println("插入成功");
}

CRUD操作–delete

Statement statement = connection.createStatement();
String sql = "delete from user where id = 1"
int num = statement.executeUpdate(sql);
if(num > 0){
    System.out.println("删除成功");
}

CRUD操作–update

Statement statement = connection.createStatement();
String sql = "update user set name='' where id = 1"
int num = statement.executeUpdate(sql);
if(num > 0){
    System.out.println("修改成功");
}

CRUD操作–select

Statement statement  = connection.createStatement();
String sql = "select * from user";
ResultSet rs = statement.executeQuery(sql);
while(rs.next()){
    //根据获取列的数据类型,分别调用rs的相应方法映射到java对象中
}

10.5sql注入问题

sql注入问题 sql存在漏洞
sql 存在漏洞,会被攻击,导致数据泄漏。SQL会被拼接

preparedStatement 可以防止SQL 注入,效率更好!

10.5PreparedStatement对象

可以防止sql注入,并且效率更高。
使用?占位符
st.setString(4,“1”);
填充的时候用set来填充

10.6 JDBC事务

例子:

package le4;

import le2.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class TestTransaction {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            //关闭自动提交功能,开始事务
            conn.setAutoCommit(false);
            String sql1 = "UPDATE account set money=money-100 WHERE name='A'";
            st = conn.prepareStatement(sql1);
            st.executeUpdate();

            //会导致操作失败,事务回滚。
            int x=1/0;

            String sql2 = "UPDATE account set money=money+100 WHERE name='B'";
            st = conn.prepareStatement(sql2);
            st.executeUpdate();

            //业务完毕提交事务
            conn.commit();
            System.out.println("Success");

        } catch (SQLException throwables) {
            //如果失败则回滚
            try {
                conn.rollback();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            throwables.printStackTrace();
        } finally {
            JdbcUtils.release(conn,st,rs);
        }
    }
}

10.7数据库连接池

数据库连接——执行完毕——释放十分消耗资源
池化技术:准备一些预先的资源,过来就连接,使用预先准备好的服务。
省去connection.