MySQL

1、初始数据库

1.1、什么是数据库

数据库(DB—DataBase)

概念:数据仓库,安装在操作系统之上的软件,可以存储大量的数据。

作用:存储数据、管理数据

1.2、数据库分类

关系型数据库:(SQL)

  • MySQL、Oracle、SqlServer、DB2、SQLllite
  • 通过表和表之前,行和列之前的关系进行数据的存储。学员信息表、考勤表…

非关系型数据库:(No SQL)

  • Redis、MongDB
  • 非关系型数据库,对象存储,通过对象的自身的属性来决定

DBMS(数据库管理系统)

1.3、数据库语言

  • DDL——定义
  • DML——操作
  • DQL——查询
  • DCL——控制

2、操作数据库

mysql关键字不区分大小写

2.1、数据库

  1. 创建数据库

IF EXISTS 、IF NOT EXISTS (可选)——表示判断存在、是否存在。例如:

CREATE DATABASES IF NO EXISTS BB;

  1. 删除数据库

DROP DATABASES IF EXISTS BB;

  1. 使用数据库

USE BB;——如果使用的表名或者字段名是一个特殊字符,那么就需要这样使用 ``(加上电脑键盘Tab键上一个键)

  1. 查看数据库

SHOW DATABASES;

2.2、数据库的列类型

数值

  • 整数:

  • tinyint 十分小的数据 1个字节

  • smallint 较小的数据 2个字节

  • mediumint 中等大小的数据 3个字节

  • int 标准的整数 4个字节——常用(对应Java中int类型)

  • bigint 较大的数据 8个字节(对应“long”类型)

  • 小数:

  • float 浮点数(单精度) 4个字节

  • double 浮点数(双精度) 8个字节

  • decimal 字符串形式的浮点数(一般金融计算的时候使用)

字符串

  • char 字符串固定大小 0~255
  • varchar 可变字符串 0~65535——常用(对应Java中String)
  • tinytext 微型文本 2^8-1
  • text 文本串 2^16-1

时间和日期

  • date YYYY-MM-DD 日期格式
  • time HH:mm:ss 时间格式
  • datetime YYYY-MM-DD HH:mm:ss 常用的时间格式
  • timestamp 时间戳 1970.1.1到现在的毫秒数
  • year 年份表示

null

  • 没有值,未知
  • 不要使用NULL进行运算,结果也为NULL。没有意义

2.3、数据库的字段属性

Unsigned:

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

zerofill:

  • 0填充
  • 不足的位数,使用0来填充。例如:int长度给定为“3”,但是我们只输入了一个数“5”,那么就会填充为“005”

自增:

  • 自动在上一条记录的基础上+1(默认)
  • 通常用来设计唯一的主键,必须是整数类型
  • 可以自定定义设计主键自增的起始值和步长

非空:

  • 设定默认值为 not null,如果不进行赋值,那么会报错
  • null,如果不填写值,默认为null

默认:

  • 设置默认值(如果不指定该列的值,则就会有默认值。)

2.4、创建数据库表


-- 注意点:使用英文括号,表的名称 和 字段尽量使用``括起来
-- AUTO_INCREMENT 自增
-- NOT NULL 不为空
-- COMMENT 描述注释
-- DEFAULT 默认值
-- PRIMARY KEY 主键,一般一个表只有一个唯一的主键;可以直接写在id那一行的后面,但是建议写在最后,这样一眼就能看出表的主键。
-- ENGINE = INNODB 存储引擎INNODB
-- DEFAULT CHARSET = UTF8 默认格式UTF8
-- 字符串可使用单引号/双引号括起来
-- 所有的语句后面加英文的逗号,最后一个不用加
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 '密码',
	`birthday` DATETIME DEFAULT '0000-00-00' COMMENT '出生日期',
	 PRIMARY KEY (`id`)
)ENGINE = INNODB DEFAULT CHARSET = UTF8

常用命令

-- 查看创建数据库的语句
SHOW CREATE DATABASE school
-- 查看student数据表的定义语句
SHOW CREATE TABLE student
-- 显示表的结构
DESC student

2.5、数据表的类型

-- 关于数据库引擎
INNODB	默认使用
MYISAM	早前使用
MYISAMINNODB
事务支持不支持支持
数据行锁定(锁定一行)不支持支持
外检约束不支持支持
全文检索支持不支持
表空间大小较小较大(约为前者2倍)

常规使用操作:

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

在物理空间存在的位置

所有的数据库文件都存在data目录下,一个文件夹就对应一个数据库

本质还是文件的存储

MySQL引擎在物理文件上的区别

  • INNODB在数据库表中只有一个*.frm文件,以及上级目录下的ibdata1文件
  • MYISAM对应文件
    • *.frm——表结构的定义文件
    • *.MYD——数据文件(data)
    • *.MYI——索引文件(index)

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

CHARSET = UTF8

不设置的话,会默认mysql默认的字符集编码(不支持中文)

MySQL的默认编码是Latin1,不支持中文

在my.ini中配置默认的编码

character-set-server=utf8

2.6、修改 删除表

修改

-- 修改表名 
-- ALTER TABLE 旧表名 RENAME as 新表名
ALTER TABLE student RENAME as students

-- 增加表的字段 
-- ALTER TABLE 表名 ADD  字段名 列属性
ALTER TABLE student ADD  age INT(11)

-- 修改表的字段(分为两种:重命名和修改约束)
ALTER TABLE student MODIFY age VARCHAR(11) --修改约束
ALTER TABLE student CHANGE age age1 INT(1) --字段重命名

删除

-- 删除表的字段
ALTER TABLE student DROP age1

-- 删除表(如果表存在再删除)
DROP TABLE IF EXISTS student

所有的创建和删除尽量加上判断,以免报错

3、MySQL数据管理

3.1、外键

CREATE TABLE IF NOT EXISTS `grade`( 
	`gradeid` INT(4) NOT NULL AUTO_INCREMENT COMMENT '年级id',
	`gradename` VARCHAR(30) NOT NULL  COMMENT '年级名称',
	 PRIMARY KEY (`gradeid`)
)ENGINE = MYISAM DEFAULT CHARSET = UTF8

-- 学生表的gradeid 字段要去引用年级表的gradeid
-- 定义外键key
-- 给这个外键添加约束
-- CONSTRAINT 约束
-- 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 '密码',
	`birthday` DATETIME DEFAULT '0000-00-00' COMMENT '出生日期',
	`gradeid` INT(10) NOT NULL COMMENT '学生的年级',
	 PRIMARY KEY (`id`),
	 KEY `FK_gradeid` (`gradeid`),
	 CONSTRAINT `FK_gradeid` FOREIGN KEY (`gradeid`) REFERENCES `grade` (`gradeid`)
)ENGINE = MYISAM DEFAULT CHARSET = UTF8

删除有外键关系的表的时候,必须要先删除引用别人的表(从表),在删除被引用的表(主表)。不然存在主外键表的关系删除会报错,删除不掉。

方式二:创建表成功后,再添加外键约束(依然是上面那个例子,我们在创建表的时候,不进行外键的添加,就是单纯的创建表的语句。在表创建完成之后,再进行添加外键约束的操作)

-- ALTER TABLE 表名
-- ADD CONSTRAINT	约束名	 FOREIGN KEY (作为外键的列)	REFERENCES	哪个表 (哪个字段)
ALTER TABLE `student`
ADD CONSTRAINT `FK_gradeid` FOREIGN KEY (`gradeid`) REFERENCES `grade` (`gradeid`)

以上的操作都是物理外键,数据库级别的外键,不建议这样使用。避免数据库过多造成困扰。比如:删都删不掉

  • 数据库就是单纯的表,只用来存数据(行—数据和列—字段)
  • 如果想要使用多张表的数据,想使用外键的操作,可用程序来实现。编写代码来查询对应的字段

3.2、DML语言

数据库意义: 数据存储、数据管理

DML语言:数据库操作语言

  • insert
  • update
  • delete

3.3、添加

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

添加多条数据操作:

insert into 表名([字段名1],[字段名2],[字段名3])

values (‘值1’,‘值2’,‘值3’),

(‘值1’,‘值2’,‘值3’),

(‘值1’,‘值2’,‘值3’);

注意事项:

  1. 字段和字段之间使用逗号隔开
  2. 字段是可以省略的,但是后面的值必须要是一一对应
  3. 可以同时插入多条数据,values后面的值,需要使用逗号隔开即可——values () , () …

3.4、修改

update 表名 set colnum_name = value,[colnum_name = value,…] where [条件]

注意事项:

  1. colnum_name是数据库的列
  2. 条件是筛选的条件,如果没有指定,则会修改所有的列。
    • 条件操作符会返回布尔值,条件包括:
    • =、<>或!=、>、<、>=、<=、BETWEEN…AND…、AND、OR
  3. value是一个具体的值,也可以是一个变量
  4. 多个设置的属性之间,使用逗号隔开

3.5、删除

delete命令

delete from 表名 [where 条件]

-- 删除数据(避免这样写,删全部删除)
delete from `student`

-- 删除指定数据
delete from `student` where id = 1 ;

TRUNCATE命令

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

TRUNCATE `student`

delete 和 TRUNCATE 的区别

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

不同点:

  • TRUNCATE 重新设置自增列计数器会归零
  • TRUNCATE不会影响事务

delete删除表数据后,重启数据库(net start),会出现的现象:

  • INNODB引擎:自增列会重新从1开始(存在内存中的,断电即失)
  • MYISAM引擎:会继续从上一个自增量开始(存在文件中的,不会丢失)

4、DQL查询数据

4.1、DQL(Data Query Language:数据查询语言)

SELECT完整的语法:筛选条件排序
在这里插入图片描述

4.2、 指定查询字段

-- 查询全部的学生
SELECT * FROM student

-- 查询指定字段
SELECT `studentNo` , `studentName` FORM student

-- 给字段和表起一个别名
SELECT `studentNo` AS 学号 , `studentName` AS 姓名 FORM student AS s

-- 函数 CONCAT(a,b)
SELECT CONCAT('姓名:',studentName) AS 新的名字 FROM student

去重复

SELECT DISTINCT `StudentNo` FROM  student

数据库的列(表达式)

-- 查询系统版本(函数)
SELECT VERSION()
-- 用来计算结果(表达式)
SELECT 100*3-1 AS 计算结果
-- 查询自增的步长(变量)
SELECT @@auto_increment_increment

-- 学员考试成绩 +1分
SELECT studentNO , studentScore + 1 AS '加分后' FROM student 

4.3、where条件子句

作用:检索数据中符合条件的值

搜索的条件由一个或者多个表达式组成,结果为布尔值。

逻辑运算符

尽量使用英文字母的那一种写法

运算符语法描述
and &&a and b a&&b逻辑与,两个都为真,结果为真
or ||a or b a ||b逻辑或,其中一个结果为真,则结果为真
not !not a ! a逻辑非,真为假,假为真

模糊查询

操作符/运算符语法描述
IS NULLa is null如果为null,结果为真
IS NOT NULLa is not null如果不为null,结果为真
BETWEEN…AND…a between b and c若a在b和c之间,则结果为真
LIKEa like bSQL匹配,如果a匹配b,则结果为真
INa in (a1,a2,a3)假设a在a1,或者a2…其中的某一个值中,结果为真
-- 查询姓王的同学
-- LIKE %(代表0到任意个字符)
SELECT `studentNo`,`studentName` FROM `student`
WHERE `studentName` LIKE '王%';

-- 查询姓王的同学,名字后面只有一个字
-- _(匹配一个字符)
SELECT `studentNo`,`studentName` FROM `student`
WHERE `studentName` LIKE '王_';

-- 查询姓王的同学,名字后面只有两个字
SELECT `studentNo`,`studentName` FROM `student`
WHERE `studentName` LIKE '王__';

-- 查询名字中间有子的同学
-- 假如你使用的是'_子_',可是你不能保证别人的名字只有三个字的情况,所以要使用%
SELECT `studentNo`,`studentName` FROM `student`
WHERE `studentName` LIKE '_子_';

-- IN的操作(具体的一个或者多个值)
-- 查询1001,1002,1003号学员
SELECT `studentNo`,`studentName` FROM `student`
WHERE `studentNo` IN ('1001','1002','1003');

-- 查询在北京的同学
-- 查询在北京不能写的查询是 IN ('%北京%'),因为括号内表示的是一个或者多个值是具体的,不能使用模糊操作。
SELECT `studentNo`,`studentName` FROM `student`
WHERE `address` IN ('北京','安徽','湖北');

-- 地址为空(null的情况还有''的情况)
SELECT `studentNo`,`studentName` FROM `student`
WHERE `address` == null OR address IS NULL;

-- 不为空
SELECT `studentNo`,`studentName` FROM `student`
WHERE `address`IS NOT NULL;

4.4、连表查询

JOIN

1b3d7ac3283a8b2bed002b98af8318a5
在这里插入图片描述

-- 查询参加了考试的同学(学号,姓名,科目编号,分数)
-- 这些信息来源于两个表(student表和result表)

/* 思路分析:
1.分析查询的字段来自哪些表?
2.确定使用哪种连接查询?
3.确定交叉点(这两个表中哪个数据是相同的)
判断的条件:学生表中的studentNo = 成绩表中的studenNo
*/
SELECT s.studentNO,studentName,subjectNo,studentResult
FROM student AS s
INNER JOIN result r
WHERE s.studentNO = r.studentNO;
-- 也可以把WHERE改成ON的写法
SELECT s.studentNO,studentName,subjectNo,studentResult
FROM student AS s
INNER JOIN result AS r
ON s.studentNO = r.studentNO;


-- Right JOIN
-- AS别名可以省略不写
SELECT s.studentNO,studentName,subjectNo,studentResult
FROM student s
RIGHT JOIN result r
ON s.studentNO = r.studentNO;

-- LEFT JOIN
SELECT s.studentNO,studentName,subjectNo,studentResult
FROM student s
LEFT JOIN result r
ON s.studentNO = r.studentNO;
操作描述
INNER JOIN如果表中至少有一个匹配,就返回行
LEFT JOIN会从左表中返回所有的值,即使右表中没有匹配
RIGHT JOIN会从右表中返回所有的值,即使左表中没有匹配
-- 查询参加考试的同学信息(学号,姓名,科目名,分数)

/* 思路分析:
1.分析查询的字段来自哪些表?(student表、result表、subject表)
2.确定使用哪种连接查询?
3.确定交叉点
判断的条件:学生表中的studentNo = 成绩表中的studenNo
*/

-- 这里为什么使用RIGHT,因为是查询参加考试的同学信息,所以说是要以考试表为主表,result在右边,所以以右表为主表,返回右表所有的值
-- 第一步,想连接两个表查询,得到学号,姓名,科目编号,分数
SELECT s.studentNO,studentName,subjectNo,studentResult
FROM student s
RIGHT JOIN result r
ON s.studentNO = r.studentNO;

-- 第二步,连接科目表,以科目编号相等,查到科目名
SELECT s.studentNO,studentName,subjectName,studentResult
FROM student s
RIGHT JOIN result r
ON s.studentNO = r.studentNO
INNER JOIN subject sub
ON r.subjectNo = sub.subjectNo;


-- 假设存在多张表查询的情况,先查询两张表然后再慢慢增加

自连接

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

假设现在存在这样的一张表,描述的是父目录与子目录的关系,同在一张表中。

在这里插入图片描述
操作:查询父类对应的子类关系

SELECT  a.categoryName AS '父栏目', b.categoryName AS '子栏目'
FROM category AS a , category AS b
WHERE a.categoryid = b.pid;

4.5、分页和排序

排序

-- 排序:升序ASC   降序DESC 
-- ORDER BY 通过哪个字段排序,怎么排序

ORDER BY studentNo ASC;
ORDER BY studentNo DESC;

分页

-- 分页的意义:缓解数据库压力,给人的体验更好
-- 类似百度图片这种的,搜索出来能一直往下拉,一直加载刷新的,称之为“瀑布流”

-- 分页:每页只显示5条数据
-- 语法:limit 起始值,页面大小


-- 第一页 limit 0,5    (1-1)*5
-- 第二页 limit 5,5		(2-1)*5
-- 第三页 limit 10,5		(3-1)*5
-- 第N页  limit  			 (n-1)*pageSize,pageSize
-- pageSize:页面大小,(n-1)*pageSize起始值,n当前页
-- 数据总数/页面大小 = 总页数

4.6、子查询

之前在WHERE中使用的条件都是固定的一个值,比如说分数大于80,ID等于多少。where(值是固定的)

现在WHERE中出现的条件的值是计算出来的结果。where(这个值是计算出来的)

本质:在where语句中嵌套一个子查询语句

where (select * from …)

执行顺序:由里及外

4.7、分组和过滤

在这里插入图片描述

5、MySQL函数

5.1、常用函数

SELECT ABS(-8) -- 绝对值 8
SELECT CEILING(9.4) -- 向上取整 10
SELECT FLOOR(9.4) -- 向下取整 9
SELECT RAND() -- 返回一个 0~1 之间的随机数
SELECT SIGN(10) -- 判断一个数的符号 0返回0,负数返回-1,正数返回1

-- 字符串函数
SELECT CHAR_LENGTH('你好') -- 字符串长度
SELECT CONCAT('你','好') -- 拼接字符串
SELECT INSERT('我爱你',1,2,'超级') -- 查询,从某个位置开始替换某个长度
SELECT LOWER('Hello') -- 全部变小写
SELECT UPPER('Hello') -- 全部变大写
SELECT INSTR('hello','h') -- 返回第一次出现的字符串索引
SELECT REPLACE('大家好','大家','你们') -- 替换出现的指定字符串
SELECT SUBSTR('坚持就能成功',4,5) -- 返回指定的字符串 (源字符串,截取的位置,截取的长度)
SELECT REVERSE('赵兄拖你帮我办点事') -- 反转

-- 查询姓 王 的同学,替换为李
SELECT REPLACE(studentName,'王','李') FROM studen
WHERE studentName LIKE '王%';

-- 时间和日期函数
SELECT CURRENT_DATE() -- 获取当前日期
SELECT CURDATE() -- 获取当前日期
SELECT NOW() -- 获取当前的时间
SELECT LOCALTIME() -- 本地时间
SELECT SYSDATE() -- 系统时间

SELECT YEAR(NOW()) -- 年
SELECT MONTH(NOW()) -- 月
SELECT DAY(NOW()) -- 日
SELECT HOUR(NOW()) -- 时
SELECT MINUTE(NOW()) -- 分
SELECT SECOND(NOW()) -- 秒

-- 系统
SELECT SYSTEM_USER()
SELECT USER()
SELECT VERSION()

5.2、聚合函数

函数名称描述
COUNT()计数
SUM()求和
AVG()平均值
MAX()最大值
MIN()最小值
-- 都能够统计表中的数据
SELECT COUNT(`列名`) FROM student; -- COUNT(字段),会忽略所有的null值
SELECT COUNT(*) FROM student; -- COUNT(*),不会忽略null值,本质是计算行数
SELECT COUNT(1) FROM student; -- COUNT(1),不会忽略null值,本质是计算行数

5.3、数据库级别的MD5加密

MD5主要是增强算法复杂度和不可逆,MD5不可逆,具体的值的MD5是一样的。

MD5破解网站的原理,后台有一个字典,MD5加密后的值和加密前的值进行循环匹配。所以说不一定能全部解密出来,有对应的对应的值才会一个一个输出。

在这里插入图片描述

6、事务

6.1、什么是事务

举例:

  1. SQL执行 A给B转账
  2. SQL执行 B收到A的钱

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

事务要表达的意思可以概括为:要么都成功 ,要么都失败。不能是A的钱少了,但是B的钱没增加。钱的总数应该是一样的。

事务原则:ACID 原子性、一致性、隔离性、持久性

  • 原子性:

    • 针对同一个事务,表示这两个步骤(转账)一起成功,或者一起失败,不能只发生其中一个动作。
  • 一致性:

    • 针对一个事务操作前与操作后的状态一致。最终一致性,不论转账的过程怎么转,最后的总数肯定是一致的。比如说:你有500元,我有500元,转账到最后的结果一定是1000元。
  • 隔离性:

    • 针对多个用户同时操作,排除其他事务对本次事务的影响。多人转账的情况,互不影响。数据库为每一个用户开启事务,不能被其他的事务的操作数据所干扰,事务之间要相互隔离
  • 持久性:

    • 事务结束后的数据不随着外界原因导致数据丢失。服务器断电等情况出现,在操作前(事务还没提交)数据应恢复到原装,在操作后(事务已经提交)持久化到数据库。事务一旦提交就不可逆

事务的隔离级别(隔离所导致的一些问题)

  • 脏读:
    • 指一个事务读取了另一个事务未提交的数据。
  • 不可重复读:
    • 在一个事务内读取表中的某一行数据,多次读取结果不同。(这个不一定错误,只是某些场合不对)
  • 幻读(虚读):
    • 在一个事务内读取到了别的事务插入的数据,导致前后的读取不一致。(一般是行影响,多了一行)
-- =====================事务==================

-- MySQL是默认开启事务自动提交的
SET autocommit = 0 -- 关闭
SET autocommit = 1 -- 开启(默认开启)

-- 手动处理事务
SET autocommit = 0 -- 关闭自动条件

-- 事务开启
START TRANSACTION -- 标记一个事务的开始,从这个之后的 SQL 都是在同一组事务内

SQL操作1
SQL操作2
......

-- 提交(持久化) 成功提交
COMMIT

-- 回滚(回到原来的样子) 失败回滚
ROLLBACK 

-- 事务结束 
SET autocommit = 1  -- 开启自动提交

-----------------保存点(比如说:保存的游戏关卡存档)
SAVEPOINT 保存点名 -- 设置一个事务的保存点
ROLLBACK TO SAVEPOINT 保存点名 -- 回滚到保存点
RELEASE SAVEPOINT 保存点名 -- 撤销保存点

在这里插入图片描述

7、索引

MySQL官方对索引的定义为:索引((Index)是帮助MySQL高效获取数据的数据结构。

提取句子主干,就可以得到索引的本质:索引是数据结构。

通过索引可以让我们更快速的获取SQL里面的结果

7.1、索引的分类

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

  • 主键索引 PRIMARY KEY
    • 唯一的标识,主键不可重复,只能有一个列作为主键
  • 唯一索引 UNIQUE KEY
    • 避免重复出现的列。唯一索引可以重复,多个列都可以标识为唯一索引
  • 常规索引 KEY/INDEX
    • 默认的。可以使用关键字KEY或INDEX来设置
  • 全文索引 FullText
    • 在特定的数据库引擎下才有
    • 作用:快速定位数据

7.2、索引测试

基础语法:

  • 添加索引的方法
    • 第一种是在创建标的时候给字段增加上索引;
    • 第二种是创建完毕后,再增加索引。如下:

在这里插入图片描述

添加索引的第三种方法:

-- id_表名_字段名(命名规范)
-- CREATE INDEX 索引名 on 表(字段)
CREATE INDEX id_app_user_name ON app_user(`name`);

7.3、索引原则

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

8、权限管理和备份

8.1、用户管理

SQL命令操作

用户表:mysql.user

-- 创建用户 CREATE USER 用户名 IDENTIFIED BY '密码'
CREATE USER 'wang' INENTIFIED BY '123456';

-- 修改当前用户密码
SET PASSWORD = PASSWORD('88888');

-- 修改指定用户密码
SET PASSWORD FOR wang = PASSWORD('111111');

-- 重命名 RENAME USER 原来名字 TO 新的名字;
RENAME USER wang TO wang2;

-- 用户授权 ALL PRIVILEGES(全部的权限),库名.表名(*.*给全部的库和全部的表的权限)
-- ALL PRIVILEGES 除了给别人授权,其他的都干
GRANT ALL PRIVILEGES ON *.* TO wang2;

-- 查看权限
SHOW GRANTS FOR  wang2; -- 查看指定用户的权限
SHOW GRANTS FOR root@localhost
-- ROOT用户权限:GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY PASSWORD '*81F5E21E35407D884A6CD4A731AEBFB6AF209E1B' WITH GRANT OPTION

-- 撤销权限 REVOKE		哪些权限	在哪个库撤销	给哪个用户撤销
REVOKE ALL PRIVILEGES ON *.* FROM wang2;

-- 删除用户
DROP USER wang2;

8.2、MySQL备份

为什么要备份数据:

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

MySQL数据库的方式:

  • 直接拷贝屋里文件(在磁盘的data目录)
  • 在可视化工具中手动导出
  • 使用命令行导出 mysqldump(命令行使用)
#mysqldump -h主机 -u用户名 -p密码 数据库 表名 > 物理磁盘位置/文件名
mysqldump -hlocalhost -uroot -proot school student >D:/abc.sql

-- 一个数据库中的多张表 
#mysqldump -h主机 -u用户名 -p密码 数据库 表名1 表名2 表名3 > 物理磁盘位置/文件名

-- 一整个数据库
#mysqldump -h主机 -u用户名 -p密码 数据库 > 物理磁盘位置/文件名

-- 导入
-- 登录的情况下,切换到指定的数据库(如果是导入这个数据库中的表的情况下,如果是导入整个数据库就没有切换的必要了)
-- source 备份文件
source d:/a.sql

-- 没有登录的情况下,其实也是需要登录的。
mysql -u用户名 -p密码 库名 < 备份文件

9、规范数据库设计

9.1、为什么需要设计数据

当数据库比较复杂的时候,业务逻辑比较复杂时候,就需要设计。如果只是单纯的一张表,那肯定是不需要怎么设计的

不好的数据库设计所产生的问题:

  • 数据冗余,浪费空间
  • 数据插入和删除等操作会比较麻烦更甚出现异常(屏蔽使用物理外键)
  • 程序的性能差

良好的数据库设计:

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

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

  • 分析需求
  • 设计关系图E-R图

举例分析:

在这里插入图片描述

9.2、三大范式

三大范式

第一范式(1NF)

要求数据库表的每一列都是不可分割的原子数据项

保证每一列不可再分

第二范式(2NF)

前提:满足第一范式

每张表只描述一件事情

第三范式(3NF)

前提:满足第一范式和第二范式

第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。

规范性 和 性能的问题

在阿里的手册描述中说,关联查询的表不得超过三张,但是按照这样的细分的方式,查询的信息要超过三张也很容易。所以有时候就需要进行取舍。

  • 考虑商业化的需求和目标(成本,用户体验等角度出发)数据库的性能更加重要
  • 在规范性能的问题时,需要适当的考虑规范性。
  • 有时候故意给表增加一些冗余的字段。(比如:订单表、和商品表。有时候会在订单宝中放入商品的信息。这样就从需要多表连接查询变为单表查询)
  • 故意增加一些计算列(从大数据量降低为小数据量的查询)
  • 适当增加索引(索引树占空间占内存)

10、JDBC

10.1 数据库驱动

在这里插入图片描述

应用程序 跟 数据库无法挂钩

于是乎需要在空间增加一层数据库驱动。驱动是由数据库厂商提供的,比如说mysql有mysql的驱动,oracle有oracle的驱动。

程序会通过数据库驱动和数据库打交道。

10.2、JDBC

由于不同的数据库需要不同的驱动,那如果有十个不同的数据库,就需要写十种程序。肯定是需要避免这种情况出现。

sun公司为了简化开发人员对数据库的统一操作,提供了一个Java操作数据库的规范。称为jdbc

这些规范的实现由具体的厂商去做。对于开发人员来说,只需要掌握jdbc的操作。

在中间再加了一层JDBC的操作

在这里插入图片描述

需要导入一个数据库驱动包 mysql-connector-java

10.3、测试jdbc程序

  1. 创建测试数据库
  2. 创建一个普通的Java项目
  3. 导入数据库驱动(新建lib目录,将驱动放入对应文件夹)
  4. 编写测试代码
    在这里插入图片描述

步骤总结:

  1. 加载驱动
  2. 连接数据库DriverManager
  3. 获得执行sql对象Statement
  4. 获得返回的结果集
  5. 释放连接

JDBC中对象解释

DriverManager

//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Class.forName("com.mysql.jdbc.Driver")//固定写法,加载驱动
  
Connection connection = DriverManager.getConnection('url','username','password');
//connection 代表数据库对象,在数据库中能操作的在这里就能操作。比如说:事务
//数据库设置自动提交
//事务提交
//事务回滚
connection.rollback()
connection.commit()
connection.setAutoCommit()
 

URL

String  url = "jdbc:mysql://localhost:3306/databaseName?
useUnicode=true&characterEncoding=utf8&seSSL=true";

// mysql 默认端口 3306
//格式:jdbc:mysql://主机地址:端口号/数据库名?参数1&参数2&参数3
  
//oracle 默认端口 1521
//格式:jdbc:oracle:thin:@localhost:1521:sid

Statement 执行SQL的对象 PreparedStatement执行SQL的对象

statement.executeQuery()//查询操作使用,返回一个结果集
statement.execut()//可执行任何SQL(既然是可以是查询也可以是修改等操作,所以说是不是存在一个判断的情况,那么执行的效率就会低)
statement.executeUpdate()//更新、插入、删除。都是使用这个,返回一个受影响的行数
statement.executeBatch()//可用作批量操作

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

获得指定的数据类型

resultSet.getObject();//在不知道列类型的情况下使用
//如果知道列的类型就使用指定的类型
resultSet.getString();
resultSet.getInt();
......

遍历(因为存在next,由此得知这是个指针,指针那么就可以进行移动)

resultSet.beforeFirst();//移动到最前面
resultSet.afterLast();//移动到最后面
resultSet.next();//移动到下一个数据
resultSet.previous();//移动到前一行
resultSet.absolute(row); //移动到指定行

10.4、statement对象

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

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

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

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

SQL注入的问题

sql存在漏洞,会被攻击导致数据泄露。其原因是SQL会被拼接为成立的条件。

举例说明:

如果一个用户登录,需要传递“用户名”,“密码”信息。

login("wang’‘,’‘123456’');//调用登录方法

正常拼接的SQL语句:

select * from user where name = “wang” and password = “123456”;//如果能查询得到用户,那么证明用户存在。

同样的实验接下来进行SQL注入的操作

login( " 'or ’ 1 = 1"," 'or ’ 1 = 1");

select * from user where name = ’ ’ or ’ 1 = 1’ and password = ’ ’ or ’ 1 = 1’;

10.5、 PreparedStatementd 对象

PreparedStatementd可以防止SQL注入,效率更高。

  • 新增

在这里插入图片描述

  • 删除

在这里插入图片描述

  • 更新

在这里插入图片描述

  • 查询

在这里插入图片描述

SQL防注入

在这里插入图片描述

10.6、事务

代码实现

  1. 开启事务 conn.setAutoCommit(false); --关闭数据库的自动提交,就会自动开启事务
  2. 一组业务执行完毕,提交事务
  3. 可以在catch语句中显示的定义 回滚 语句,也可以不写。因为默认失败就会回滚。

在这里插入图片描述

10.7、数据库连接池

数据库的执行过程:数据库连接——执行完毕——释放资源

从连接——释放 的这个过程十分浪费系统资源

池化技术:准备一些预先的资源,过来就连接预先准备好的

比如:

银行办理业务的过程概括为:银行开门——为人服务——关门。假如每次来一个人要执行一次这样的操作,肯定就是不合理的。所以可以调整为:银行开门——业务员——为人服务——关门。我们可以提前准备一些业务员来为人进行服务,随时进行等待。所以说连接池就相当于这里所准备的业务员。

所涉及到的新问题,需要多少个业务人员。所以就会有一个连接数的问题。

常用连接数:

最小连接数:

最大连接数:(业务最高承载上限) 超过设置的最大连接数的个数,那就需要排队等待。

等待超时:如果超过这个设置的等待时间。就会断掉。

编写连接池,实现一个接口DataSource

列举目前 开源数据源实现

DBCP

C3P0

Druid:阿里巴巴

使用了这些数据库连接池后,在项目开发中就不需要编写连接数据库的代码了。(代码中获取数据库连接那段代码)

DBCP

需要使用到的jar

commons-dbcp-、commons-pool-

C3P0

需要使用到的jar

c3p0-、mchange-commons-java-

结论

无论使用使用什么数据源,本质还是一样的。一层一层点进代码里面去,最后一层还是实现的DataSource接口不变。方法也就不会变。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值