前端:页面(展示数据)。
后端:连接点,连接数据库JDBC,连接前端(控制,控制视图跳转,给前端传递数据)。
数据库:存储数据(Txt,Excel,word)。
-
只会写代码,学好数据库,基本上是混饭吃。
-
操作系统,数据结构与算法,当一个不错的程序员。
-
离散数学,数字电路,体系结构,编译原理,实战经验,优秀的程序员。
1.1 为什么要学数据库
-
岗位需求。
-
现在是大数据时代,数据变现,得数据者得天下。
-
被迫需求:存数据。
-
1.2 什么是数据库
数据库(DB):DataBase。
概念:数据仓库,软件,安装在操作系统(window,linux,mac.....)之上。
作用:存储数据,管理数据。
1.3 数据库分类
关系型数据库:(SQL)
-
Mysql,Oracle,Sql Server,DB2,SQLlite.
-
通过表和表之间,行和列之间的关系进行数据的存储。
非关系型数据库:(NoSQL) Not Only
-
Redis ,MongDB。
-
非关系型数据库,对象存储,通过对象的自身的属性来决定。
DBMS(数据库管理系统)
数据库管理软件,科学有效的管理我们的数据,维护和获取数据。
MySQL,就是典型的数据库管理系统。
注意:数据库DB,不等于数据库管理系统。
1.4 MySQL简介
MySQL是一个*,由瑞典MySQL AB 公司开发,属于
MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。
MySQL所使用的 SQL 语言是用于访问
安装建议:
尽量使用压缩包安装,不然不好删除。
2.操作数据库
2.1 操作数据库
1、创建数据库
CREATER DATABASE [IF NOT EXISTS] 数据库名字
2、删除数据库
DROP DATABASE [IF EXISTS] 数据库名字
3、使用数据库
USE `数据库名字` 这里的 ` 是tab键上面的
4、查看数据库
SHOW DATABASES --查看所有的数据库
2.2 数据库列类型
数值
- tinyint 十分小的数据 1个字节 - smallint 较小的数据 2个字节 - mediumint 中等大小的数据 3个字节 - int 标准的整数 4个字节 常用 - bigint 较大的数据 8个字节 - float 浮点数 4个字节 - double 浮点数 8个字节(精度问题) - decimal 字符串形式的浮点数 金融计算的时候,一般是使用decimal
字符串
- char 字符串固定大小 0-255 - varchar 可变字符串 0-65535 常用的变量 String - tinytext 微型文本 2^8-1 - text 文本串 2^16-1 保存大文本
时间日期
java.Util.Date - date YYYY-MM-DD,日期格式 - time HH:mm:ss,时间格式 - datatime YYYY-MM-DD HH:mm:ss,最常用的时间格式 - timestamp 时间戳,1970.1.1到现在的毫秒数 也较为常用 - year 年份表示
null
没有值,未知。 注意,不要使用NULL进行运算,结果为NULL。
2.3 数据库的字段属性
Unsigned:
-
无符号的整数。
-
声明了该列不能声明为负数。
zerofill:
-
0填充的。
-
不足的位数,使用0来填充。
自增:
-
自动在上一条记录的基础上+1。
-
通常用来设计唯一的主键,必须是整数类型。
-
可以自定义设计主键自增的起始值和步长。
非空:
-
假设设置为not null,如果不给他赋值,就会报错。
默认:
-
设置默认的值。
-
如,设置sex的默认值为男,那么建立的所有值性别都是男。
2.4 创建数据库表
格式:
CREATE TABLE [IF NOT EXISTS] `表名`(
\'字段名\' 列类型 [属性] [索引] [注释],
\'字段名\' 列类型 [属性] [索引] [注释],
\'字段名\' 列类型 [属性] [索引] [注释],
......
PRIMARY KEY(`ID`)
)[表类型][字符集设置][注释]
ENGINE=INNODB DEFAULT CHARSET=UTF8
常用命令:
SHOW CREATE DATABASE school --查看创建数据库语句 SHOW CREATE TABLE student --查看student数据表的定义语句 DESC student --显示表的结构
2.5 数据表的类型
关于数据库引擎:
-
INNODB --现在默认使用
-
MYISAM --早些年使用
区别:
| MYISAM | INNODB | |
|---|---|---|
| 事务支持 | 不支持 | 支持 |
| 数据行锁定 | 不支持 | 支持 |
| 外键约束 | 不支持 | 支持 |
| 全文索引 | 支持 | 不支持 |
| 表空间大小 | 较小 | 较大,约为前者两倍 |
总结:
-
MYISAM:节约空间,速度比较快。
-
INNODB:安全性高,事务处理的速度,适合多表用户操作。
在物理空间存在的位置:
所有的数据库文件都存在data目录下,本质上还是文件的存储。
MySQL引擎在物理文件上的区别:
-
INNODB在数据库表中只有一个 *.frm 文件,以及上级目录下的ibdata1文件。
-
MYISAM对应的文件:
-
*.frm --表结构定义的文件
-
*.MYD --数据文件(data)
-
*.MYI --索引文件(index)
-
设置数据库的字符集编码:
CHARSET=utf8
不设置的话,会是默认的字符集编码(不支持中文!)
你也可以在my.ini中设置默认的编码
charset-set-server = utf8
不支持后面这种,如果换电脑可能会出现中文乱码。
2.6 修改删除表
修改表名 -- ALTER TABLE 表名 RENAME AS 新表名 ALTER TABLE teacher RENAME AS teacher1 增加表的字段 -- ALTER TABLE 表名 ADD 字段名 列属性 ALTER TABLE 表名 ADD age int(11) 修改表的字段名,约束 -- ALTER TABLE 表名 MODIFY 字段名 列属性[] ALTER TABLE teacher modify age int(1) -- ALTER TABLE 表名 change 旧名字 新名字 列属性[] ALTER TABLE teacher1 change age age1 int(1) 删除表的字段 -- ALTER TABLE 表名 DROP 字段名 ALTER TABLE teacher DROP age 删除表(先判断,如果存在再删除,以免报错) DROP TABLE IF EXISTS teacher
注意:
-
字段名使用 tab 键上面的 ` 包裹
-
注释 -- /**/
-
sql关键字大小写不敏感,建议小写
-
所有符号使用英文
3.MySQL数据管理
3.1 外键
创建两个表,学生表和年级表
在创建表的时候添加约束 CONSTRAINT
-- 学生表的 gradeid 字段要去引用年级表的 gradeid
-- 定义外键
-- 给这个外键添加约束(执行引用) references 引用
KEY `FK_gradeid` (`gradeid`), CONSTRAINT `FK_gradeid` FOREIGN KEY (`gradeid`) REFERENCES `grade`(`gradeid`)
这里创建的是物理外键,数据库级别的外键,不建议使用。
最佳操作:
-
数据库就是单纯的表,只用来存数据,只有行(数据)与列(字段)。
-
如果想使用多张表,使用程序实现。
阿里规范:
-
强制不得使用外键与级联,一切外键概念必须在应用层解决。
-
每次做DELETE和UPDATE都必须考虑外键约束,会导致开发的时候很痛苦,测试数据极为不方便。
3.2 DML语言
-
insert
-
delete
-
update
添加 (insert):
insert into 表名([字段名1,字段名2,......]) values (\'值1\',\'值2\'......);
写插入语句,一定要保证数据和字段一一对应。
字段是可以省略的,但是后面的值必须要一一对应。
可以同时插入多条数据,values后面的值,需要使用逗号隔开。
修改(update):
update 表名 set column_name = value where 条件
column_name 是数据库的列,尽量带上``。
where后面的筛选条件,如果没有指定,则会修改所有的列。
value是一个具体的值,也可以是一个变量。
多个设置的属性之间,使用英文逗号隔开。
删除(delete):
delete from 表名 where 条件 truncate 表名
都能清空数据库:
相同点:都能删除数据,都不会删除表结构。
不同点:truncate 重新设置自增列,计数器会归零,且不会影响事务。
delete删除问题:
- 使用INNODB引擎,重启数据库,自增列会从1开始,因为它存在内存中,断电即失。
- 使用MyISAM引擎,重启数据库,会继续从上一个自增量开始,因为它存在文件中,不会丢失。
4.DQL查询数据(重点)
4.1 DQL
Data Query Language:数据查询语言
-
所有的查询操作都用它 select。
-
简单的查询,复杂的查询它都能做。
-
数据库中最核心的语言。
-
使用频率最高的语句。
4.2 指定查询字段
查询一个表中所有的信息 -- select * from 表名 查询指定字段 -- select 字段 from 表名 别名,给结果起一个名字 AS 可以给字段起别名也可以给表起别名 见名知意 -- select 字段名 AS 别名, 字段名 AS 别名 from 表名 AS 别名 各种函数,如Concat(a,b) -- select Concat(\'姓名\',StudentName) AS 新名字 from 表名 去重,distinct -- select distinct 字段名 from 表名 查询版本号 -- select version() 用来计算 -- select 100*2-1 AS 计算结果 查询自增步长 -- select @@auto_increment_increment 学生考试成绩加一分 -- select `studentNO`,`studentResult`+1 AS `加分后` from result
Select完整的语法:
select [All | Distinct]
{* | table.* | [table.field1[as alias1]].....}
FROM table_name[as table_alias]
[left | right | inner join table_name2] --联表查询
[where ...] --指定结果需要满足的条件
[GROUP BY...] --指定按照哪几个字段来分组
[HAVING] --过滤分组的记录必须满足的次要条件
[ORDER BY...] --按照条件排序
[LIMIT] --分页
4.3 where 模糊查询
| 运算符 | 语法 | 描述 |
|---|---|---|
| IS NULL | a is null | 查询结果为空的 |
| IS NOT NULL | a is not null | 查询结果不为空的 |
| BETWEEN | a between b and c | 查询结果a在b与c之间的 |
| Like | a like b | like模糊查询 |
| In | a in (a1,a2,a3) | 查询括号里匹配的 |
like 结合 %(代表0到任意个字符) _ 一个字符 -- 查询名字以 李 开头的学生 -- select `StudentNo`,`StudentName` from `student` where StudentName like \'李%\'; -- 查询姓 李 的学生,名字后面只有一个字 -- select `StudentNo`,`StudentName` from `student` where StudentName like \'李_\'; -- 查询 1001 1002 1003号学员 -- select `StudentNo`,`StudentName` from `student` where StudentNo in (1001,1002,1003);
4.4 联表查询
写联表查询思路:
1.分析需求,分析查询的字段来自于哪些表。
2.确定使用哪种联表查询。
3.确定交叉点(即两张表中哪个数据是相同的)
join (连接的表) on (判断条件) 连接查询
where 等值查询
假设存在一种多张表查询,慢慢来,先查询两张表,随后慢慢增加。
4.5 分页和排序
排序
-- DESC 降序
-- ASC 升序
Order by 字段名 升序或降序
分页
为什么要分页?
缓解数据库压力,给人更好的体验。
-- limit 起始值,页面的大小
-- limit (n-1)*pageSize,pageSize
4.6 子查询
子查询就是指的在一个完整的查询语句之中,嵌套若干个不同功能的小查询,由里及外,从而一起完成复杂查询的一种编写形式。可以用联表查询代替。
5.MySQL函数
5.1 常用函数
一般用于计算的函数,官网查看。
5.2 聚合函数 (大量使用)
COUNT 查询一个表中有多少个记录 -- select count(字段名) from 表名; count(字段名),会忽略所有的 null 值 -- select count(*) from 表名; 不会忽略 null 值,本质上是计算行数 -- select count(1) from 表名; 不会忽略 null 值,本质上是计算行数 -- select sum(字段名) as 总和 from 表名 -- select avg(字段名) as 平均数 from 表名 -- select max(字段名) as 最大值 from 表名 -- select min(字段名) as 最小值 from 表名
5.3 数据库级别的MD5加密
什么是MD5?
主要增强算法复杂度和不可逆性。
MD5不可逆,相同值得MD5是一样的,背后有一个字典。
-- 插入数据的时候加密 Insert into 表名 values(1,\'姓名\',MD5(\'123456\')); -- 如何校验,将用户传递进来的密码,进行MD5加密,然后对比加密后的值 select * from 表名 where \'name\'=\'\', and pwd=MD5(\'123456\');
6.事务
6.1 什么是事务
要么都成功,要么都失败。
一一一一一一
1.第一个sql。
2.第二个sql.
......
一一一一一一
将一组sql放在一个批次中去执行。
事务原则(ACID)
-
原子性(atomicity):
一个事务要么全部提交成功,要么全部失败回滚,不能只执行其中的一部分操作,这就是事务的原子性。
-
一致性(consistency):
事务的执行不能破坏数据库数据的完整性和一致性,一个事务在执行之前和执行之后,数据库都必须处于一致性状态。
比如:两个人的账户一共有1000元钱,执行完事务之后,两个账户加起来还是1000元,不能多不能少。
-
隔离性(isolation):
事务的隔离性是指在并发环境中,并发的事务时相互隔离的,一个事务的执行不能不被其他事务干扰。不同的事务并发操作相同的数据时,每个事务都有各自完成的数据空间,即一个事务内部的操作及使用的数据对其他并发事务时隔离的,并发执行的各个事务之间不能相互干扰。
-
持久性(durability):
一旦事务提交,那么它对数据库中的对应数据的状态的变更就会永久保存到数据库中。即使发生系统崩溃或机器宕机等故障,只要数据库能够重新启动,那么一定能够将其恢复到事务成功结束的状态
隔离所导致的一些问题: 脏读:
指一个事务读取了另外一个事务未提交的数据。
不可重复读: 在一个事务内读取表中的某一行数据,多次读取结果不同。
虚读(幻读):
是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。
在标准SQL规范中,定义了4个事务隔离级别,不同的隔离级别对事务的处理不同,分别是:未授权读取,授权读取,可重复读取和串行化。
1、读未提交(Read Uncommited),该隔离级别允许脏读取,其隔离级别最低;比如事务A和事务B同时进行,事务A在整个执行阶段,会将某数据的值从1开始一直加到10,然后进行事务提交,此时,事务B能够看到这个数据项在事务A操作过程中的所有中间值(如1变成2,2变成3等),而对这一系列的中间值的读取就是未授权读取
2、授权读取也称为已提交读(Read Commited),授权读取只允许获取已经提交的数据。比如事务A和事务B同时进行,事务A进行+1操作,此时,事务B无法看到这个数据项在事务A操作过程中的所有中间值,只能看到最终的10。另外,如果说有一个事务C,和事务A进行非常类似的操作,只是事务C是将数据项从10加到20,此时事务B也同样可以读取到20,即授权读取允许不可重复读取。
3、可重复读(Repeatable Read)
就是保证在事务处理过程中,多次读取同一个数据时,其值都和事务开始时刻是一致的,因此该事务级别禁止不可重复读取和脏读取,但是有可能出现幻影数据。所谓幻影数据,就是指同样的事务操作,在前后两个时间段内执行对同一个数据项的读取,可能出现不一致的结果。在上面的例子中,可重复读取隔离级别能够保证事务B在第一次事务操作过程中,始终对数据项读取到1,但是在下一次事务操作中,即使事务B(注意,事务名字虽然相同,但是指的是另一个事务操作)采用同样的查询方式,就可能读取到10或20;
4、串行化
是最严格的事务隔离级别,它要求所有事务被串行执行,即事务只能一个接一个的进行处理,不能并发执行。
事务模拟场景:转账
SET autocommit = 0; --关闭自动提交 START TRANSACTION --开启一个事务(一组事务) update account set money = money - 500 where `name` = \'A\'; --A账户减500元 update account set monet - money + 500 where `name` = \'B\'; --B账户加500元 commit; --提交事务,注意:一旦事务被提交就被持久化到数据库了,此时再回滚也没用了。 rollback; --回滚 set autocommit = 1; --恢复默认值
7.索引
MySQL官方定义:索引(index)是帮助MySQL高效获取数据的数据结构。
即,索引就是数据结构。
7.1 索引的分类
在一个表中,主键索引只能有一个,唯一索引可以有多个。
-
主键索引(primary key):
-
唯一的标识,主键不可重复,只能有一个列作为主键。
-
-
唯一索引(unique key):
-
避免重复数据的出现,唯一索引可以重复,多个列可以标识为唯一索引。
-
-
常规索引(key/index):
-
默认的,index,key关键字来设置。
-
-
全文索引(fulltext):
-
在特定的数据库引擎下才有,Myisam。
-
快速定位数据。
-
基础语法:
索引的使用: 1.在创建数据表的时候给字段添加索引。 2.创建数据表之后,使用alter add 添加索引。 3.创建数据表之后,使用create on 添加索引。 -- 显示所有索引信息 SHOW INDEX FROM student -- 增加一个全文索引 alter add 方式 alter table student add fulltext index `studentName`(`studentName`); -- 增加一个索引 -- 命名方式 一般是 id_表名_字段名 -- create index 索引名 on 表(字段) create index id_app_user_name on app_user(`name`); -- explain分析sql执行情况 看查询的数据行数 explain select * from student
索引在小数据量的时候,用处不大,但是在大数据的时候,区别十分明显。
7.3 索引原则
-
索引不是越多越好。每个额外的索引都要占用额外的磁盘空间,并降低写操作的性能。
-
不要对进程变动数据加索引。
-
小数据量的表不需要加索引。
-
索引一般加在常用来查询的字段上。
索引的数据结构:
Hash类型的数据结构。
Btree:Innodb的默认数据结构。
8.规范数据库设计
三大范式
为什么要数据规范化?
-
信息重复
-
更新异常
-
插入异常,无法正常显示信息
-
删除异常,丢失有效的信息
第一范式(1NF):
原子性,保证每一列不能再分。
第二范式(2NF):
前提:满足第一范式。
每张表只描述一件事情。
第三范式(3NF):
前提:满足第一范式与第二范式。
第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。
规范性 与 性能问题
阿里规定:关联的表不能超过三张。
-
考虑商业化的需求和目标(成本与用户体验),数据库的性能更加重要。
-
在规范性能问题的时候,需要适当的考虑一下 规范性。
-
故意给某些表增加一些冗余的字段。(从多表查询变成单表查询)
-
故意增加一些计算列(从大数据量降低为小数据量的查询:索引)