数据库MySQL详解

数据库详解(MySQL)

一、初始MySQL

1、JavaEE:企业级Java开发 web

前端(页面:展示,数据!)

后台(连接点:连接数据库JDBC,连接前端(控制,控制视图跳转,和给前端传递数据))

数据库(存数据,Txt,Excel,word)

1.1、为什么学习数据库?

1、岗位需求

2、大数据时代

3、被迫需求:需要一个工具来存储数据

4、数据库是所有软件体系中最核心的存在

1.2、什么是数据库

1、数据库,(DB,DataBase)。软件,安装在操作系统之上!SQL语句,可以存储大量的数据,500万!

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

1.3、数据库分类

1、关系型数据库:行、列 (SQL)

  • MySQL,Oracle,SqlServer,DB2,SQLlite
  • 通过表和表之间,行和列之间的关系进行数据的存储,学员信息表,考勤表

2、非关系型数据库: (NoSQL)NOT ONLY SQL

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

3、DBMS(数据库管理系统) :管理和操作数据

  • 数据库的管理软件,科学有效的管理我们的数据。维护和获取数据;
  • MySQL,数据库管理系统

1.4、MySQL简介

MySQL是一个关系数据库管理系统,由瑞典MySQL AB公司开发,现在属于Oracle旗下产品。MySQL是最流行的关系型数据库管理系统之一。关系数据库将数据保存在不同的表中,MySQL所使用的是SQL语言。适用于大中小型网站

官网:https://www.mysql.com/

1.5、安装MySQL

  1. zip下载地址:

https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.19-winx64.zip

  1. 解压
  2. 把这个包放在自己的环境目录下
  3. 添加环境变量
  • 在path中添加bin目录的文件路径D:\JavaEnvironment\mysql-5.7.19\bin
  • 添加成功
  1. 新建mysql配置文件
  • my.ini
【mysqld】
#目录一定要换成自己的
basedir=D:\JavaEnvironment\mysql-5.7.19\
datadir=D:\JavaEnvironment\mysql-5.7.19\data\
port=3306
skip-grant-tables
  1. 安装mysql服务:启动管理员模式下的CMD,并将路径切换至mysql下的bin目录,然后输入mysqld-install(安装mysql)
C:\Windows\system32>cd /d D:\JavaEnvironment\mysql-5.7.19\bin

D:\JavaEnvironment\mysql-5.7.19\bin>mysqld -install

Service successfully installed.

  1. 初始化数据,输入mysqld --initialize-insecure --user=mysql
  • 出现错误:mysqld: [ERROR] Found option without preceding group in config file
  • 解决:把.ini文件另保存为Anis格式,默认是utf-8,导致错误。修改后成功初始化添加data文件
  1. 启动mysql,修改密码(通过命令行)
  • 打开mysql:net start mysql
  • 进入mysql管理界面:mysql -u root -p
  • 更改root密码:
update mysql.user set authentication_string=password('123456') where user='root' and Host='localhost';
  • 最后刷新权限:flush privileges;
  1. 修改.ini文件,删除最后一句skip…
  2. 重启mysql即可正常使用 net start mysql net stop mysql

1.6、安装SQLyog

1)解压----安装-----注册-----连接

  • 新建一个数据库school
  • 新建一张表student

2)每一个sqlyog的执行操作,本质上对应了一个sql,可以在软件的历史记录查看

1.7、连接数据库

命令行连接

mysql -u root -p  --注释
--所有的语句都使用;结尾
show databases; --查看所有的数据库
mysql>use school --切换数据库 use 数据库名
show tables; --查看数据库中所有的表
describe student; --显示数据库中表的信息
create database westos; --创建一个数据库

exit--退出连接
--单行注释
/*  多行注释*/

二、操作数据库

操作数据库–>操作数据库中的表–>操作数据库中表的数据

2.1、操作数据库

  1. 创建数据库
  • mysql语句不分大小写
CREATE DATABASE IF NOT EXISTS westos
  1. 删除数据库
DROP DATABASE IF EXISTS westos
  1. 使用数据库
--如果你的表名或者字段名是一个特殊符号,则加上``
USE `school`
  1. 查看数据库
SHOW DATABASES   --查看所有的数据库

2.2、数据库的列类型

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

  • smallint 较小的数据 2个字节

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

  • int 标准的整数 4个字节(常用)

  • bigint 较大的数据 8个字节

  • float 浮点数 4个字节

  • double 浮点数 8个字节

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

  1. 字符串
  • char 字符串固定大小的 0~255
  • varchar 可变字符串 0~65535(常用)
  • tinytext 微型文本 2^8 -1
  • text 文本串(大型文本) 2^16 -1
  1. 时间日期
  • date YYYY-MM-DD ,日期格式
  • time HH:mm:ss ,时间格式
  • datetime YYYY-MM-DD HH:mm:ss (常用)
  • timestamp 时间戳,1970.1.1到现在的毫秒数
  • year 年份表示
  1. null
  • 没有值,未知
  • 注意,不要使用null进行运算,结果为null

2.3、数据库的字段属性

  1. Unsigned
  • 无符号的整数
  • 声明该列不能为负数
  1. zerofill
  • 0填充的
  • 不足的位数,使用-来填充
  1. 自增
  • 自动在上一天记录的基础上+1(默认)
  • 通常用来设计唯一的主键 index 必须是整数类型
  • 可以自定义设计主键的起始值和步长
  1. 非空 NULL & not NULL
  • not null:不能为空,如果不赋值就会报错
  • NUll:如果不填值默认是null
  1. 默认
  • 设置默认的值!
  • sex,默认值为男,则如果不指定该列的值,则会默认为男

2.4、创建数据库表

--目标:创建一个school数据库
--创建学生表(列,字段)  使用SQL创建
--学号int 登录密码 varchar(20) 姓名、性别 varchar(2),出生日期(datatime),家庭住址,emil
--注意点,使用英文(),表的名称和字段尽量使用``括起来
--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'性别',
`brithday`DATETIME DEFAULT NULL COMMENT '出生日期',
`address`VARCHAR(100)DEFAULT NULL COMMENT'家庭住址',
`emil`VARCHAR(30)DEFAULT NULL COMMENT'邮箱',
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

  • 格式:
CREATE TABLE[IF NOT EXISTS] `表名`(
'字段名'列类型 【属性】【索引】【注释】,
'字段名'列类型 【属性】【索引】【注释】,
'字段名'列类型 【属性】【索引】【注释】,
'字段名'列类型 【属性】【索引】【注释】

)[表类型][字符集设置][注释]
  • 常用命令
SHOW CREATE DATABASE school  --查看创建数据库的语句
SHOW CREATE TABLE student --查看student数据表的定义语句
DESC student --显示表的结构

2.5、数据表的类型

  1. 关于数据引擎
  • INNODB 默认使用:安全性高,事务的处理,多表多用户操作
  • MYISAM 早些年使用的:节约空间,速度较快
  1. 所有的数据库文件都存在data目录下,本质还是文件的存储,一个文件夹就对应一个数据库

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

  3. INNDOB在数据库表里只有一个*.frm文件,以及上级目录下的ibdata1文件

  4. MYISAM对应文件

    • *.frm -表结构的定义文件
    • *.MYD 数据文件(data)
    • *.MYI 索引文件
  5. 设置数据库表的字符集编码

charset=utf8

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

其他设置方法:

  • 在.ini文件中加上一行代码
character-set-server=utf8

2.6、修改删除表

  1. 修改
--修改表
ALTER TABLE student RENAME AS student1

--增加表的字段
ALTER TABLE student1 ADD hobby VARCHAR(4)

--修改表的字段(重命名,修改约束)
ALTER TABLE student1 MODIFY pwd INT(8)  --只能修改约束

ALTER TABLE student1 CHANGE emil emil1 VARCHAR(10) --既可以重命名也可以修改约束

--删除表的字段
ALTER TABLE student1 DROP sex


  • modify只能修改约束,不能重命名
  • change一般用来重命名,放在后面也可以修改约束
  1. 删除(如果表存在则删除)
DROP TABLE IF EXIST student
  • 所有的创建和删除操作尽量加上判断,以免报错

三、MySQL数据管理

3.1、外键

  1. 方式一:在创建表时,增加约束(比较复杂)
--学生表的gradeid字段要去引用年级表的gradeid
--定义外键key
--给这个外键添加约束(执行引用)  reference引用


KEY `FK_gradeid`,
CONSTRAINT `FK_gradeid` FOREIGN KEY(`grade`)REFERENCES `grade`(`gradeid`)
  • 删除有外键关系的表的时候,必须先删除引用别人的表(从表),再删除被引用的表(主表)
  1. 方式二:创建表成功后,添加外键约束
--创建表的时候没有外键关系,添加外键约束
ALTER TABLE `student`
ADD CONSTRAINT `FK_graderid`FOREIGN KEY(`gradeid`)REFERENCES`grade`(`gradeid`)

--公式:
-- ALTER TABLE 表 ADD  CONSTRAINT 约束名  FOREIGN KEY(作为外键的列))REFERENCES 哪个表(哪个字段)
  • 以上操作都是物理外键,数据库级别的外键,不建议使用(避免数据库过多造成困扰)
  • 最佳实现
    • 数据库就是单纯的表,只用来存数据,只有行(数据)和列(字段)
    • 我们想使用多张表的数据,想使用外键,用程序去实现

3.2、DML语言(背下来)

  1. 数据库意义:数据存储,数据管理
  2. DML语言:数据操作语言
  • insert
  • update
  • delete
  1. 添加(insert)
-- 插入语句(添加),一般写插入语句,我们一定要数据和字段一一对应
-- INSERT INTO 表名([字段名1,字段名2,字段名3])values(`值1`,`值2`,`值3`)
--INSERT INTO 表名(`字段名1`)values(`值1`),(`值2`),(`值3`)
INSERT INTO `student`(`id`)VALUES('45678'),('12345')

-- 插入多个字段
INSERT INTO `student`(`name`)VALUES('王也'),('冯宝'),('诸葛青')


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'性别',
`brithday`DATETIME DEFAULT NULL COMMENT '出生日期',
`address`VARCHAR(100)DEFAULT NULL COMMENT'家庭住址',
`emil`VARCHAR(30)DEFAULT NULL COMMENT'邮箱',
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO `student`(`name`,`pwd`)VALUES('张三','123456')
INSERT INTO `student`(`emil`)VALUES('123455666')
INSERT INTO `student`(address)VALUES('江西省南昌市')
INSERT INTO `student`(`name`,`sex`)VALUES('王也','男')
  • 一般写插入语句,我们一定要数据和字段一一对应
  • 字段是可以省略的,但是后面的值必须要一一对应,不能少
  • 可以同时插入多条数据
  1. 修改(update)
  • set原来的值=新值 where指定条件
-- 修改学员名字(用where指定条件,不指定条件会全部修改)
UPDATE `student`SET`name`='诸葛青'WHERE id =1 

-- 修改多个属性,逗号隔开
UPDATE `student`SET`name`='冯宝宝',`sex`='无'WHERE id=3
  • 条件:where 字句 运算符 id 等于某个值,大于某个值,在某个区间内修改…
  • 操作符:
    • 等于 =
    • 不等于 != 或者<>
    • 大于 >
    • 小于 <
    • 在某个区间 between…and…
    • 两个条件都要满足 and
    • 两个条件中一个满足就行 or

  1. 删除(delete)
-- 删除指定数据
--delete from 表名where 条件

DELETE FROM `student`WHERE id=1
  • 一样用where限定条件
  • TRUNCATE:完全情空一个数据库表,表的结构和索引约束不会变
--清空 student表
TRUNCATE `student`
  • delete 和 TRUNCATE的区别
    • TRUNCATE :重新设置,自增列,计数器会归零,不会影响事务
    • 相同:都能删除数据,都不会删除表结构
    • delete:不会影响自增
  • delete删除的问题,重启数据库后,
    • INNODB 自增列会从1开始(因为是存在内存当中的,断电即失)
    • MYISAM 继续从上一个自增量开始(是存在文件中的,不会丢失)

四、DQL查询数据

4.1、DQL

  1. 数据查询语言(Date Query Language)
  • 所有的查询操作都用它 Select
  • 简单的查询和复杂的查询都能做
  • 数据库中最核心的语言,最重要的语句
  • 使用频率最高的语句

4.2、指定查询字段

-- 查询全部的年纪   select 字段 FROM 表
SELECT *FROM `grade`

-- 查询指定字段
SELECT `gradename`FROM `grade`

-- 给结果起一个名字  as
SELECT `gradeid`AS 年级 FROM`grade`
SELECT`studentname`AS 姓名 ,`studentno` AS 学号 FROM`student`



-- 函数 concat(a,b)拼接
SELECT CONCAT('姓名:',studentname)AS 新名字 FROM student

-- 去重 distinct
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 表

4.3、where条件字句

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

尽量使用英文字母

-- 查询学号大于等于5的学生学号和姓名
SELECT `studentno` ,`studentname` FROM `student` WHERE `studentno`>=5

-- 模糊查询 (区间)

SELECT `studentno` ,`studentname` FROM `student` WHERE `studentno` BETWEEN 5 AND 9

-- 除了...之外的(!=) not
SELECT `studentno` ,`studentname` FROM `student` WHERE NOT `studentno` =6

  • 模糊查询:比较运算符
    • is null
    • is not null
    • between and
    • LIKE a like b :SQL匹配,如果a匹配b,则结果为真
    • in a in (a1,a2,a3):假设a在这其中的某一值中,结果为真
-- 模糊查询
-- 查询姓张的同学
-- like 结合 % (代表0到任意个字符),_(代表一个字符),后面几个字就几个_,任意字就%
SELECT `studentno`,`studentname`FROM `student`WHERE `studentname`LIKE'张%'

-- 查询名字中间带宝的
SELECT `studentname`FROM `student`WHERE `studentname`LIKE'%宝%'


-- 查询1,2,3号学生
SELECT`studentname`,`studentno`FROM`student`WHERE`studentno`IN(1,2,3)

-- 查询年级为2的学生的所有信息
SELECT *FROM`student`WHERE`gradeid`IN(2)

-- 查询地址为空的学生 null 或者用 ‘’
SELECT `studentno`,`studentname`FROM `student`WHERE `address`=''

-- 查询地址不为空的学生 not null
SELECT `studentno`,`studentname`FROM `student`WHERE `address`IS NOT NULL



4.4、 联表查询

数据库MySQL详解_第1张图片

1.连接查询思路:

  • 分析需求(需要的信息分别来自哪几张表)
  • 确定使用哪种连接查询
  • 确定交叉点
-- inner join
SELECT studentname,s.studentno,subjectno,studentresult 
FROM student AS s INNER JOIN result AS r
ON s.studentno=r.studentno

-- right join
SELECT studentname,s.studentno,subjectno,studentresult 
FROM student AS s RIGHT JOIN result AS r
ON s.studentno=r.studentno


-- left join
SELECT studentname,s.studentno,subjectno,studentresult 
FROM student AS s LEFT JOIN result AS r
ON s.studentno=r.studentno

区别:

  • inner join: 两张表只要有一个匹配,就返回该行所有的值
  • left join:从左表返回所有的值,即使右表中没有匹配。(左表全集)
  • right join:从右表中返回所有的值,即使左表中没有匹配(右表全集)
-- 查询缺考的同学
-- 分析:因为是查同学,所以不能漏掉同学,所以用leftjoin,再where判断result为null就行
SELECT studentname,s.studentno,subjectno,studentresult 
FROM student AS s LEFT JOIN result AS r
ON s.studentno=r.studentno
WHERE studentresult IS NULL 
  • join on :连接查询
  • where : 等值查询
  1. 自连接
  • 自己的表和自己的表连接,核心:一张表拆为两张一样的表即可
-- 查询父子信息:把一张表看为两个一模一样的表
SELECT a.`categoryname`AS'父栏目',b.`categoryname`AS'子栏目'
FROM `category`AS a,`category`AS b
WHERE a.`categoryid`=b.`pid`

4.5、 分页和排序

  1. 排序 order by
-- 排序:升序 ASC,降序DESC

-- 查询所有学生信息按降序
SELECT *FROM `student`
ORDER BY `studentno`DESC
  1. 分页 limit
  • 为什么要分页:缓解数据压力,给人的体验更好
-- 分页:limit 
-- 语法 limit 0,5  从第一个开始,只显示五个数据;limit 1,5,从第二个值开始,显示五个数据;第一个值是起始值,第二个值是页面大小
-- 分页,每页只显示五页数据


SELECT *FROM `student`
ORDER BY `studentno`DESC
LIMIT 0,5

第n页: (n-1)*pagesize,pagesize

  • 语法: limit (起始下标值,pagesize)

4.6、子查询

  1. 本质:在where语句中嵌套一个子查询的语句
-- 查询数据库结构的所有考试结果(学号,科目编号,成绩),降序排列
SELECT `studentno`,r.`subjectno`,`studentresult`
FROM`result` r
INNER JOIN `subject` s
ON r.subjectno = s.subjectno
WHERE subjectname = '数据库结构'
ORDER BY studentresult DESC

-- 方式二:使用子查询()
SELECT `studentno`,`subjectno`,`studentresult`
FROM `result`
WHERE subjectno =(
SELECT subjectno FROM `subject`
WHERE subjectname = '数据库结构'
)
ORDER BY studentresult DESC

-- 分数不小于80分的学生的学号和姓名
SELECT `studentno`,`studentname`
FROM `student`
WHERE `studentno`=ANY (
SELECT `studentno`FROM `result`
WHERE `studentresult`>80
)
ORDER BY `studentno`DESC


  • 碰到error:Subquery returns more than 1 row:子查询的结果多余一行

产生原因:子查询结果多于一行,即子查询中查询的结果多于一个解决办法;

解决办法:在子查询条件语句后加limit 1,或者 在子查询前加关键字any或 some 或 in(in的用法稍有不同)

WHERE `studentno`=ANY (
SELECT `studentno`FROM `result`
WHERE `studentresult`>80
)
  • 子查询总结:子查询关键在于,同样是找到两张表相同的部分,利用相同的部分连接到另一张表,从而在另一张表里找到其他部分。

4.7、 分组、过滤

-- 查询不同课程的平均分,最高分,最低分

-- 核心:(根据不同课程分组)

SELECT `subjectname`,AVG(`studentresult`)AS 平均分,MAX(`studentresult`),MIN(`studentresult`)
FROM result r
INNER JOIN `subject`sub
ON r.subjectno = sub.subjectno
GROUP BY r.subjectno   -- 通过什么字段来分组
HAVING 平均分 >80   


4.8、 select语法小结

SELECT[ALL| DISTINCT]
[FROM ...]
[left | right | inner join ] -- 联合查询
[where...] -- 指定结果需要满足的条件
[group by...]  -- 指定结果按照哪几个字段来分组
[having...]  --  过滤分组必须满足的次要条件
[order by ...]  -- 指定查询记录按一个或多个条件排序
[limit...]  -- 分页 指定查询的记录从哪条到哪条

五、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('我独缺你一生的了解')  -- 字符串长度  9
SELECT CONCAT('我','是')  -- 拼接字符串
SELECT INSERT('我爱编程',1,2,'超级热爱')  -- 插入替换 超级热爱编程  从某个位置开始替换某个长度的字符串
SELECT LOWER('AA') -- 转换为小写
SELECT UPPER('aa') -- 替换为大写
SELECT INSTR('aaabbccddhjs','d')  -- 返回第一次出现的子串的索引 (从1开始算)
SELECT REPLACE('坚持就能成功','坚持','努力') -- 替换指定字符串  努力就能成功
SELECT SUBSTR('坚持就能成功',3,2)  -- 返回指定字符串  从某个位置开始返回多少个字符串
SELECT REVERSE('aabbcc')  -- 反转字符串

-- 时间和日期函数(记住)
SELECT CURRENT_DATE() -- 获取当前日期  2022-04-09
SELECT NOW() -- 获取当前时间  2022-04-09 15:00:00
SELECT LOCALTIME() -- 本地时间
SELECT SYSDATE()  -- 系统时间
SELECT DAY(NOW()) -- 获取日期

-- 系统
SELECT SYSTEM_USER() -- 获取用户
SELECT USER()  -- 获取用户
SELECT VERSION()  -- 获取版本信息

5.2、聚合函数

  • COUNT() 计数
  • SUM() 求和
  • AVG() 平均值
  • MAX() 最大值
  • MIN() 最小值
-- 聚合函数

-- count():查询一个表中有多少个记录
SELECT COUNT(studentname)FROM `student`  -- count(指定列) 
SELECT COUNT(*)FROM `student`
SELECT COUNT(1)FROM `student`
-- 三者都能计算出数据,区别:
-- count(指定列):会忽略所有的null值
-- count(*):不会忽略null值  本质:计算行数
-- count(1):不会忽略null值  本质:计算行数


-- sum():求总和
SELECT SUM(`studentresult`)AS 总和 FROM `result`


-- avg():求平均值
SELECT AVG(`studentresult`)AS 平均分 FROM `result`


-- min():查最低分
SELECT MIN(`studentresult`)AS 最低分 FROM `result`

-- max():查最高分
SELECT MAX(`studentresult`)AS 最高分 FROM `result`


5.3、 数据库级别的MD5加密

  1. MD5:主要增强算法复杂度和不可逆性
CREATE TABLE `testdemo5`(
`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 `testdemo5`(`id`,`name`,`pwd`)VALUES('1','张三','123456')
INSERT INTO `testdemo5`(`id`,`name`,`pwd`)VALUES('2','李四','123457')

INSERT INTO `testdemo5`(`id`,`name`,`pwd`)VALUES('3','王五','123458')

-- 加密
UPDATE testdemo5 SET pwd = MD5(pwd)WHERE id =1
UPDATE testdemo5 SET pwd = MD5(pwd)WHERE id =2


-- 插入的时候加密
INSERT INTO `testdemo5`(`id`,`name`,`pwd`)VALUES('4','小明',MD5('1234567'))

-- 如何校验:将用户传递进来的密码进行MD5加密,然后比对加密后的值:相同的密码加密后是一样的
SELECT *FROM testdemo5 WHERE `name`='小明'AND pwd = MD5('1234567')




六、事务

6.1、什么是事务

  1. 事务
  • 要么都成功,要么都失败
  • 比如银行转账,要么转账成功(一个发出来一个收到),要么都不成功。
  • 将一组sql放在一批次中去执行
  1. 事务原则
  • 原子性原子性是指事务是一个不可再分割的工作单位,事务中的操作要么都发生,要么都不发生。

  • 一致性数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。 事务前后的数据完整性要保持一致

  • 隔离性多个事务并发访问时,事务之间是隔离的,一个事务不应该影响其它事务运行效果。

  • 持久性 :意味着在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,不会随着外界原因导致数据丢失。事务一旦提交就不可逆,被持久化到数据库中

  1. 隔离所导致的一些问题
  • 脏读 :指一个事务读取了另一个事务为提交的数据
  • 不可重复读 :在一个事务内读取表中的某一行数据,多次读取结果不同
  • 虚读(幻读) :是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致

6.2、执行事务

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

-- 手动处理事务
SET autocommit=0  -- 先关闭自动提交
-- 事务开启
START TRANSACTION  -- 标记一个事务的开始,从这个之后的sql都在同一个事务内


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

 ROLLBACK -- 回滚:回到原来的样子(失败)
 
 SAVEPOINT  -- 保存点 设置一个事务的保存点
 ROLLBACK TO SAVEPOINT  -- 回滚到保存点
 RELEASE SAVEPOINT -- 撤销保存点



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

模拟转账

-- 转账
CREATE DATABASE	shop CHARACTER SET utf8 COLLATE utf8_general_ci

USE shop

CREATE TABLE `acount`(
`id`INT(3)NOT NULL AUTO_INCREMENT,
`name`VARCHAR(30)NOT NULL,
`money`DECIMAL(9,2)NOT NULL,
PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO acount(`name`,`money`)VALUES('A',2000.00),('B',10000.00)

-- 模拟转账
SET autocommit = 0;
START TRANSACTION
UPDATE acount SET money = money-500 WHERE `name`='A'  -- A-500
UPDATE acount SET money = money+500 WHERE `name`='B'  -- B+500

COMMIT; -- 提交事务

ROLLBACK -- 如果提交成功,则回滚不到最初始

SET autocommit = 1 -- 恢复默认值

七、索引

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

7.1、索引的分类

  1. 主键索引 (PRIMARY KEY)
  • 唯一的标识,主键不可重复,只能有一个列作为主键
  1. 唯一索引(UNIQUE KEY)
  • 避免重复的列出现,唯一索引可以重复,多个列都可以标识唯一索引(可以有很多个唯一索引,标记为唯一索引的列同样不能有重复的)
  • 举个例子,一个人只能有一个身份证号(这是主键索引),唯一一个。但是可以有很多其他证件,这些证件都是唯一索引,每个标为唯一索引的列同样不能有重复的数据
  1. 常规索引(KEY/INDEX)
  • 默认的
  1. 全文索引(FULLTEXT)
  • 在特定的数据库引擎下才有
  • 快速定位数据
- 索引的使用
-- 1.在创建表的时候给字段增加索引
-- 2.创建完毕后,增加索引

-- 显示所有的索引信息
SHOW INDEX FROM student

-- 增加一个全文索引
ALTER TABLE `student` ADD FULLTEXT INDEX `studentname`(`studentname`)


-- explain 分析sql执行状况
EXPLAIN SELECT *FROM student  -- 非全文索引 ,查了十行

EXPLAIN SELECT *FROM student WHERE MATCH(studentname)AGAINST('张')  -- 全文索引。只查了一行

7.2、测试索引

  1. 准备工作,创建表,插入100万条数据
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用户表'


-- 插入100万条数据
DELIMITER $$ -- 写函数之前必须要写,当做标志
CREATE FUNCTION mock_data1 ()
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 mock_data1() -- 执行此函数 生成一百万条数据
  1. 测试索引
SELECT *FROM app_user WHERE `name`='用户9999'  -- 查询很慢,耗时接近一秒钟

EXPLAIN SELECT *FROM app_user WHERE `name`='用户9999' -- 查询了992517行,很慢

-- 索引名字:  id_表名_字段名
-- create index 索引名 on 表(字段名)
CREATE INDEX id_app_user_name ON app_user(`name`)
SELECT *FROM app_user WHERE `name`='用户9999'  -- 0.001s查询完毕,只查询了一行,很快,增加了索引

  1. 索引在大数据的时候,区别非常明显

7.3、索引原则

  1. 索引不是越多越好
  2. 不要对经常变动的数据添加索引
  3. 小数据量的表不需要加索引
  4. 索引一般加在常用来查询的字段上(方便查询,节约查询时间)

八、权限管理和备份

8.1、用户管理

  1. SQL yog可视化管理

    点击用户:可以添加、删除用户等操作

  2. SQL命令操作

用户表:mysql.user

  • 本质:对这张表进行增删改查
-- 创建用户  create user 用户名 IDENTIFIED BY 密码
CREATE USER kuangshen IDENTIFIED BY '123456'

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

-- 修改密码(修改指定用户密码)
SET PASSWORD FOR kuangshen = PASSWORD('1234')

-- 给用户重命名
RENAME USER kuangshen TO kuangshen2

-- 用户授权 
GRANT ALL PRIVILEGES ON *.* TO kuangshen2  -- 给全部权限   库.表 to 用户

-- 查询权限
SHOW GRANT FOR kuangshen2   -- 查看指定用户的权限

-- 撤销权限  revoke 哪些权限 ,在哪个库撤销,给谁撤销
REVOKE ALL PRIVILEGES ON *.* FROM kuangshen2



-- 删除用户
DROP USER kuangshen






8.2、 MySQL备份

  1. 为什么要备份
  • 保证重要的数据不丢失
  • 数据转移
  1. MySQL数据库备份的方式
  • 直接拷贝物理文件
  • 在sql yog这种可视化工具中手动导出
  • 使用命令行导出 mysqldump 在命令行使用
#mysqldump -h主机 -u用户 -p密码 数据库 表 

mysqldump -hlocalhost -uroot -p123456 school student >D:/a.sql

#导入
#登录的情况下,切换到指定的数据库
#source 备份文件
source d:/a.sql

九、规范数据库设计

9.1、为什么需要设计

  1. 当数据库比较复杂时,就需要设计
  2. 糟糕的数据库设计:
  • 数据冗余,浪费空间
  • 数据库插入和删除都会麻烦,异常
  • 程序性能差
  1. 良好的数据库设计:
  • 节省内存空间
  • 保证数据库的完整性
  • 方便我们开发系统
  1. 软件开发中,关于数据库的设计
  • 分析需求:分析业务和需要处理的数据库的需求
  • 概要设计:设计关系图和E-R图
  1. 设计数据库的步骤:(个人博客为例)
  • 收集信息,分析需求
    • 用户表(用户登录注销,用户的个人信息,写博客,创建分类)
    • 分类表(文章分类,谁创建的)
    • 文章表(文章的信息)
    • 评论表
    • 友链表(友链信息)
    • 自定义表(系统信息,某个关键的字,或者一些主字段) key:value
  • 标识实体(把需求落实到每个字段)
  • 标识实体之间的关系
    • 写博客:user->blog
    • 创建分类:user->category
    • 关注:user->user
    • 评论:links

9.2、三大范式

  1. 为什么需要数据规范化?
  • 信息重复
  • 更新异常
  • 插入异常
    • 无法正常显示信息
  • 删除异常
    • 丢失有效的信息
  1. 三大范式
  • 第一范式

原子性:保证每一列不可再分

  • 第二范式

前提:满足第一范式

每张表只描述一件事情

  • 第三范式

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

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

  • 规范性和性能的问题
    • 考虑商业化的需求和目标,(成本,用户体验) 数据库的性能更加重要
    • 在规范性能的问题的时候,需要适当的考虑一下规范性
    • 故意给某些表增加一些冗余的字段(从多表查询变为单表查询)
    • 故意增加一些计算列(从大数据量降低为小数据量的查询:索引)

你可能感兴趣的:(数据库,数据库)