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
联表查询的思路是:
- 分析需求,分析查询的字段分别来自哪些表
- 确定使用哪种连接查询
- 确定交叉点(即两、三张表中哪个数据是相同的)
对于多表查询:
首先,要查询哪些数据。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)
前提是要满足第一范式和第二范式。
第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能简介相关。
在进行规范数据库的设计时,会产生 规范性和性能的问题。针对这样的问题,需要考虑以下:
关联查询的表不得超过三张。
- 考虑商业化的需求和目标,数据库的性能更加重要。
- 在规范性能的问题的时候,需要适当考虑一下规范性。
- 故意给某些表增加一些冗余的字段。从多表查询中变为单表查询。
- 故意增加一些计算列。从大数据量降低为小数据量的查询。
来源:CSDN
作者:myrhythm_
链接:https://blog.csdn.net/Adelagirl/article/details/104213961