数据库简介 1.0
- 数据库是按照数据结构来组织、存储和管理数据的仓库
- 数据库是一种用来持久保存数据的方式,数据库中的数据可以通过多种形式(网络、本地)进行共享,使多台设备访问的是同一个数据库服务,可以实现数据的共享
- 数据库内置了一套完整的安全机制,在存储数据的同时,也可以安全保障数据不会受到外界的影响。
MySQL数据库简介: MySQL数据是一个关系型数据库,最早是由瑞典MySQLAB公司开发的,后来被Oracle公司高价收购,MySQL已经成为最流行的关系型数据库管理系统,尤其是在Web应用程序上,表现最好。
MySQL管理方法介绍
关系型数据库:
- 存储的格式可以直接反映实体之间的一种关系,实体指的就是表,在关系型数据库下,表和表之间有存在着关系的
比如:
| 图书表 | 图书类别 |
|---|---|
| 图书编号 | 类别编号 |
| 图书名称 | 类别名称 |
| 图书价格 | |
| 图书类别 |
- 图书类别表中包含以下几个数据
- 1 教科用书
- 2 儿童读物
- 3 情感交流
- 4 成人读物
图书表中
| 编号 | 书名 | 价格 | 数量 |
|---|---|---|---|
| 1 | 金瓶梅 | 18.00 | 4 |
- 以上这种关系,就属于关系型数据库中所指的实体和关系,图书表、类型表就是实体
概念:
MySQL就是建立在这种关系基础上来管理数据的,MySQL管理数据速度快并且灵活,MySQL使用的开发语言是标准的SQL语言(结构化查询语言,通用的数据库管理操作语言),不像其它的数据库(SQLServer)对SQL语言进行了更改。MySQL采用的是双授权政策,分为社区版(免费、开源)和商业版(收费,提供服务,价格较低)
- 在开发语言中,有一种非常流行的组合:
LAMPLAMJ - L:
Linux操作系统 - A:
Apache服务器 - M:
MySQL数据库 - P:
PHP开发语言 - J:
Java开发语言 因为免费,所以MySQL数据库在项目中的应用是最为广泛的,而且安全性相对于也是较高,其应用场景较Oracle(MySQL的大哥)这样的大型关系型数据库应用的更为广泛。在中小型软件应用中,首选MySQL。
MySQL的优势特点:
- 1、开源,在其基础上进行二次开发,同时授权也是免费的
- 2、
MySQL支持大型的数据库操作,可以处理拥有千万级操作的大型数据 - 3、
MySQL采用标准SQL语言做为开发语言,学习成本最低 - 4、
MySQL支持跨平台 - 5、
MySQL支持多种语言开发 - 6、
MySQL支持定制,采用GPL协议,可以直接修改MySQL的源码
扫盲时间
名词解释:
-
数据库:是数据表、关系和其它数据库对象的集合
-
数据表:数据表是真正存储数据的容器,你可以把数据表理解成一个电子表格 列:
- 属性列,一列代表着表中的一个
属性,一个列中的所有数据,都是该属性类型的数据值。
- 属性列,一列代表着表中的一个
-
行:数据行,记录、元组,是一组相关数据的集合,用来描述一个实体所具有的所有属性信息。
-
冗余:重复的数据即冗余,但是冗余从性能角度上来说,不能完全消灭
-
约束:是一种规则,用来强制性的保证数据的完整性和一致性
MySQL存储引擎
- 对于
MySQL 5.5及更高版本,默认的存储引擎是InnoDB。在5.5版本之前,MySQL的默认存储引擎是MyISAM。 - MyISAM:最为常用、拥有较高的插入、查询速度,但不支持事务操作
- InnoDB:已经成为事务型数据库的首选引擎,支持事务操作,支持行级锁定(锁住一条记录),为现在MySQL5.5版本以后的默认数据库存储引擎。
数据库常用命令
- MySQL是一种数据库服务,如果想要使用MySQL来存储数据.
- 第一步需要安装MySQL服务,
- 第二步启动MySQL服务(配置成随系统自动启动),
- 第三步通过客户端程序来访问MySQL服务
- 要访问MySQL数据库服务的时候,会涉及到一些命令
启动和停止MySQL服务命令
启动MySQL服务的命令
- net start MySQL的服务名(MySQL57)
- 停止MySQL服务的命令
- net stop MySQL的服务名
- 在使用的时候,需要注意启动服务命令和停止服务命令需要具有管理员权限,所以在打开控制台的时候,请以管理员的身份来运行控制台程序。
卸载MySQL服务命令
- sc delete 服务名
2、使用MySQL命令来登录MySQL服务
登录本地数据库服务器
- mysql -u 帐号名 -p 回车
- 会以指定的帐号名来登录本地服务器,并且会提示用户输入密码
- mysql -u 帐号名 -p密码(-p和密码之间不能有空格)
- 会以指定的帐号名来登录本地服务器,密码不需要输入了
登录远程数据库服务器
- mysql -h 127.0.0.1 -u root -padmin
- 连接ip地址为127.0.0.1的远程服务器,并以root做为用户名admin做为密码
- 登录数据库的同时去使用一个指定的数据库
- mysql -D 数据库名 -u root -padmin
- 会以root帐号,admin为密码登录本地服务器,并使用指定的数据库
断开当前数据库连接
exit
- 会以root帐号,admin为密码登录本地服务器,并使用指定的数据库
断开当前数据库连接
3、数据库相关命令
- 查看一下当前数据库服务器中已经存在了哪些数据库
show databases;
新建数据库
- create database 数据库名;
- create database 数据库名 character set 字符编码集;
- 采用指定的字符集创建数据库
删除数据库
- drop database 数据库名;
使用数据库
- use 数据库名;
- 通过use命令,切换当前操作的数据库环境,use数据库名可以切换到指定的数据库下,再执行的对表的操作,就是针对于指定数据库下的表的操作
- 若执行命令之后,显示Database changed;代表数据库改变成功
查看数据库元数据
- select database();
- 查看当前数据库的名
- select version();
- 查看服务器的版本信息
- select user();
- 查看当前登录的用户名
- show status;
- 显示服务器状态
- show variables;
- 显示当前服务器的配置变量
- select now();
- 显示当前(服务器)时间
- select dayofmonth(current_date);
- 显示当前的日,一个月中的第几天
- select month(current_date);
- 显示当前的月份
- select year(current_date);
- 显示当前的年
- select '字符串内容';
- 显示指定的字符串
- select 数学公式或表达式 如 select 123+321; 结果为444
- 显示指定的表达式的结果
当执行SQL语句之后返回的结果有以下几种情况:
- 1、Query OK, 1 row affected (0.01 sec):
- 查询成功,1行受到影响(使用了0.01秒完成的操作)
- 2、ERROR 1007 (HY000): Can't create database 'j259db'; database exists:
- 错误: 不能 创建 数据库 数据库 已存在
- 3、ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'databases j259db' at line
- 错误(1064语法错误)你出现了一个错误在你的SQL语法中,请检查你的SQL语句是否适合指定的MySQL 服务器版本,请输入正确的语法在database j259db附近
- 4、SQL语言
- SQL(Structured Query Language 结构化查询语言),是一款特殊的编程语言,它是专门用来对数据查询和程序设计语言,主要用来存取数据和查询、更新和管理关系数据库系统。在实际开发过程中,SQL往往会做为一个独立的语系分支来去使用,我们可以使用SQL直接在数据库后台就可以操纵数据。并且可以对数据库进行性能优化和提升。
按照功能,将SQL语言分为四大类:
DDL:数据定义语言(Data Definition Language)
- 主要作用是用于定义数据库的逻辑结构。包括数据库的定义、表的定义及其它数据库对象的定义,特征关键字:create alter drop
DML:数据操纵语言
- 主要作用是用来控制数据,我们要执行数据的插入、删除和修改,特征关键字:insert delete update
DQL:数据查询语言
- 主要作用就是用来进行数据查询操作,特征关键字:select
DCL:数据控制语言
- 主要作用是用来对数据库的安全性进行控制,比如用户权限的赋予或者取消,特征关键字:grant revoke
数据库常用SQL语句:
<>为必选项 []为可选项
- 1、创建数据表
语法:
create table <数据表名>
(
<字段名1> <字段类型1(字段长度)> [字段属性],
<字段名2> <字段类型2(字段长度)> [字段属性],
....
<字段名n> <字段类型n(字段长度)>[字段属性]
)
示例:
- 创建一个图书类别表,表中有类别编号,类别名称两个字段
| 编号 | 类别 |
|---|---|
| BookCategory | |
| categoryId | int |
| categoryName | String |
MySQL中数据类型有哪些:
三大类:
- 1、数值类
| 整数类型 | 字节 |
|---|---|
| tinyint | 1字节 |
| smallint | 2字节 |
| mediumint | 3字节 |
| int | 4字节 |
| bigint | |
| integer | 4字节 |
| tinyint | -128~127 0~255 |
浮点类型 |
字节 |
| float | 4字节 |
| double | 8字节 |
| decimal |
- decimal是可以由程序指定长度的(还可以指定小数点位数)
2、日期时间类
| 单词 | 翻译 | 字节 |
|---|---|---|
| year | 年 | 1 |
| date | 年月日 | 3 |
| time | 时分秒 | 3 |
| datetime | 年月日时分秒 | 8 |
| timestamp | 时间戳 | 8 |
- 1970-1-1 0:0:0:000到现在
3、字符或字符串类
字符串类
- char、varchar
字节串类
- binary、varbinary
二进制长文本类型
- blob
长文本类型
- text
练习:
- 1、图书表(Book)
| 字段 | 字段名 | 数据类型 | 长度 |
|---|---|---|---|
| 图书编号 | bookid | smallint | |
| 图书名称 | bookname | varchar | 20 |
| 图书类别 | category | int | |
| 出版时间 | pubDate | date | |
| 图书价格 | price | decimal | 长度5,小数点后2位 |
| 图书介绍 | memo | text |
表名和列名的命名规则和规范**
- 研发过程中经常发生因为数据库表的设计不良而影响开发进度的问题,其中最低级的一种错误就是命名格式不规范或者命名方案不统一、可读性不高等等,所以在一开始我们就要对表名和列表进行规范的设计,是构建良好SQL编程的前提。 数据库命名规范
- 1、字母+数字+下划线
- 2、不要用关键字
- 3、若有多个单词,中间可用下划线进行拼接
- studentName
- student_name
- 4、命名要见名知义
- 5、简明扼要
- Student
- s_id
- s_name
- s_age
- Teacher
- t_id
- t_name
- 数据查询优化关键点之一:列名不宜过长
- 6、表名和字段名不要使用复数形式
- 不要使用Students 使用Student
- 7、表名和字段名尽量不要使用缩写
- sid
- sname
- sage
- 以上的三个变量命名不规范,容易产生歧义
- 8、尽量定义注释,为表名和列名定义注释
关于数据类型的定义规范:
- 1、数据要对应数据类型
- 2、尽量不要浪费存储空间
- 能用tinyint就别用smallint,
- 能用smallint就别用int,
- 能用varchar(20),就别用varchar(255)
列属性:
- not null :非NULL,该列不可以为null,必须给其赋值
- default 值:默认值,该列若不赋值,则按默认值进行赋值
- auto_increment:自动增长,该列中的值为自动增长值,不需要用户进行赋值,使用该关键字进行修饰的数据类型必须是整数类型的
数据类型补充:
-
unsigned:无符号,若不写该关键字,则数据类型的最小值是从负数开始,若加入该关键字,则数据类型的最小值从0开始
-
tinyint 若使用有符号(默认),最小值是-128,最大值是127
-
tinyint使用unsinged,则最小值是0,最大值是255
-
PS:创建表还有一种扩展操作,就是在创建表的同时,指定该表采用的默认字符编码
-
create table 表名
- ( 列名 数据类型 长度 列属性. )
- engine=innodb default charset=utf8;
-
2、删除表
- drop table 表名;
-
3、修改表
- 查看表结构
- desc student;
- 或者
- describe student;

修改表名
-
alter table 老表名 rename to 新表名; 修改表结构
-
1、修改指定列的类型
- alter table 表名 modify column s_name varchar(12) not null;
-
2、修改指定列的列属性
- alter table 表名 modify column s_name varchar(12) null default '未命名';
-
3、添加列
- alter table 表名 add s_phone char(11) not null;
-
4、删除列
- alter table 表名 drop 列名
-
5、调整字段的顺序
- 1、更改现有字段的排列顺序
- alter table student change s_sex s_sex char(2) not null default '男' after s_id;
- 2、添加一个新的字段在指定的字段之后
- alter table 表名 add column s_phone char(11) not null after s_sex;
- 1、更改现有字段的排列顺序
约束:
- 在MySQL中代表着一种限制、规定。对数据的限制,对数据的规定。
- 约束制定了你必须做什么,不能做什么。
- MySQL通过约束来实现对表中数据的有效性和完整性做出保证的一种方式
约束的类型:
- 1、主键约束:primary key,主要的键,主键约束的特点是这个列中所有的数据不能有重复,并且不能为null,一张表中只能有一个主键约束,一个主键约束可以由1个列或多个列组合而成。
- 2、非空约束:not null,不能为空,非空约束的特点是这个列中的所有数据不能为null
- 3、默认约束:default,默认的值,默认约束定义该列是有默认值的
- 4、唯一约束:unique key,唯一的不重复的,唯一约束的特点是这个列中的所有数据不能有重复,但是可以为null
- 5、外键约束:foreign key,需要与主键约束配合使用,涉及两张表的操作
- 外键约束的作用,就是规范外键列中的数据,必须是主键表中的主键列,若主键表中的主键列并 - 没有指定的值,那么外键表中的外键列就不能添加指定的值
- 前4种都属于字段属性,都是对数据值(列)进行约束
- 第5种约束,属于行级属性(记录约束),是对数据行进行约束
如何创建约束?
-
1、在创建表的同时创建约束
-
2、表创建完毕之后再添加约束
-
在创建表同时创建约束的语法是:
方式1:
create table 表名
(
主键字段名 数据类型 primary key, -- 创建主键约束的关键字
非空字段名 数据类型 not null, -- 创建非空约束的关键字,若不写,则代表可为空
默认字段名 数据类型 default '默认值', -- 创建默认约束的关键字
唯一字段名 数据类型 unique -- 创建唯一约束的关键字
外键字段名 数据类型 references 主键表名(主键列名) -- 此方式经过实测,无效,不支持
);
方式2:
create table 表名
(
字段名1 数据类型,
字段名2 数据类型,
字段名3 数据类型,
字段名4 数据类型,
字段名5 数据类型,
constraint PK_表名_字段名 primary key(字段名1),
constraint UQ_表名_字段名 unique(字段名2),
constraint FK_表名_字段名 foreign key(字段名3) references 主键表名(主键列)
)
创建表之后,再添加约束
- alter table 表名 add constraint 约束名 约束类型()
- 添加主键约束:
- alter table student add constraint PK_student_s_id primary key (s_id);
- 添加唯一约束:
- atler table student add constraint UQ_student_s_name unique (s_name);
- 添加外键约束:
- alter table student add constraint FK_student_f foreign key(外键字段) refrerence 主键表名(主键列名);
删除约束:
- 1、删除唯一约束:
- alter table test1 drop index 唯一约束名;
- 2、删除外键约束
- -- 先解除主外键关系
- alter table testb
- drop foreign key
FK_testb_tid;
- -- 再删除外键列(可选操作)
- alter table testb drop tid; PS:
- 在使用create table 表名这种方式创建的表,我们称为普通的数据表,但是在实际开发过程中还会用以一种临时表。
- 临时表:在数据库运行过程中,用来临时存储数据的一张表,主要作用就是临时的存储一些数据,这张表支持完整的增删改查(CRUD)操作,但是临时表只在当前连接有效的情况下可以访问,如果用户断掉当前连接,则临时表会自己删除并释放空间,当然就算连接未断开的情况下,用户也可以手动释放临时表。
create temporary table tempTable
(
sid int primary key,
sname varchar(20)
);
- 手动删除临时表,与删除普能表一下,使用drop table 临时表名
复制表
- 在实际开发过程中,我们经常会遇到需要将一张表中的结构复制出来形成一张临时表或者新表的情况,那么这种情况下,我们需要复制出原表中完整的表
结构、索引、约束和默认值等内容,这种情况下可以使用show create table表名 命令来获取建表的语句,该语句的执行结果会包含原数据表完整的结构、约束和索引。然后就可以复制这些代码,来新建一个表了,相当于完成了一个复制表的操作。 - 创建一张新表,这张新表中的所有数据是指定表中的数据
create temporary table tempTeacher
(
select * from teacher
);
- 这种方法创建的临时表,只具有原表中的结构和数据,并不能复制出原表的约束和索引
4、添加数据
- 向指定表中添加数据
- insert into 表名 values(值1,'值2',...);
- '字符、字符串或日期类型数据'
- values后面的值的顺序和个数一定要与表中的列的顺序和个数是一致的 添加数据的标准语法:
- insert into <表名>[(列名1,列名2,...)] values(数据值1,数据值2...)[,(数据值1,数据值2...)];
PS:
- 1、如果想从A表中复制所有的数据到B表中(A表中的结构与B表中的结构是一样)
- insert into B select * from A;
- 2、如果想从A表中复制指定字段的所有数据到B表中
- insert into B(B表字段1,B表字段2) select A表字段1,A表字段2 from A;
5、删除数据
- 删除数据的基本语法:
- delete from 表名;
- 删除表中所有的数据,危险性较大,所以在执行该语句一定要慎重。
- delete from 表名 where 筛选条件
- 按照指定的筛选条件来删除数据,符合筛选条件的数据,将会被删除掉
- 需要注意的是,删除数据的基本操作单位是数据行,也就是说删除数据是整行整行删除,不是只删除某一个字段中的值,如果你只是想删除某一个字段中的值,那是修改。
where 筛选条件,它属于一个独立的语法结构,可以与删除、修改和查询配合使用,来筛选出指定条件的数据
- 删除班级中所有的男同学
- delete from student where s_sex='男';
- 删除班级中所有年龄小于18岁的同学
- delete from student where s_age<18;
- 删除班级中所有小于18岁的男同学
- delete from student where s_age<18 and s_sex='男'
6、修改数据
修改数据的语法:
- update 表名 set 字段名=新值 [,字段名=新值]
- 将表中所有的数据都进行了修改
- update 表名 set 字段名=新值 [,字段名=新值] where 筛选条件
示例:
- 修改Account表中张老师的帐户余额,为1000元
7、查询数据
-
由于该内容的重要性,故将所有内容移动下面单独进行讲解
-
5、常用DBMS--DataGrip
-
DBMS和数据库是两个内容,数据库是服务,DBMS是用来操纵数据库服务的软件 MySQL中的DBMS:
- 1、navicat
- 2、DataGrip:是一款非常专业的DBMS,可以对市面上所有的常见数据库进行管理 下载:
-
1、进入百度,搜索DataGrip,并进入jetBirans的官网
-
2、下载DataGrip即可 安装:



解决乱码
- 为什么我们在创建完数据库,创建完数据表之后,向表中添加中文数据的时候,会产生乱码呢?,原因是数据库服务在安装的时候,默认采用的字符编码并不是UTF-8编码,所以当客户端向服务器发送中文数据时,服务器会不识别中文数据,如何解决的:
- 1、更改服务器的默认字符编码(我不建议)
- 2、设置连接字符串,在连接字符串中设置编码格式
jdbc:mysql://localhost:3306?useUnicode=true&characterEncoding=utf-8- 在设置好连接字符串之后,我们可以创建数据库了,在创建数据库时,为了保证数据是支持中文的,所以我们需要在创建数据库的同时,来设置一下数据库的默认字符编码方式:
create database数据库名default character set utf8 collate utf8_general_ci;- 这样我们就可以解决中文乱码的问题了
需要补充的是:
- 1、在创建数据库的时候,指定默认字符编码集,是让数据库支持中文
- 2、调用连接字符串中的编码格式,是告诉数据库,客户端采用的是什么编码格式 所以,在使用DBMS系统访问数据库,用数据库操作中文数据的时候,两都缺一不可
6、SQL语言高级操作
7、MySQL数据库调优**
-
建库建表建约束
-
增删改查和事务
-
存储过程触发器
-
视图索引与函数
-
前端(HTML+CSS+JS)获取用户数据
-
通过jQuery、AJAX、JSP将数据传递给后台
-
后台(Java)获得数据将数据传递给持久层(JDBC、MyBatis)
-
持久层负责与数据库(MySQL、Oracle)进行交互,实现数据存储
varchar和char的区别:
- 1、char和varchar都可以用来存储字符串
- 2、char(10),在数据库中就为每一个数据开辟了一个长度为10的字符空间,最多能存储10个字符,同时最少也是10个字符,如果在这个空间中存储了一个a的话,实际存储的是一个a加上九个空格
- varchar(10),定义的存储空间最长是10个,但是最少是根据实际的数据长度来决定的,也就是说如果这个空间中存储了一个a的话,实际存储的就是1个a
练习题:
- 1、使用SQL语句创建一个支持UTF-8字符编码的数据库,叫做BankDB
- 2、在该数据库中创建以下的几张表
帐户表(Account)
| ↓ | ↓ | ↓ | ↓ |
|---|---|---|---|
| 帐户编号 | a_id | bigint unsinged | 主键 |
| 用户姓名 | a_username | varchar(20) | 非空 |
| 用户年龄 | a_age | tinyint unsinged | 非空 |
| 用户性别 | a_sex | char(2) | 非空,默认为男 |
| 开户时间 | a_createdate | datetime | 非空 |
| 帐户余额 | a_balance | decimal(12,2) | 非空 |
交易表(Deal)
| ↓ | ↓ | ↓ | ↓ |
|---|---|---|---|
| 交易编号 | d_id | bigint | 主键 |
| 交易时间 | d_dealdate | datetime | 非空 |
| 交易类型 | d_dealtype | tinyint unsinged | 外键,非空 |
| 原帐户编号 | d_account1 | bigint unsinged | 外键,非空 |
| 目标帐户编号 | d_account2 | bigint unsinged | 外键,非空 |
| 交易金额 | d_money | decimal(12,2) | 非空 |
| 交易状态 | d_status | tinyint unsinged | 外键,非空 |
交易类型表(DealType)
| ↓ | ↓ | ↓ | ↓ |
|---|---|---|---|
| 交易类型编号 | dt_id | tinyint unsinged | 主键 |
| 交易类型名称 | dt_name | varchar(20) | 非空 |
- 1 转帐
- 2 存款
- 3 取款
交易状态表(DealStatus)
| ↓ | ↓ | ↓ | ↓ |
|---|---|---|---|
| 交易状态编号 | ds_id | tinyint unsinged | 主键 |
| 交易状态名称 | ds_name | varchar(20) | 非空 |
- 1、正常
- 2、延时
- 3、取消
- 3、通过SQL语句实现相应属性的约束添加操作
- 4、使用SQL语句,为每张表中至少添加3条测试数据
练习题:
学生表 Student
| ↓ | ↓ | ↓ |
|---|---|---|
| s_id | smallint unsigned | 主键 |
| s_name | varchar(20) | 非空 |
| s_sex | char(2) | 非空 默认男 |
| s_age | tinyint unsigned | 非空 |
| s_address | varchar(200) | |
| s_phone | char(11) | 唯一 |
| s_cardid | char(18) | 非空 唯一 |
老师表 Teacher
| ↓ | ↓ | ↓ |
|---|---|---|
| t_id | tinyint unsigned | 主键 |
| t_name | varchar(20) | 非空 |
课程表 Course
| ↓ | ↓ | ↓ |
|---|---|---|
| c_id | tinyint unsigned | 主键 |
| c_name | varchar(20) | 非空 |
| c_hours | tinyint unsigned | 非空 |
教学计划表 TeachPlan
| ↓ | ↓ | ↓ |
|---|---|---|
| tp_id | tinyint unsigned | 主键 |
| c_id | tinyint unsigned | 非空,外键 |
| t_id | tinyint unsigned | 非空,外键 |
考试成绩表 ExamScore
| ↓ | ↓ | ↓ |
|---|---|---|
| es_id | tinyint unsigned | 主键 |
| c_id | tinyint unsigned | 非空 外键 |
| s_id | smallint unsigned | 非空 外键 |
| sc_score | tinyint unsigned |
- 如果把增删改查(CRUD),8分查询,1分增加,1分修改,0分删除
上面的查询数据移到了这
- 查询操作属于DQL语言,是实际开发过程中最常应用的语言
- 在做查询的时候,大家脑海中一定要想这么几个问题
- 我想要啥数据?
- 我想要的这些数据在哪里呢?
基础语法:
SELECT [distinct] 字段名[as '列别名'][,字段] | *
FROM [数据库名.]表名
[
WHERE 筛选条件
GROUP BY 分组依据
HAVING 分组条件
ORDER BY 排序依据
LIMIT 限制行数
]
1、 字段列表,是用户想查看的字段列表,如果用户想查看表中所有字段,可以使用*号代替
2、 数据源,用户要查询的数据从哪些数据源中获取,数据源可是以普通的数据表、临时表、视图。
3、 筛选条件,用来设置筛选规则,查询语句会按照指定的筛选条件对数据进行过滤,不满足筛选条件的数据是不会查询出来的
4、 排序依据,默认为升序排序,也可以使用DESC(降序)或者ASC(升序)来指明排序的规则,排序依据可以添加多列,中间用逗号分隔,那么排序将会按照从左至右的先后顺序对数据进行排序,若第一个列中有重复值,则按第二个列进行排序。
5、 限制行数,共有两种用法:
- 1、limit 查看行数
- 2、limit 越过行数,查看行数
- 6、FROM - WHERE - GROUP BY - HAVING - DISTINCT - ORDER BY - LIMIT
顺序解析:
- 当所有的查询组件都存在的情况下,那么查询的执行顺序是:
- 1、执行from,确定查询的数据源
- 2、执行where,确定数据的筛选条件,并执行,获得符合条件的数据集
- 3、执行group by,对筛选后的数据进行分组
- 4、执行having,对分组后的数据进行再次筛选过滤
- 5、执行distinct,去掉重复的结果
- 6、执行orderby,对最后的结果进行排序
- 7、执行limit,对排序后的结果限制显示条数
- 8、执行select,显示结果
筛选条件和运算符:
- where 字段名 运算符 数据值
1、 比较运算符
-
< <= >= > = !=
2、 区间运算符
-
in
- in:在里面,只要数据在指定的数据源中存在,即符合条件 age in (18,19,20,21,22)
-
not in
- not int:不在里面,只要数据在指定的数据中不存在,即符合条件
-
between and
- between 18 and 22 e 18到22之间所有的数据都符合条件,区间 只能应用于数值数据和日期数据的区间筛选操作
3、 逻辑运算符
- not and or
- 逻辑运算符中的and 和 or的作用,是用来连接条件的,not是取反的
4、 相似运算符
- like,主要作用就是用来进行模糊筛选,数据类型为字符串类型,在使用like进行模糊筛选的时候,要与通配符配合使用,才能使用模糊筛选效果。
- %:代替任意多个任意字符
- _: 代表任意一个字符
- like '%文%'
5、 正则匹配符
- 正则匹配其实就是按照正则表达式来对数据的格式进行筛选
- 16103100225
- regexp '正则表达式公式'
- sid regexp '161031[0-9]{5}';
分组查询:
group by 字段:
- 可以按照指定的字段中的值,来进行分组,将相同的数据分成一组
- 分组之后的数据,因为已经按照指定的字段数据进行了分组,故除分数数据以外,其它数据无法正确的显示,所以分组一般是用来结合聚合函数,进行统计操作、
count(): 统计个数
max(): 统计最大值
min(): 统计最小值
sum(): 求和
avg(): 求平均值
- 分组之后,select显示的数据只能是分组的字段和聚合函数的值
- 聚合函数只能写在select后
- 统计男女生最小的学生是多少岁(先按性别分组,再统计最小年龄)
- select s_sex,min(s_age) from student group by s_sex;
每个课程有几个老师教(先按课程编号分组,再统计该课程老师人数
select course.c_name as '课程名称',count(*) as '老师人数'
from course inner join teachPlan on course.c_id = teachPlan.c_id
inner join teacher on teachPlan.t_id = teacher.t_id
group by teachPlan.c_id;
显示每门课都有哪些老师教(先按课程编号分组,再拼接分组后的老师姓名
select course.c_name as '课程名称',group_concat(teacher.t_name) as '老师姓名'
from course inner join teachPlan on course.c_id = teachPlan.c_id
inner join teacher on teachPlan.t_id = teacher.t_id
group by teachPlan.c_id;
显示每一位学生共参加了几次考试,都考了哪些试
- 庄新民版
select student.s_name as '学生姓名',group_concat(course.c_name)as '考试科目',count(*)as '共参加了考试次数'
from student inner join examScore on student.s_id = examScore.s_id
inner join course on examScore.c_id= course.c_id
group by student.s_id
order by course.c_id;
- 张浩涵版
select Student.s_name as '学生姓名',count(C.c_name) as '考试科目数量(科)',group_concat(C.c_name order by C.c_id) as '考试科目名字'
from Student inner join ExamScore `ES` on Student.s_id = `ES`.s_id
inner join Course `C` on `ES`.c_id = `C`.c_id
group by Student.s_name
- having分组筛选
- Where筛选是分组之前,对数据进行一次筛选,对筛选后的数据再进行分组
- having筛选是分组之后,对分组后的数据进行再一次的筛选,以满足分组的需要
PS:
- select count(s_sex) from student
- having count(s_sex);
- 这样也是可以的,只是单纯的为了使用聚合函数也可以只写having(或者省略)
结果排序:
- 对筛选后的数据进行升序或者降序的排列,这种排列只是对结果进行排序,不会影响数据在数据表中的存储位置。
- 排序默认情况下是升序,也可以使用
ASC代表升序,或者DESC代表降序 - 排序可以使用多个列进行排序,会按照从左至右的优先级进行排序,我们也可以分别为这些列指定排序的依据
- order by sex desc,sid asc,先按性别进行降序排序,如果性别相同,则按编号进行升序排序 限制结果:
limit用法共有两种:
- 1、limit m:只显示m行数据
- 2、limit m,n:从第m+1行开始,显示n行数据
多表连接查询
- 顾名思义多表连接查询就是查询的数据从多张表中获得,在这种查询语句中会联合使用多张表一起进行查询,所以多表连接查询属于MySQL中的高级查询操作,是一种常用的用于获取数据的查询语句,根据其不同的使用场景和需求,多表连接查询也分几种类型:
1、内连接查询
- 内连接查询查询的是交集数据
- 两张表中同时符合某种特定条件的数据记录的集合
举个例子:
| A表中 | B 表 |
|---|---|
| a和 b | b和 c |
| 1和 11 | 11和 a |
| 2 和 12 | 12和 b |
| 3和 11 | 13和 c |
| 4和 13 |
-
根据上图,我们可以看出,在获取数据的时候,我们需要查询到的是A表和B表中的共有数据(11、12、13),这两张表也是通过b字段连接在一起的,我们根据内连接的定义,就可以得知若A表和B表进行内连接操作的话,获取的就是11、12、13符合这三个数据的所有数据行
-
在MySQL中,内连接与交叉连接不同之处在于内连接比交叉连接多了限制条件(筛选条件),如果将内连接的限制条件去掉,内连接和交叉连接是一样的结果
-
换个思想,如果交叉连接加上on的话,那么会不会就是内连接了呢?
-
内连接去掉on,就是交叉连接
-
交叉连接加上on,就是内连接
-
但是官方要求,这两者其实是不同的,所以在使用
cross join和innerjoin的时候,一定要注意on的使用。 -
所谓的内连接,其实就是按照某种条件同时筛选两张表中都符合的记录
-
所谓的交叉连接,其实就是将两张表的数据进行组合(A表*B表)形成的数据集合
-
内连接就是建立在交叉连接形成的数据集合基础上,进行的数据筛选
-
在学习过程中,我们使用内连接往往使用的是等值内连接,
a.id=b.id -
还可以进行不等值连接。
-
在平常的时候,我会使用Where来代替连接查询,但是从数据库优化角度,连接查询的性能要高于Where查询,所以在面试实际开发过程中,遇到大量数据组合查询的时候,一定要使用连接查询。
2、外连接查询
左外连接查询 右外连接查询
- 我们在使用外连接的时候,主要是通过
左外连接和右外连接两种方式实现的,左和右是一种相对的称呼,所以只要弄清楚其中一种,那另外一种就不言而喻了。
左外连接:
left outer join,使用该关键字将两表进行左外连接
- 通过代码的演示,我们发现在同样的连接条件下(与内连接进行对比),左外连接(右外连接)会比内连接查询出来的数据多一点(也有可能相等),多出来的记录是左表存在,但是右表没有与之相等的数据(称为Null数据),左外连接,以左表为主,显示左表中所有数据,并按连接条件将右表中数据与其对应,若没有数据与其对应,则为null
3、交叉连接查询
4、联合查询
- 联合查询的实现效果非常简单,就是将两张表中的数据连接在一起显示出来
显示所有参加舞会的嘉宾名单
-
select name from A
-
union
-
select name form B
-
显示的结果就是两张表中共有的数据拼接而成的一个新的数据集合
-
在使用
union的时候,需要注意一件事情,就是两个查询的结果中的字段数并且是一样的,否则无法使用联合查询 -
在使用union的时候,若两表中有相同的数据进行联合查询,则union会自动的过滤掉相同数据,造成数据的丢失,那么这种情况下,如果你确定要显示所有的人员名单,确定就是名字重复了,那么可以使用
union all
5、全连接查询
- 在SQLServer中是有的,full join ,但是在MySQL中是不存在的
事务
- 建库建表建约束
- 增删改查和事务
- innodb本身最大的特点就是支持事务,事务也是关系型数据库最需要注意和使用的地方。
事务: 按字面意思理解,事务就是一个事情,一个事情可能会分为若干个步骤,这若干个步骤组合形成了一件事情
我是普通的员工,过年了,我想给我领导送点礼:
-
1、买东西:执行买东西相应的操作
-
2、送东西:执行送东西相应的操作
-
3、领导收东西:执行领导收东西的操作
-
可是,当买完东西,送完东西之后,领导不收,那么给领导送礼的操作就相当于无效的(没有完成)
- 第1个步骤:买东西
- 第2个步骤:送东西
-
虽然成功了,但是第3个步骤没有成功,那么就导致整个给领导送礼物的操作失败
-
将前两个步骤的操作也取消
-
这个就叫做事务
-
要不一起成功,要不一起失败
在MySQL中:
- 默认的每一条语句指令就是一个事务,但是在实际开发过程中,经常会遇到将一系列的事情算做一个事务的操作,需要在一个事务中包含多条SQL语句指令,并将这些语句指令当成一个整体的执行单元去执行,这种情况下,我们就需要修改事务的级别,将这些语句当成一个整体的事务进行设置就可以了。
事务有四大特性:ACID
A:Atomicity 原子性: 事务里所有的操作(语句)是不可分割的,要不然一起成功,要不然一起失败,是一个整体。
C:Consistency 一致性: 数据在数据库中总是保持着数据的一致的状态
I: Isolation 隔离性: 每一个事务都是独立的,事务中的操作对于其它事务来说是不可见的,但是我们可以通过设置事务的隔离级别来控制可见性
D:Durability 持久性: 事务一旦被成功的执行提交,事务所做的所有操作结果都会被修改并永远保存,就算出现未知错误,也不会影响事务的更改结果
- A 转出100元钱给B帐户 A帐户要减100元
- B 从A帐户接受到100元 B帐户要加100元
MySQL
因为采用了innodb存储引擎,所以MySQL默认情况下就支持事务的ACID特性
概念:
使用事务就是将多条SQL语句指令设置成一个整体执行单元,这个单元中的指令还是会按照顺序从上至下的顺序执行,但是除非所有的语句都执行成功,那么我们才提前这个事务,否则如果只要有一个指令执行出现了错误,那么我就不提交这个事务,并且将已经执行完成(成功)的SQL语句的操作结果取消·(回滚)
事务伪代码语法:
-
设置事务开始位置
-
SQL语句指令1;
-
SQL语句指令2;
-
SQL语句指令3;
-
SQL语句指令4;
-
SQL语句指令5;
-
提交事务(事务完成)
-
事务是如何实现数据的一致性(要不一起成功,要不然一起失败),怎么做到已经操作完了,结果不算数了。
事务实现的原理:
- 事务是通过一个叫做事务日志的机制来实现数据的提交和回滚操作的
- 事务日志分为两种日志 和 取消日志: undo log 重做日志: redo log
undo日志 :
- 理解成数据被修改前的数据备份(类似于游戏的存档文件,修改之前先备份,没问题了,这个备份就可以删除了,若有问题,直接将你之前的备份数据设置成你现在的值)。比如事务中有10条语句,你都成功执行了9条了,如果最后一条执行失败了,那么我们就可以通过
undo log将执行这9条语句之前的数据恢复回来。undo日志是逻辑日志。
redo日志
- mysql会将事务中的SQL语句中涉及数据操作的记录先存放到
redo log中,然后再将操作从redo log同步到对应的数据文件中。通俗的讲,在事务执行commit提交之前,在修改对应的数据文件中的记录之前,一定要保证对应的记录修改操作都已经记录到了redo日志中。redo日志主要是实现原子性,保证的是一个事务单元中包含所有的SQL执行指令。
redo日志分为两部分:
- 1、redo log buffer(重做日志缓冲),存储在内存中,速度快,易丢失
- 2、redo log file(重做日志文件),存储在磁盘上,速度慢,持久性
- redo 日志是物理日志(能看得见的),而且redo日志中的记录是数据库对数据的实际的操作,而不是逻辑上的增删改查。
在MySQL中去实现事务:
1、需要设置事务的开始
2、编写事务中的执行语句
3、提前事务
如何设置并且控制我们的事务
-
首先,在MySQL中,默认情况下,每一条SQL语句都是一个完整的事务,并且在执行语句之后,若语句执行成功,则会自动的进行事务的提交操作,若语句执行失败,则会自动的执行回滚操作。为什么这么方便呢,是因为MySQL在默认情况下采用的事务提交方式为自动提交。
-
我们来看一下事务中的一些关键指令(关键字)
- start transaction; (可以简写成begin)
-
显示的开始一个事务,从这条语句之后到事务结束语句之前的所有SQL指令都是事务中的代码
- commit;(commit work)
-
提交,提交事务,代表着事务中的所有操作将会被持久的保存下来,一般情况下是没有错误的时候,就可以提交了。
- rollback;(rollback work)
-
回滚,回滚事务,代表着事务中语句出现了问题,要取消事务中所有的指令操作,回滚之后,数据会保持一致性,恢复到执行事务之前的状态。
- savepoint 保存点;
-
创建一个临时的保存点,用来解决,若一个大事务中包含很多条指令,比如有10条指令,前三条是一个小操作,中间三是一个小操作,后四是一个小操作,若第二小操作出现问题,我们只想回滚到第一个小操作完成之后就可以了,让用户继续尝试,这样就需要用到保存点,因为回滚是从头回滚,而使用了保存点之后,我们可以阶段性回滚,这样不需要重新执行指令,不用回滚整个事务。 在一个事务中可以包含多个保存点 -rollback to savepoint 保存点名;(小回滚)
-
回滚到指定的保存点位置,执行完该语句,会撤销对应保存点之后的所有操作,并且不会结束当前的大事务,回滚到指定的保存点以后还可以继续操作,还是在这个大事务里面,与
rollback关键字不同。
begin
1
2
savepoint a;
3
4
savepoint b
5
savepoint c
6
rollback to savepoint a
release savepoint 保存点名;
删除一个指定的保存点
使用事务的时候,语法:
start transaction;
SQL指令
SQL指令
commit;
start transaction;
SQL指令
SQL指令
rollback;
视图:View
概念: 视图说白了就是数据表的一种逻辑上的展现方式,视图可以理解成是数据表的界面,数据表是视图的数据来源,数据表才是真正存储数据的地方,而视图主要就是用来负责展示,所以视图中是没有数据的,视图是不存储数据的,当我们操作一个视图的时候,其实是通过视图来操作视图背后的数据表。所以视图可以理解成它是一张虚拟的数据表,视图中可以包含一张表或多张表的结构和数据,但是这些结构和数据只是通过视图展现出来,并不是真正的存储在视图中
- 数据表是仓库,视图就是实体店,实体店只负责向用户展示商品,而所有的商品都是来源于仓库的。 所以视图称之为虚表,视图是一张根本就不存在的表
视图的优势:
1、简化操作:
- 当我们经常要做一种复杂的查询操作时(连接查询、组合查询、分组查询...),都可以过视图来提前的保存(定义)好查询的语句,这样在后面我们想要执行查询操作时,就不需要再编写较复杂的查询代码,只需要像操作数据表一样,操作视图即可。视图简化了表和表之间的查询关系和查询语句。
2、安全性更高:
-
表名和字段名如果暴露给前端用户,可能会对数据库的安全性造成危害,可能会产生SQL注入攻击的情况出现,还有就是A表中有些数据我只想a用户看,b用户只给其看A表中的某几列数据,那么这种情况下,我们就可以通过视图来完成不同用户访问不同视图的操作。
-
b用户不具备访问数据表的权限,但是让b用户具有访问视力的权限,这样b用户就没有办法查看A表中的所有记录所有字段,只能查看视图中所定义的字段数据
-
视图在使用的时候,需要注意SQL语句的优化,因为在使用视图时往往隐藏了具体的语句实现,所以视图中如何定义的连接查询语句就会大大影响整体的查询性能。
-
所以编写视图一定要注意SQL语句的优化问题,如果能解决该问题,那么视图全身上下都是优点,建议大家以后经常使用视图来查询数据。
创建视图的语法:
create view 视图名
as
查询语句
;
创建或替换视图的语法:
create or replace view 视图名
as
查询语句
;
删除视图的语法:
drop view 视图名;
drop view if exists 视图名;
如果视图则执行删除操作,若视图不存在,则不执行任何操作
create database if not exists Studentdb;
查询指定数据库中的所有视图:
select * from information_schema.VIEWS where TABLE_SCHEMA='数据库名';
修改视图:
alter view 视图名
as
SQL语句
;
视图用来做查询非常的方便,同时我们也知道了视图中是没有数据的,它只是存储了表的查询语句,那么请问,可否通过视图来完成增删改的操作呢? 视图一般情况下,只是用来进行查询操作的,查看数据的,我们很少会用视图进行增删改操作,虽然它可以,但是这个可以是建立在一定的条件下的,如果视图包含以下几种情况,是不可以使用视图进行增删改操作的:
- 1、视图中使用了聚合函数
- 2、视图中使用了group by 分组
- 3、使用了union联合查询
- 4、使用了join表连接
- 5、使用了distinct关键字
- 6、当视图设定了algorithm=temptable
视图的查询 是可以添加条件的,你可以把视图当成一张表来操作
1、创建一个视图 用来查询张老师所教授各课程的最高分、最低分和平均分 avg
- 先通过老师姓名在老师表中查询张老师的编号,
- 然后在教学计划表中获取张老师对应编号所教授的课程
- 然后在成线表中查询该课程编号的所有考试成绩进行聚合函数汇总 (可使用连接查询和子查询都做一下,大家体会一下子查询和内连接查询的区别) 第一题完成的同学在群里扣1
- Java基础 99 86 76.5
- JavaWeb 98 75 85
2、创建一个视图
用来显示每一位老师所教授所有课程的最高分、最低分和平均分avg
- 张老师 99 75 78
- 李老师 88 75 79
3、创建一个视图,
- 用来统计每名学生的考试总分 sum
- 庄新民 856
4、创建一个视图,
- 用来显示缺考学生的名单信息和课程信息
- 赵文博 Java基础
- 赵文博 UI设计
5、创建一个视图,
- 用来显示每门课程的教师安排情况
- 课程名称 教师数 教师姓名
- Java基础 2 张老师,周老师
存储过程
- 存储过程就是数据库中的方法
- Java中访问的定义语法
访问修饰符 返回值类型 方法名(参数列表){
方法体
}
- 存储过程在定义的时候,与方法的定义方式基本上是一样的
CREATE PROCEDURE 存储过程名(参数)
begin
存储过程体
end
存储概念:
- 持久性的保存在数据库端,可以将复杂的操作,持久的保存在数据库服务中,这样前台在调用存储过程时,只需要传递存储过程名,即可实现操作。并且因为存储过程在创建的同时就完成了语句的编译,所以执行速度会更快(当我们执行每一条SQL语句的时候,将SQL语句发送给数据库服务器端,数据库服务器接收到SQL语句之后,需要将先SQL语句进行编译,编译的过程也是对语法的检查,检查通过之后,再执行操作)
- 过程:步骤的集合,指令的集合,指令的是MySQL指令的集合,可以用来完成一种特定的操作。
使用存储的最终目标
- 是将常用的或者是复杂的SQL语句提前的编写好,并封装到存储过程中,并编译之后保存在数据库服务器中,从而实现:方便调用、执行高效、操作封装,最终实现数据库优化操作。 所有的常见主流关系型数据库基本上都支持存储过程
- MySQL在5.0版本以后开始支持存储过程
存储过程的定义:
- 创建存储过程
- 语法:
创建无参存储过程:
CREATE PROCEDURE <存储过程名>()
BEGIN
存储过程体
END
创建有参存储过程:
- 存储过程的参数分为输入参数、输出参数(返回值)、输入输出参数三种类型
- 存储过程可以有多个输出参数(有多个返回值)
CREATE PROCEDURE <存储过程名>(参数类型 参数名 参数数据类型)
BEGIN
存储过程体
END
示例:
- 创建无参存储过程并调用
create procedure sp_showAllStudents()
begin
select * from student;
end;
创建有一个输入参数的存储过程: call sp_showAllStudents();
创建有一个输入一个输出的存储过程:
create procedure sp_getStudentBySex(in sex char(2))
begin
select * from student where schooldb.student.s_sex=sex;
end ;
过程的操作
修改存储过程
ALTER PROCEDURE 存储过程名 MODIFIES SQL DATA SQL SECURITY INVOKER
BEGIN
存储过程语句
- END
删除存储过程
- DROP PROCEDURE 存储过程名;
存储过程的调用:
调用无参:
- CALL 存储过程名();
- CALL 存储过程名;也是可以的,但是不规范
调用有参:
- 输入参数
- CALL 存储过程名(值);
- 输出参数
- CALL 存储过程名(@变量名);
练习题
- 1、使用bankDB,银行数据库
- Account Deal
- 2、现要求,使用存储过程实现以下的功能:
- 1、调用存储过程时,传递账户1编号,帐户2编号,转帐金额,设置输出参数flag
- 2、完成相应表中数据的操作
- 1、改变Account表中的用户金额
- 2、在Deal表中添加一条交易记录
- 3、默认情况下,Deal表中交易状态为正常,交易日期为系统当前时间now()
- 4、转账成功,返回1
深入了解一下存储过程的创建方式:
- 存储过程是一组SQL指令的集合,除了DML、DQL以及DDL以外,还可以通过条件结构、循环结构来实现一些较为复杂的逻辑操作,同时,我们也可以在存储过程中,定义变量(类似于Java中的局部变量)
MySQL中的变量
分为四种类型:
- 1、用户变量
- 特征:@用户变量名,用户变量是跟MySQL的客户端有直接关系的,只对当前用户使用的客户端有效。默认情况下,一个客户端就是一个用户。(root)
- 2、会话变量:只针对于当前会话的客户端有效。
- 3、局部变量:局部变量一般情况下是定义在begin和end块中的变量
- 4、全局变量
- 特征:@@全局变量名,对所有的连接到该服务器的客户端有效,所有的用户都可以访问全局变量。全局变量普通用户是没有权力创建的,只有DBA权限才可以设置全局变量。
如何在存储过程中创建局部变量:
- 语法:
declare 局部变量名 数据类型;
set 局部变量名 = 值; 为局部变量赋值
或者将以上两步合二为一
declare 局部变量名 数据类型 DEFAULT 初始值;
MySQL中的条件结构
语法:
- 1、简单if结构
IF 条件 THEN
操作
END IF;
- 2、标准if else结构
IF 条件 THEN
操作1
ELSE
操作2
END IF;
- 3、多重if结构
IF 条件 THEN
操作1;
ELSEIF 条件2 THEN
操作2;
ELSE
操作3;
END IF;
- 4、CASE结构
CASE 表达式或变量
WHEN 常量值 THEN
操作1;
WHEN 常量值 THEN
操作2;
WHEN 常量值 THEN
操作3;
ELSE
操作4
END CASE
- MySQL中的循环结构
while 循环条件 do
循环操作;
循环操作;
end while
- 存储过程中的事务管理
- 事务在MySQL的存储过程中,默认是没有事务的,而在Oracle数据库中存储过程默认是一个事务
建库建表建约束
增删改查和事务
存储过程触发器
视图索引与函数
- JDBC
- MyBatis
- HTML+CSS+JS
晨练:
-
1、使用MySQL语句实现创建testDB数据库,并且设置数据库默认字符编码为UTF-8
-
2、在testDB数据库中使用MySQL语句实现以下操作
-
如果Student表不存在,则创建Student表,表结构如下:
- student_id int 无符号 主键,自增长
- student_name varchar(20) 非空
- student_gender char(2) 非空,默认男
-
如果Work表不存在,则创建Work表,表结构如下:
- work_id int 主键,自增长
- student_id int 无符号 非空,外键
- work_date datetime not null
-
3、向各表添加3条测试数据
MySQL中的触发器
- A是一张表,当对A表进行增加、删除、修改操作的时候,我们可以让数据库自动的去执行定义好的功能。
- 触发器是MySQL的数据库对象之一(存放在数据库中的),作用就是当表满足了某种特定的条件的时候,会自动的触发,并去执行触发器中所定义的SQL语句集合,我们经常用触发器来优化数据库的操作,保证数据库中数据的完整性、安全性。
- 触发器核心点:
- 什么情况下触发
- 什么时候触发
- 针对于哪张表进行触发
- 触发之后干什么
定义触发器的语法:
CREATE TRIGGER 触发器名字
触发时间 触发事件
ON 表名
[触发顺序]
FOR EACH ROW
触发器代码
1、触发时间: BEFORE(之前)、AFTER(之后) 触发时间是用来设置触发器的代码是执行触发事件之前执行,还是触发事件之后执行
2、触发事件: INSERT(插入触发器)、DELETE(删除触发器)、UPDATE(修改触发器) 触发事件是用来设置,当表在执行添加、删除、修改操作的时候,会自动进行触发的事件类型,也就是说,如果表中设置的触发事件为插入触发的话,那么当表在执行插入数据操作时,才会自动的执行触发器
3、FOR EACH ROW: 这是一个关键字,代表触发器对会指定表中每一行数据进行检测,你只对表中的任何一个数据进行操作,都会触发触发器。
4、触发顺序: FOLLOWS(当前触发器在现有触发器之后执行)、PRECEDES(当前触发器在现有触发器之前执行)
- 是触发器的可选参数(5.7版本以后新增的),如果定义了多个具有相同触发事件和触发时间的触发器时,默认情况下触发的顺序是按照创建的顺序来执行的,谁先创建的谁先执行,但是我们可以通过触发顺序这个可选项来改变相同触发事件、相同触发时间的多个触发器的执行顺序。
示例:
-
现有两张表,表结构是一样的,A表做为主表,B表做为备份表
-
当对A表进行添加数据操作时,B表同时进行添加数据的操作
-
添加触发器中,可以使用new来代表新增加的数据,通过new.字段名的方式可以获取新增加的数据中各字段的值,但是添加触发器中没有old。
-
修改触发器中,可以使用old来代表修改之前的数据,用new代表新的数据
-
删除触发器中,可以使用old来代表删除的数据,但是删除触发器中没有new
-
触发器与存储过程类似,都是一个结构体,可以包含多条SQL语句指令,所以可以使用begin和end来定义触发器的结构体,在触发器中我们可以定义用户变量而无需使用声明,可以直接使用@变量名就可以创建和使用变量了,其次触发器也可以使用if和while结构
2、查看触发器
-
方式1,显示当前服务器中所有的触发器
-
select * from information_schema.TRIGGERS;
-
select * from information_schema.TRIGGERS where TRIGGER_SCHEMA='testdb';
-
select * from information_schema.TRIGGERS where EVENT_OBJECT_TABLE = 'c';
-
show databases;
-
show tables;
-
-
方式2 ,直接查询数据库中的triggers对象,显示当前数据中所有的触发器
- show triggers ;
-
查看指定数据库中的触发器
- show triggers from bankdb;
-
3、删除触发器
- drop trigger 触发器名
- drop trigger if exists 触发器名
MySQL中的索引
主键索引: 在一张表中,为某一个字段定义成主键,那么这个字段就是主键索引
唯一索引: 在一张表中,为某一个字段定义成唯一约束,那么这个字段就是唯一索引
为什么要使用索引呢?
- 数据库的主要作用:
- 1、持久数据,将数据永远的保存下来,方便程序的调用
- 2、操作数据,DML:数据管理语言,insert delete update
- 3、检索数据:DQL:数据查询语言
概念: 随着数据的日益庞大,数据库中所存储的数据也达到了一个非常恐怖的量级,随便都是千万级数据,如果快速的检索(查询)到用户所需要的数据,是我们一个合格的数据库设计者、管理者、使用者都需要考虑的事情,所以数据库厂商为了加快数据的检索速度,采用了多种方式来提高数据的检索,索引就是其中一种,索引是按照一定的规律,来改变数据的存储位置,从而能加快数据的检索速度。 字典中的数据量很大,所以为了能加快数据的检索速度,每一个汉字在印制(存储)的时候,会按照一定的规律(拼音)进行有序的排列,并将排列之后的结果,形成一种检索页(索引页)和数据页(实际存储数据的页),用来在查找数据时,通过索引页来找到数据实际存储的位置。
-
MySQL中的索引,就是一种数据的存储机制,按照一定的规律将数据进行存储,从而实现一种快速的数据检索。
-
索引为了检索而生,有了索引检索速度会大大提升!所以索引是优化数据库操作中最重要的一个内容。
索引的分类:
1、单列索引: 顾名思义,单列索引是作用于一个列上的索引,但是一张表中可以包含多个单列索引, 主键索引、唯一索引、普通索引都属于单列索引
2、组合索引 顾名思义,组合索引就将表中的多个字段组合在一起创建的索引。
3、全文索引 只能在MyISAM存储引擎中使用,它的主要作用就是对文字中的数据进行索引
4、空间索引 是对空间数据类型的字段建立索引,point geometry
如何使用索引:
- 1、创建索引
- 单例索引:
- 主键索引
- 唯一索引
- 以上两种索引,是在建立约束的同时,就创建了
- primary key
- unique
普通索引的创建
商品表
1、创建表同时,添加普通索引
- 商品编号 int unsigned primary key, -- 创建了主键索引
- 商品名称 varchar(20) unique, -- 创建了唯一索引
- 商品生产日期 year not null,
- index(商品生产日期) -- 普通索引
- key(商品生产日期) -- 普通索引
2、创建表之后添加普通索引
- alter table 表名
- add index
索引名(字段名);
- add index
组合索引
alter table 表名
add index `索引名`(字段名1,字段名2,字段名3);
create index `索引名` on `表名`(字段名1,字段名2,字段名3);
概念 主键索引可不可以包含多列 主键索引可不可以有多个(一张表中只能一个主键)
- 在MySQL中,是支持将多个列做为一个主键列,只要这些列组合起来的值没有重复值即可(张浩涵:这多个列没有完全相同的数据)。
删除索引:
- drop index 索引名 on 表名;
索引的优缺点:
优点:
- 1、索引可以确保数据的唯一性(主键索引、唯一索引),不会有重复的数据
- 2、索引可以大大加快数据的检索速度,并且减少表的检索行数,先在索引页中找,找到之后再对应到相应的数据页。
- 3、在分组和排序的时候进行检索,可以有效的减少分组和排序时所消耗的时间
- 4、在表连接的时候,使用索引字段做为关联字段,可以加快表和表直接的连接操作
- 总之一句话,索引的优点就是检索速度快
2、缺点:
-
1、在创建索引和维护索引上,会消耗系统的时间(创建索引时间是需要额外操作,添加一条记录进入到表中,需要一定的时间,给这个数据找位置),这些时间会随着数据量的加大而不断的增加
-
2、在创建时候的同时,会创建索引面,索引页可以理解成是一个特殊的数据页,因为这个页里存储的是索引数据,所以索引在使用的时候,会占用物理磁盘,每一个索引都会占用自己的物理磁盘
-
3、因为索引主要是用来执行select操作,所以对索引数据进行增删改操作时,会加大索引的维护成本,所以索引列不建议经常修改
-
总之一句话,索引的缺点就是占地方
-
空间换性能
-
空间复杂度、时间复杂度
-
哪些键适合做索引,哪些情况下不能创建索引
-
重点:哪些情况下不能使用索引
- 1、查询时很少使用到的列,不适用于加索引(不需要查询字段,就没有必须建立索引页,建立了反而增加了数据的空间复杂度)
- 2、数据行较少的表中,不适用于加索引(如果一张表中只有两三个数据,那么建立索引页就有点得不偿失,速度没上来,反而空间复杂度变大了,结果会变慢)
- 3、较大数据类型不适用于加索引,比如二进制类型、图像类型和长文本类型
- 4、当某张表的DML操作远远大于DQL操作时,不适用于建立索引。