数据库学习之MySQL

感情迁移 提交于 2020-02-08 04:08:44

MySQL简介

数据库

为什么要学数据库?

有以下几点原因:

最现实的原因就是为了找工作,数据库是岗位的需求,所以要学。

其次就是现在是大数据时代,数据是非常重要的,得数据者得天下。

然后就是我们需要存储数据,这就要用到数据库了。

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

什么是数据库?

数据库即DataBase(DB),它是存放数据的仓库,它的存储空间很大,可以存放百万条、千万条、上亿条数据。

数据库是一个按照数据结构来存储和管理数据的计算机软件系统,安装在操作系统之上。

数据库的作用说白了就是:存储数据、管理数据。

数据库的分类

数据库可以分为关系型数据库和非关系型数据库。

关系型数据库:(SQL)

关系型数据库,存储的格式可以直接且直观地反映实体间的关系。关系型数据库中表与表之间是有很多复杂的关联关系的。

常见的关系型数据库有MySQL,SqlServer,Oracle,DB2,SQLlite等。

在轻量或小型应用中,使用不同的关系型数据库对系统的性能影响不大,但是在构建大型应用时,需要根据应用的业务需求和性能需求,选择合适的关系型数据库。

关系型数据库大多都遵循SQL(Structured Query Language,结构化查询语言)标准,常见操作有查询(SELECT)、新增(INSERT)、更新(UPDATE)、删除(DELETE)等。

关系型数据库通过表和表之间、行和列之间的关系进行数据的存储。

非关系型数据库(NoSQL)

非关系型数据库指的是分布式的、非关系型的、不保证遵循ACID原则的数据存储系统。

NoSQL数据库有MongoDB,Redis,Memcache等。

非关系型数据库是进行对象的存储,通过对象的自身的属性来决定。

非关系型数据库的设计目的是简化数据库结构、避免冗余、影响性能的表连接、摒弃复杂分布式。

NoSQL数据库适合追求速度和可扩展性、业务多变的应用场景。

数据库管理系统简称DBMS,它是数据库的管理软件,可以科学有效地管理、维护和获取数据。MySQL就是数据库管理系统。

MySQL

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,现属于Oracle公司。MySQL是最流行的关系型数据库管理系统之一,在web应用方面,MySQL是最好的RDBMS(Relational Database Management System,关系数据库管理系统)应用软件之一。

数据库的操作

对数据库的操作实际上是对数据库中表中的数据的操作。

数据库的基本操作

创建数据库

CREATE DATABASE IF NOT EXISTS school;

删除数据库

DROP DATABASE IF EXISTS school;

使用数据库

USE school;

查看数据库

SHOW DATABASES;

如果表名或者字段名是一个特殊的字符,那么就要使用tab键上的那个符号(``)将其括起来。如

CREATE DATABASE `school`;

数据库的列类型

常用的数据库的列类型。

数值

类型 含义 字节数
tinyint 十分小的数据 1个字节
smallint 较小的数据 2个字节
mediumint 中等大小的数据 3个字节
int 标准的整数 4个字节(常用)
bigint 较大的数据 8个字节
float 浮点数 4个字节
double 浮点数 8个字节(存在精度问题)
decimal 字符串形式的浮点数 16个字节(不存在精度损失,常用语金融计算)

字符串

类型 含义 大小
char 字符串固定大小的 0~255
varchar 可变字符串 0~65535(常用)
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进行运算,因为结果为null

数据库的字段属性

字段属性 含义
Unsigned 表示无符号的整数。表明该列不能声明为负数
Zerofill 0填充。不足的位数,使用0来填充
自增 自增,即自动在上一条记录的基础上加1(默认)。通常用来设计唯一的主键,必须是整数类型。可以自定义设计主键自增的起始值和步长。
非空(NULL/NOT NULL) j假设设置为not null,如果不赋值,就会报错。假设设置为null,如果不填写值,默认就为null。
默认 设置默认的值。例如设置sex字段默认值为男,如果不指定该列的值,那么就会有默认的值。

每一个表都必须存在以下五个字段。这是用于做项目的,表示一个记录存在意义!

字段 含义
id 主键
version 乐观锁
is_delete 伪删除
gmt_create 创建时间
gmt_update 修改时间

创建数据库表

创建数据库表的格式:

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

在school数据库中创建一个student表。

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

几个常用命令:

查看创建数据库的语句

SHOW CREATE DATABASE school

查看创建表的定义语句

SHOW CREATE TABLE student

显示表的结构

DESC student
-- mysql的注释为--,且需要在--和注释内容之间空一格

数据库表的类型

在创建数据库和表的时候会定义引擎,常用的有两种:INNODB(默认使用)和MYSIAM(早些年使用)。

两者的区别主要有以下:

MYISAM INNODB
事务支持 不支持 支持
数据行锁定 不支持 支持
外键约束 不支持 支持
全文索引 支持 不支持
表空间的大小 较小 较大,约为2倍

常规的使用操作:

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

在物理空间存在的位置

所有的数据库文件都存在data目录下,一个文件夹就对应一个数据库。本质还是文件的存储。

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

  • INNODB:在数据库表中只有一个 *.frm文件,以及上级目录下的ibdata1文件。

  • MYISAM对应文件

    • *.frm文件:表结构的定义文件
    • *.MYD文件:数据文件(data)
    • *.MYI文件:索引文件(index)

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

CHARSET=utf8

不设置字符集编码的话,会使用MySQL默认的编码 Latin1,该编码不支持中文。

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

character-set-server=utf8

表的修改和删除

表的修改

修改表名 ALTER TABLE 旧表名 RENAME AS 新表名;

ALTER TABLE student RENAME AS student01;

增加表的字段 ALTER TABLE 表名 ADD 字段 列属性;

ALTER TABLE student01 ADD grade INT(3);

修改表的字段–修改约束 ALTER TABLE 表名 MODIFY 字段 列属性[]

ALTER TABLE student01 MODIFY grade VARCHAR(11) -- 修改约束

修改表的字段–字段重命名 ALTER TABLE 表名 CHANGE 旧名字 新名字 列属性[]

ALTER TABLE student01 CHANGE grade grade1 INT(2) 

删除表的字段 ALTER TABLE 表名 DROP 字段名

ALTER TABLE student01 DROP grade1

表的删除

-- 删除表(考虑表如果存在再去删除)
DROP TABLE IF EXISTS student01

在进行表的创建和删除操作时,应该加上判断避免报错

MySQL数据管理

外键

外键:表的外键是另一表的主键,外键可以有重复的,可以是空值。外键表示了两个关系之间的相关联系。

外键有两种创建方式。

方式一

在创建表的时候,就增加约束来创建外键。但这样做的缺点是麻烦且复杂。

CREATE TABLE `grade`(
  `gradeid` INT(10) NOT NULL AUTO_INCREMENT COMMENT '年级id',
  `gradename` VARCHAR(50) NOT NULL COMMENT '年级名称',
  PRIMARY KEY (`gradeid`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
-- 学生表的 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 '出生日期',
  `gradeid` INT(10) NOT NULL COMMENT '学生的年级',
    `address` VARCHAR(100) DEFAULT NULL COMMENT '家庭住址',
  `email` VARCHAR(50) 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(10) NOT NULL AUTO_INCREMENT COMMENT '年级id',
  `gradename` VARCHAR(50) NOT NULL COMMENT '年级名称',
  PRIMARY KEY (`gradeid`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
-- 学生表的 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 '出生日期',
  `gradeid` INT(10) NOT NULL COMMENT '学生的年级',
  `address` VARCHAR(100) DEFAULT NULL COMMENT '家庭住址',
  `email` VARCHAR(50) DEFAULT NULL COMMENT '邮箱',
  PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
-- 创建表的时候没有外键关系
ALTER TABLE `student`
ADD CONSTRAINT `FK_gradeid` FOREIGN KEY(`gradeid`) REFERENCES
`grade`(`gradeid`);
ALTER TABLE 表名 ADD CONSTRAINT 约束名 FOREIGN KEY(作为外键的列) REFERENCES 哪个表(哪个字段)

上面的操作都是物理外键,是数据库级别的外键,不建议使用(避免数据库过多造成困扰)。

最佳的实现就是

  • 数据库就是单纯的表,只用来存数据,只有行(数据)和列(字段)
  • 若想使用多张表的数据,想使用外键则通过程序来实现

DML语言

DML:Data Manipulation Language,数据库操作语言。通过该语言可以实现对数据库的基本操作。

DML基本的操作是:

  • 插入
  • 修改
  • 删除

插入(添加)操作

插入操作使用 INSERT。

插入的语法为:INSERT INTO 表名([字段名1,字段名2,字段名3]) VALUES ('值1'),('值2'),('值3',...)

-- INSERT INTO 表名([字段名1,字段名2,字段名3]) VALUES ('值1'),('值2'),('值3',...)
INSERT INTO `grade`(`gradename`) VALUES ('大一') -- 由于主键是自增的,我们可以省略
-- 如果不写表的字段,就会一一匹配
INSERT INTO `grade` VALUES('大三')

一般写插入语句时,一定要数据和字段一一对应

INSERT INTO `student`(`name`,`pwd`,`sex`) VALUES ('张三','123456','男')
-- 插入多个字段
INSERT INTO `grade`(`gradename`)
VALUES('大二'),('大四')

需要注意的是:

  • 字段和字段之间使用英文逗号隔开
  • 字段可以省略,但是后面的值还是要一一对应
  • 可以同时插入多条数据,VALUES后面的值使用英文逗号隔开即可

修改操作

修改使用 UPDATE

修改操作的语法为:update 表名 set column_name=value,[column_name=value,...] where [条件]

-- 修改名字,带了条件
UPDATE `student` SET `name`='李四' WHERE id = 1;
-- 在不指定条件的情况下,会改动所有表!
UPDATE `student` SET `name`='王五'
-- 修改多个属性,使用逗号隔开
UPDATE `student` SET `name`='张三',`age`='23' WHERE id = 1;

where id = 1 是一个条件句。where + 判断条件(字段 操作符 某个值/区间)

where操作符会返回一个布尔值。

操作符 含义 示例 结果
= 等于 5=6 false
<> 或者 != 不等于 5<>6/5!=6 true
> 大于 10>8 true
< 小于 10<8 false
>= 大于等于 8>=8 true
<= 小于等于 16<=20 true
between … and … 在某个范围内 5 between 1 and 10 true
and 且/和 5>2 and 2>3 false
or 5>2 or 2>3 true

对于修改的语法。需要注意的有:

  • column_name 是数据库的列,所以最好带上``
  • 修改的时候如果没有带筛选的条件,则会修改所有的列
  • value 是一个具体的值,也可以是一个变量
  • 多个设置的属性之间,使用英文逗号隔开

删除操作

删除使用 delete。

删除的语法:delete from 表名 [where 条件]

-- 删除指定数据
DELETE FROM `student` WHERE id = 1;
-- 删除时如果没有带条件,则会全部删除,所以尽量避免这样写
DELETE FROM `student`;

TRUNCATE 命令

TRUNCATE 的作用是:完全清空一个数据库表,但表的结构和索引约束不会变。

-- 清空 student 表
TRUNCATE `student`

delete和truncate的区别

  • 相同点:两者都可以删除数据库表,都不会删除表结构
  • 不同点
    • truncate 会重新设置自增列,计数器会归零
    • truncate不会影响事务

delete删除的问题:重启数据库后的现象

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

DQL查询数据

DQL

DQL:Data Query LANGUAGE,数据查询语言。

对于DQL而言,所有的查询操作都使用它(select);简单查询、复杂查询都可以做到;它是数据库中最核心的语言,也是最重要的语句;它是使用频率最高的语句。

select 语法

SELECT [ALL | DISTINCT]
{* | table.* | [table.field[as alias1][,table.field2[as alias2]][,...]] }
FROM table_name [as table_alias]
	[left | right |inner join table_name2]  -- 联合查询
	[WHERE ...]      -- 指定结果需满足的条件
	[GROUP BY ...]   -- 指定结果按照哪几个字段来分组
	[HAVING ...]     -- 过滤分组的记录必须满足的次要条件
	[ORDER BY ...]   -- 指定查询记录按一个或多个条件排序
	[LIMIT {[offset,]row_count | row_countOFFSET oeeset}];        -- 指定查询的记录从哪条至哪条

注意:[ ]括号表示可选的,{ }括号表示必选的

查询字段

语法:select 字段 from 表名

-- 查询全部的学生    select 字段 from 表名
SELECT * FROM `student`
-- 查询指定的字段
SELECT `StudentNo`,`StudentName` from student

有时候,列名字不是很见名知意,可以起别名,使用as。

字段名 as 别名;表名 as 别名

-- 起别名 AS   给结果起一个名字  可以给字段、表起别名
SELECT `StudentNo` AS 学号,`StudentName` AS 学生姓名 from student
-- 拼接函数 concat(a,b)
SELECT CONCAT('姓名:',StudentName) AS 新名字 FROM student

distinct 去重

distinct的作用是:去除select查询出来的结果中重复的数据,即重复的数据只显示一条即可。

-- 发现重复数据,去重
SELECT DISTINCT `StudentNo` FROM result 

数据库的列

-- 查询系统版本(select+函数)
SELECT VERSION()
-- 可以用来计算(select+表达式)
SELECT 20-8 AS 计算结果
-- 查询自增的步长(select+变量)
SELECT @@auto_increment_increment
-- 考试成绩 + 1分查看
SELECT `StudentNo`,`StudentResult`+1 AS '提分后' FROM result

数据库中的表达式可以是:文本值,列,null,函数,计算表达式,系统变量等

语法:select 表达式 from 表

where条件子句

where条件字句的作用是于检索数据库中符合条件的值。搜索的条件由一个或者多个表达式组成。结果是布尔值。

where中用到的逻辑运算符

运算符 语法 描述
and && a and b / a && b 逻辑与,两个都为真,则结果为真
or || a or b / a ||b 逻辑或,其中一个为真,则结果为真
not ! not a / ! a 逻辑非,真为假,假为真
-- and 
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 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 f如果a在b和c之间,则结果为真
like a like b sql匹配,如果a匹配b,则结果真
in a in (a1,a2,a3,…) r如果a在a1,a2,a3,…中的其中的某一个值中,则结果为真
-- 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 '%雨%'
-- in
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE StudentNo IN (1,3,5,6);
-- null   not null
-- not null
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE `BornDate` IS NOT NULL
-- null
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE `BornDate` IS NULL

联表查询

联表查询使用 join。联表查询有三大类。

查询方式 描述
inner join 如果表中至少有一个匹配,就返回行
left join 会从左表中返回所有的值,即使右表中没有匹配
right join 会从右表中返回所有的值,即使左表中没有匹配

join的语法:join(连接的表) on(判断的条件)

-- inner join
SELECT s.studentNO,studentName,SubjectNo,StudentResult
FROM student AS s
INNER JOIN result AS 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

-- right join
SELECT s.studentNO,studentName,SubjectNo,StudentResult
FROM student s
RIGHT JOIN result r
ON s.studentNO = r.studentNO

联表查询的思路是:

  1. 分析需求,分析查询的字段分别来自哪些表
  2. 确定使用哪种连接查询
  3. 确定交叉点(即两、三张表中哪个数据是相同的)

对于多表查询:

首先,要查询哪些数据。select …

其次,要从哪几张表中查。from 表 xxx join 连接的表 on 交叉条件

多张表查询时,先查询两张表然后再慢慢增加。

join是连接查询,where是等值查询

自连接

自连接是自己的表和自己的表进行连接,核心是将一张表拆为两张一样的表。

分页和排序

排序

排序的方式有两种,升序(ASC)和降序(DESC)。

排序的语法:order by 哪个字段 排序方式

SELECT s.`StudentNo`,`StudentName`,`SubjectName`,`StudentResult`
FROM student s
INNER JOIN `result` r
ON s.StudentNo = r.StudentNo
INNER JOIN `subject` sub
ON r.`SubjectNo` = sub.`SubjectNo`
WHERE subjectName = '数据库结构-1'
ORDER BY StudentResult ASC

分页

分页的目的是 为了缓解数据库的压力,使用户的体验感更好。网页中就应用了分页。

分页的语法:limit 起始值,页面的大小

SELECT s.`StudentNo`,`StudentName`,`SubjectName`,`StudentResult`
FROM student s
INNER JOIN `result` r
ON s.StudentNo = r.StudentNo
INNER JOIN `subject` sub
ON r.`SubjectNo` = sub.`SubjectNo`
WHERE subjectName = '数据库结构-1'
ORDER BY StudentResult ASC
LIMIT 5,5

分页的一些计算

每页只显示五条数据
第一页 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 :当前页 】
【数据总数/页面大小 = 总页数】

子查询

当一个查询时另一个查询的条件时,称之为子查询。

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

SELECT StudentNo,StudentName FROM student WHERE StudentNo IN (
SELECT StudentNo FROM result WHERE StudentResult>80 AND SubjectNo = (
SELECT SubjectNo FROM `subject` WHERE `SubjectName` = '高等数学-2')
)

分组和过滤

分组是通过某个字段来进行分组。

过滤则是根据某个条件或某些条件来进行筛选。

SELECT SubjectName, AVG(StudentResult) AS 平均分,MAX(StudentResult) AS 最高
分,MIN(StudentResult) AS 最低分
FROM result r
INNER JOIN `subject` sub
ON r.`SubjectNo` = sub.`SubjectNo`
GROUP BY r.SubjectNo 
HAVING 平均分>80

MySQL函数

常用函数

数学运算

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

字符串函数

-- 字符串长度
SELECT CHAR_LENGTH('hello,world') 
-- 拼接字符串
SELECT CONCAT('我','爱','你') 
-- 查询,从某个位置开始替换某个长度
SELECT INSERT('我爱编程helloworld',1,2,'超级热爱') 
-- 小写字母
SELECT LOWER('Hello') 
-- 大写字母
SELECT UPPER('Hello') 
-- 返回第一次出现的子串的索引
SELECT INSTR('Hello','l') 
-- 替换出现的指定字符串
SELECT REPLACE('我爱编程','爱','超级热爱') 
-- 返回指定的子字符串 (源字符串,截取的位置,截取的长度)
SELECT SUBSTR('我爱编程helloworld',4,6) 
-- 反转
SELECT REVERSE('清晨我上马') 

时间和日期函数

-- 获取当前日期
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()

聚合函数

聚合函数是比较常用的。

常见的聚合函数有:

函数 描述
count() 计数
sum() 求和
avg() 平均值
max() 最大值
min() 最小值

count()

想要查询一个表中有多少个记录,可以使用count()。

count(字段) 会忽略所有的null值
count(*) 不会忽略null值。本质是计算行数
count(1) 不会忽略null值。本质是计算行数

如果表没有主键,那么count(1)比count( * )快。表有主键,count(*)会自动优化到主键列上。

数据库级别的MD5加密

MD5

MD5:Message-Digest Algorithm,是一种被广泛使用的密码散列函数。主要增强算法复杂度和不可逆性。

MD5是不可逆的,但具体值的MD5是一样的。

UPDATE testmd5 SET pwd=MD5(pwd) WHERE id = 1

使用MD5,校验的时候,需要将用户传递进来的值进行MD5加密,然后在数据库中对比加密后的值。

事务

事务:Transaction,一般是指要做的或所做的事情。

在mysql中,事务是将一组SQL放在一个批次中去执行。

事务的原则是:ACID原则

A:原子性(Atomicity)

原子性即 事务要么都成功,要么都失败,不存在一方成功一方失败的情况(会出错)。

B:一致性(Consistency)

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

I:隔离性(Isolation)

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

D:持久性(Durability)

持久性是针对事务提交的,事务一旦提交则不可逆,将被持久化到数据库中。

隔离导致的一些问题


脏读

脏读指的是一是个事务读取了另外一个事务未提交的数据。

不可重复读

在一个事务内读取表中的某一行数据,多次读取结果不同。(这个不一定是错误的,只是某些场合不对)

虚读(幻读)

虚读指的是在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。

执行事务

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

-- 手动处理事务
SET autocommit = 0 -- 关闭自动提交
-- 事务开启
START TRANSACTION -- 标记一个事务的开始,从这个之后的 sql 都在同一个事务内
INSERT xx
INSERT xx
-- 提交: 持久化 (成功!)
COMMIT
-- 回滚: 回到的原来的样子 (失败!)
ROLLBACK
-- 事务结束
SET autocommit = 1 -- 开启自动提交

索引

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

InnoDB 的默认数据结构是 BTree

索引分类

索引可以分为:

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

基本语法

索引的创建:

  • 在创建表的时候给字段增加索引
  • 创建成功表后,增加索引
-- 显示所有的索引信息
SHOW INDEX FROM student
-- 增加一个全文索引 (索引名) 列名
ALTER TABLE school.student ADD FULLTEXT INDEX `studentName`(`studentName`);

索引在小数据量的时候,用处不大,但是在大数据的时候,区别十分明显~

索引的原则

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

权限管理和备份

用户管理

方式一

使用可视化管理工具进行用户的管理。

方式二

使用SQL命令进行用户的管理,实际上操作的是 mysql.user这张表。本质也是对表的增删改查。

-- 创建用户 CREATE USER 用户名 IDENTIFIED BY '密码'
CREATE USER zhangsan IDENTIFIED BY '123456'
-- 修改密码
-- 修改当前用户密码
SET PASSWORD = PASSWORD('123456')

-- 修改指定用户密码
SET PASSWORD FOR zhangsan = PASSWORD('1234567')
-- 重命名 RENAME USER 原来名字 TO 新的名字
RENAME USER zhangsan TO zhangsan02
-- 用户授权 ALL PRIVILEGES 全部的权限 (可以对数据库和表)
-- ALL PRIVILEGES 除了给别人授权,其他都能够干
GRANT ALL PRIVILEGES ON *.* TO zhangsan02
-- 查询权限
-- 查看指定用户的权限
SHOW GRANTS FOR zhangsan02 
SHOW GRANTS FOR root@localhost
-- 撤销权限 REVOKE 哪些权限, 在哪个库撤销,给谁撤销
REVOKE ALL PRIVILEGES ON *.* FROM zhangsan02
-- 删除用户
DROP USER zhangsan02

备份

备份的原因:

  • 保证数据不丢失
  • 数据转移

MySQL数据库备份的方式:

  • 直接拷贝物理文件

  • 在可视化工具中手动导出

    • 在想要导出的表或库中,右键选择备份或导出
  • 使用命令行导出(mysqldump命令)

    # mysqldump -h 主机 -u 用户名 -p 密码 数据库 表名 > 物理磁盘位置/文件名
    mysqldump -hlocalhost -uroot -p123456 school student >D:/a.sql
    
    # mysqldump -h 主机 -u 用户名 -p 密码 数据库 表1 表2 表3 > 物理磁盘位置/文件名
    
    # mysqldump -h 主机 -u 用户名 -p 密码 数据库> 物理磁盘位置/文件名
    mysqldump -hlocalhost -uroot -p123456 school >D:/c.sql
    
    

数据的导入:

# 导入
# 登录的情况下,切换到指定的数据库
# source 备份文件
source d:/a.sql
mysql -u用户名 -p密码 库名< 备份文件

规范数据库设计

当数据比较复杂的时候,就需要设计数据库。

数据库的设计也有好坏之分。

糟糕的数据库设计会产生一系列问题:

  • 数据冗余,浪费空间
  • 数据库插入和删除都很麻烦,且产生异常
  • 程序性能差

良好的数据库设计的优点是:

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

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

当数据库不规范时,会产生一系列问题:

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

在软件开发中,设计数据库时涉及到两方面:分析需求(分析业务和需要处理的数据库的需求)和概要设计(设计关系图 E-R图)。

设计数据库的步骤:

  • 收集信息,分析需求
  • 标识实体:把需求落地到每个字段
  • 标识实体之间的关系

三大范式

第一范式(1NF)

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

第二范式(2NF)

前提是要满足第一范式。每张表只描述一件事情。

第三范式(3NF)

前提是要满足第一范式和第二范式。

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

在进行规范数据库的设计时,会产生 规范性和性能的问题。针对这样的问题,需要考虑以下:

关联查询的表不得超过三张。

  • 考虑商业化的需求和目标,数据库的性能更加重要。
  • 在规范性能的问题的时候,需要适当考虑一下规范性。
  • 故意给某些表增加一些冗余的字段。从多表查询中变为单表查询。
  • 故意增加一些计算列。从大数据量降低为小数据量的查询。
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!