Mysql之mysql基础篇

MYSQL

mysql简介

mysql官网 mysql是一个开源的关系型数据库管理系统,现在是oracle公司旗下的一款产品,由C和C++语言编写,可移植性高。支持在多种操作系统上安装,最常见有AIX,linux,window。mysql因为开源免费,所以受到了目前互联网行业的欢迎。

版本区别

  • MySQL Community Server 社区版本,开源免费,但不提供官方技术支持。
  • MySQL Enterprise Edition 企业版本,需付费,购买了之后可以电话支持。
  • MySQL Cluster 集群版,开源免费。可将几个MySQL Server封装成一个Server。

数据库的基本概念详解

  1. 什么是库?

顾名思义就是数据仓库的意思,存储着一定数据结构的数据,一个数据库中可能包含着若干个表,我们可以通过数据库提供的多种方法来管理数据库里边的数据。本质上mysql数据库是一个关系型数据服务管理系统。

  1. 什么是表?

我们所说的表就是数据表,每一张表是由行和列组成,每记录一条数据,数据表就增加一行。列是由字段名与字段数据属性组成,我们称之列为字段,每一个字段有着多个属性。例如是否允许为空、长度、类型等等。

数据库:database
数据表:table
字段(列):column
行:row

mysql的操作语句分类

操作语句分为四类:

  1. DDL 数据定义语言 (Data Definition Language) 。

DDL主要是用在定义或改变表(TABLE)的结构,数据类型,表之间的链接和约束等初始化工作上,他们大多在建立表时使用。(建库,建表)

常用的语句关键字包括:

 CREATEALTERDROP
  1. DML 数据操纵语言(Data Manipulation Language)。

用于添加、删除、更新和查询数据库记录,并检查数据完整性。SQL中处理数据等操作统称为数据操纵语言 。(对表中的数据进行增删改操作)

常用的语句关键字包括:

 SELECTUPDATEINSERTDELETE
  1. DQL 数据查询语言(Data Query Language) 。

用来查询数据(记录),不会对数据进行改变,而是让数据库发送结果集给客户端。(对数据进行查询)

常用的语句关键字包括:

select...from...where
  1. DCL 数据控制语言(Data Control Language)。

用来授予或回收访问数据库的某种特权,并控制数据库操纵事务发生的时间及效果,对数据库实行监视等 。(对用户的权限进行设置)

常用的语句关键字包括:

COMMITSAVEPOINTROLLBACKSET TRANSACTION

DDL数据定义语言

数据库的创建使用

直接创建数据库 study:

create database study;

查看当前在哪个库里边:

select database();

进入库的操作:

use study;

判断是否存在,如果不存在则创建数据库 study:

create database if exists study;

创建数据库并指定字符集为 gbk:

create database study dafault character set gbk;

查看某个库是什么字符集:

show create database User;

mysql常见数据类型

1. 数据类型是什么?

数据类型是指列、存储过程参数、表达式和局部变量的数据特征,它决定了数据的存储格式,代表了不同的信息类型。有一些数据是要存储为数字的,数字当中有些是要存储为整数、小数、日期型等…

2. mysql常见数据类型 详情请看

  1. 整型
MySQL数据类型 含义
tinyint(m) 1个字节 范围(-128~127)
smallint(m) 2个字节 范围(-32768~32767)
mediumint(m) 3个字节 范围(-8388608~8388607)
int(m) 4个字节 范围(-2147483648~2147483647)
bigint(m) 8个字节 范围(±9.22*10的18次方)
  1. 浮点型(float和double)
MySQL数据类型 含义
float(m,d) 单精度浮点型 8位精度(4字节) m总个数,d小数位
double(m,d) 双精度浮点型 16位精度(8字节) m总个数,d小数位
  1. 字符串(char,varchar,_text)
MySQL数据类型 含义
char(n) 固定长度,最多255个字符
varchar(n) 固定长度,最多65535个字符
tinytext 可变长度,最多255个字符
text 可变长度,最多65535个字符
mediumtext 可变长度,最多2的24次方-1个字符
longtext 可变长度,最多2的32次方-1个字符
  1. 日期时间类型
MySQL数据类型 含义(格式)
date 日期 ‘2008-12-2’(yyyy-MM-dd)
time 时间 ‘12:25:36’(HH:mm:ss)
year 日期 ‘2008’(yyyy)
datetime 日期时间 ‘2008-12-2 22:06:44’(yyyy-MM-dd HH:mm:ss)
timestamp 自动存储记录修改时间,可作时间戳(yyyy-MM-dd HH:mm:ss)

创建表

语法:

cretae table student(
	字段名1 字段类型1 约束条件1 说明1,
	字段名2 字段类型2 约束条件2 说明2,
	字段名3 字段类型3 约束条件3 说明3
);

如:
cretae table student(
	id tinyint(5) unique key auto_increment comment '学生学号',
	name varchar(20) not null comment '学生姓名',
	age tinyint default null comment '学生年龄' 
);

//注意:建议这种创建表的方式用于日常测试,因为可能索引什么的会复制不过来
//oracle通用   不加条件会复制数据
create table study1 as select * from study where 1=2;

//会一模一样的复制
create table study1 like study;

约束条件:

MySQL关键字 含义
NULL 数据列可包含NULL值
NOT NULL 数据列不允许包含NULL值
DEFAULT 默认值
PRIMARY KEY 主键
UNIQUT KEY 唯一值
AUTO_INCREMENT 自动递增,适用于整数类型
UNSIGNED 无符号
ZEROFILL 自动填充
CHARACTER SET name 指定一个字符集

查看表的基本结构信息

  1. 查看数据库中的所有表:
show tables;
  1. 查看表结构:
desc study;
  1. 查看创建表的sql语句:
show create table study;

结构的修改

  1. 修改表名:
//rename table 旧表名 to 新表名;
rename table study to student;
  1. 添加列:
//给表添加一列:alter table 表名 add 列名 类型;
alter table study add addr varchar(50);

//alter table 表名 add 列名 类型 comment '说明';
alter table study add family varchar(50) comment '学生家长';

//给表最前面添加一列:alter table 表名 add 列名 类型 first;
alter table study add job varchar(20) first;

//给表某个字段后添加一列:alter table 表名 add 列名 类型 after 字段名;
alter table study add phone int(11) after id;

//注意:没有给表某个字段前添加一列的说法。
  1. 修改列类型:
//alter table 表名 modify 列名 新类型;
alter table study modify phone varchar(50);
  1. 修改列名(类型也可修改):
//alter table 表名 change 旧列名 新列名 类型;
alter table study change phone telphone varchar(50);
  1. 删除列:
//alter table 表名 drop 列名;
alter table study drop addr;
  1. 修改字符集:
//alter table 表名 character set 字符集;
alter table study character set GBK;
  1. mysql表的删除:
//drop table 表名;
drop table study;
//判断是否存在,若存在则删除表:drop table if exists 表名;
drop table if exists study;

DML数据操纵语言

数据的新增

  1. 插入表数据(增)
// insert into 表名 (字段名,字段名) values('','');
insert into emp (name,classroom) values('李小龙','行政楼202');

// insert into 表名 values(所有字段相互对应值);
insert into emp values('成龙','行政楼204','PM 14:00');
  1. 蠕虫复制(将一张表的数据复制到另一张表中)
// insert into 表1 select * from 表2;
insert into study2 select * from study1;

// insert into 表名1(字段名1,字段名2) select 字段名1,字段名2 from 表名2;
insert into emp (name,classroom) select name,classroom from employee;
  1. 建表复制
// create table 表名 select * from 旧表名;
create table study2 select * from study1;

// create table 表名 like 旧表名;
create table study2 like study1;
  1. 一次性插入多个数据
// insert into 表名  (字段名) values (对应值1),(对应值2),(对应值3);
insert into 
	study (name,classroom,...) 
values 
	('李小龙','行政楼202',...),('成龙','行政楼204',...),('释小龙','行政楼206',...);

数据的删改

  1. 修改(更新)
// update 表名 set 字段=值 where 条件; 
update study set teacher = '李小龙' where id = 1;

// update 表名 set 字段1=值1,字段2=值2 where 条件; 
update study set teacher = '成龙',classroom = '行政楼204'  where id = 2;
  1. 删除
//delete与truncate与drop 这三种删除数据的共同点都是删除数据,他们的不同点是什么?

// delete 会把删除的操作记录下来,以便数据回退,不会释放空间。
delete from 表名 where 条件;

// delete 多表删除
delete p1 FROM Person p1,Person p2 WHERE p1.Email = p2.Email AND p1.Id > p2.Id;

// truncate 会把表占用的空间恢复成初始状态,不会记录删除的操作。
truncate table 表名;

// drop 会删除整张表,会释放表占用的空间。
drop table 表名;

//删除速度
drop > truncate > delete

中文乱码问题

  1. 查看当前mysql使用的字符集
mysql> show variables like 'character%';

+--------------------------+----------------------------------+
| Variable_name            | Value                            |
+--------------------------+----------------------------------+
| character_set_client     | utf8                             |
| character_set_connection | utf8                             |
| character_set_database   | utf8                             |
| character_set_filesystem | binary                           |
| character_set_results    | utf8                             |
| character_set_server     | utf8                             |
| character_set_system     | utf8                             |
| character_sets_dir       | /usr/local/mysql/share/charsets/ |
+--------------------------+----------------------------------+

character_set_client:客户端请求数据的字符集
character_set_connection:客户端与服务器连接的字符集
character_set_database:数据库服务器中某个库使用的字符集设定,如果建库时没有指明,将默认使用配置上的字符集
character_set_results:返回给客户端的字符集(从数据库读取到的数据是什么编码的)
character_set_server:为服务器安装时指定的默认字符集设定。
character_set_system:系统字符集(修改不了的,就是utf8)
character_sets_dir:mysql字符集文件的保存路径
临时:set names gbk;

  1. 修改库的字符集编码
alter database xiaoxiao default character set gbk;
  1. 修改表的字符集编码
alter table employee default character set utf8;

DQL数据查询语言

所需表和数据

/*创建部门表*/
CREATE TABLE dept(
    deptnu      INT  PRIMARY KEY comment '部门编号',
    dname       VARCHAR(50) comment '部门名称',
    addr        VARCHAR(50) comment '部门地址'
);/* 某个公司的员工表 */
CREATE TABLE employee(
    empno       INT  PRIMARY KEY comment '雇员编号',
    ename       VARCHAR(50) comment '雇员姓名',
    job         VARCHAR(50) comment '雇员职位',
    mgr         INT comment '雇员上级编号',
    hiredate    DATE comment '雇佣日期',
    sal         DECIMAL(7,2) comment '薪资',
    deptnu      INT comment '部门编号'
)ENGINE=MyISAM DEFAULT CHARSET=utf8;/*创建工资等级表*/
CREATE TABLE salgrade(
    grade       INT  PRIMARY KEY comment '等级',
    lowsal      INT comment '最低薪资',
    higsal      INT comment '最高薪资'
);/*插入dept表数据*/
INSERT INTO dept VALUES (10, '研发部', '北京');
INSERT INTO dept VALUES (20, '工程部', '上海');
INSERT INTO dept VALUES (30, '销售部', '广州');
INSERT INTO dept VALUES (40, '财务部', '深圳');/*插入emp表数据*/
INSERT INTO employee VALUES (1009, '唐僧', '董事长', NULL, '2010-11-17', 50000,  10);
INSERT INTO employee VALUES (1004, '猪八戒', '经理', 1009, '2001-04-02', 29750, 20);
INSERT INTO employee VALUES (1006, '猴子', '经理', 1009, '2011-05-01', 28500, 30);
INSERT INTO employee VALUES (1007, '张飞', '经理', 1009, '2011-09-01', 24500,10);
INSERT INTO employee VALUES (1008, '诸葛亮', '分析师', 1004, '2017-04-19', 30000, 20);
INSERT INTO employee VALUES (1013, '林俊杰', '分析师', 1004, '2011-12-03', 30000, 20);
INSERT INTO employee VALUES (1002, '牛魔王', '销售员', 1006, '2018-02-20', 16000, 30);
INSERT INTO employee VALUES (1003, '程咬金', '销售员', 1006, '2017-02-22', 12500, 30);
INSERT INTO employee VALUES (1005, '后裔', '销售员', 1006, '2011-09-28', 12500, 30);
INSERT INTO employee VALUES (1010, '韩信', '销售员', 1006, '2018-09-08', 15000,30);
INSERT INTO employee VALUES (1012, '安琪拉', '文员', 1006, '2011-12-03', 9500,  30);
INSERT INTO employee VALUES (1014, '甄姬', '文员', 1007, '2019-01-23', 7500, 10);
INSERT INTO employee VALUES (1011, '妲己', '文员', 1008, '2018-05-23', 11000, 20);
INSERT INTO employee VALUES (1001, '小乔', '文员', 1013, '2018-12-17', 8000, 20);/*插入salgrade表数据*/
INSERT INTO salgrade VALUES (1, 7000, 12000);
INSERT INTO salgrade VALUES (2, 12010, 14000);
INSERT INTO salgrade VALUES (3, 14010, 20000);
INSERT INTO salgrade VALUES (4, 20010, 30000);
INSERT INTO salgrade VALUES (5, 30010, 99990);

查询子句之where条件查询

  1. 简单查询
// select *(代表全部) from 表名;
select * from employee;

// select 字段1,字段2,字段3 as 别名 from 表名;
select empno,ename,job as ename_job from employee;
  1. 精确条件查询
// select * from 表名 where 条件;
select * from employee where ename='后裔';
select * from employee where sal != 50000;
select * from employee where sal <> 50000;
select * from employee where sal > 10000;
  1. 模糊条件查询
show variables like 'character%';
select * from employee  where ename like '林%';
  1. 范围查询
// select * from 表名 where 字段 between 范围值 and 范围值;
select * from employee where sal between 10000 and 30000;
select * from employee where hiredate between '2011-01-01' and '2017-12-1';
  1. 离散查询
// select * from 表名 where 字段 in (); 
select * from employee where ename in ('猴子','林俊杰','小红','小胡'); 

select * from employee 
where deptnu='30' and ename 
in (select ename from employee where job='销售员');
  1. 清除重复值
// select distinct(所要去重复的字段) from 表名;
select distinct(job) from employee;
  1. 统计查询(聚合函数)
// count(*) 计算总数
select count(*) from employee;
select count(ename) from employee;

// sum()  计算总和 
select sum(sal) from employee;

// max()    计算最大值
select max(sal) from employee;

// avg()   计算平均值
select avg(sal) from employee;

// min()   计算最低值
select min(sal) from employee;

// concat() 起到连接作用
select concat(ename,' 是 ',job) as aaaa from employee;

查询子句之group by分组查询(分组)

作用:针对某些字段进行分组,然后在组内对多行数据进行处理(计算行数,计算max,min等等)。
适用场合:常用于统计场合,一般和聚合函数连用。

//注意:group by 关键字后的字段必须和所展示的字段一致。
select deptnu,count(*) from employee group by deptnu;
select deptnu,job,count(*) from employee group by deptnu,job;
select job,count(*) from employee group by job;

查询子句之having条件查询(筛选)

作用:对查询的结果进行筛选操作。
适用场合:一般跟在group by之后。

select job,count(*) from employee group by job having job ='文员';
select  deptnu,job,count(*) from employee group by deptnu,job having count(*)>=2;
select  deptnu,job,count(*) as 总数 from employee group by deptnu,job having 总数>=2;

查询子句之order by排序查询(排序)

作用:对查询的结果进行排序操作。
适用场合:一般用在查询结果的排序。

select * from employee order by sal;

select * from employee order by hiredate;

select  deptnu,job,count(*) as 总数 from employee group by deptnu,job having 总数>=2 order by deptnu desc;

select  deptnu,job,count(*) as 总数 from employee group by deptnu,job having 总数>=2 order by deptnu asc;

select  deptnu,job,count(*) as 总数 from employee group by deptnu,job having 总数>=2 order by deptnu;

//顺序:where ---- group by ----- having ------ order by 

查询子句之limit限制查询(限制)

作用:对查询结果起到限制条数的作用。
适用场合:数据量过多时,可以起到限制作用。

// 从第五个开始展示五条数据
select * from employee limit 4,5;

查询子句之exists型子查询

exists型子查询后面是一个受限的select查询语句。
exists子查询,如果exists后的内层查询能查出数据,则返回 TRUE 表示存在;为空则返回 FLASE则不存在。

// 分为俩种:exists跟 not exists
select * from 表名 a where exists (select * from 表名2 b where 条件);
select * from 表名 a where not exists (select * from 表名2 b where 条件);

// 查询出公司有员工的部门的详细信息:
select * from dept a where exists (select * from employee b where a.deptnu=b.deptnu);

// 查询出公司没有员工的部门的详细信息:
select * from dept a where not exists (select * from employee b where a.deptnu=b.deptnu);

查询子句之左连接查询与右连接查询

左连接关键字:left join 表名 on 条件
说明: left join 是left outer join的简写,左(外)连接,左表的记录将会全部表示出来, 而右表只会显示符合搜索条件的记录。右表记录不足的地方均为NULL。

右连接关键字:right join 表名 on 条件
右连接说明:right join是right outer join的简写,与左(外)连接相反,右(外)连接,左表只会显示符合搜索条件的记录,而右表的记录将会全部表示出来。左表记录不足的地方均为NULL。

// 列出部门名称和这些部门的员工信息,同时列出那些没有的员工的部门
select a.dname,b.* from dept a  left join employee b on a.deptnu=b.deptnu;
select b.dname,a.* from employee a  right join  dept b on b.deptnu=a.deptnu;

查询之内连接查询与联合查询

内连接:获取两个表中字段匹配关系的记录
主要语法:INNER JOIN 表名 ON 条件;

//想查出员工张飞的所在部门的地址
select a.addr  from dept a inner join employee b on a.deptnu=b.deptnu and b.ename='张飞';

// 推荐 性能更优也最普遍
select a.addr from dept a,employee b where a.deptnu=b.deptnu and b.ename='张飞';

联合查询:就是把多个查询语句的查询结果结合在一起

/*	union查询的注意事项:
1、两个select语句的查询结果的“字段数”必须一致;
2、通常,也应该让两个查询语句的字段类型具有一致性;
3、也可以联合更多的查询结果;
4、用到order by排序时,需要加上limit(加上最大条数就行),需要对子句用括号括起来
*/

// 对销售员的工资从低到高排序,而文员的工资从高到低排序
(select * from employee a where a.job = '销售员'  order by a.sal limit 999999 ) 
union  
(select * from employee b where b.job = '文员' order by b.sal desc limit 999999);

查询之项目高级查询实战

  1. 查出至少有一个员工的部门。显示部门编号、部门名称、部门位置、部门人数.
select a.deptnu,a.dname,a.addr, b.zongshu 
from dept a,(select deptnu,count(*) as zongshu from employee group by deptnu) b 
where a.deptnu=b.deptnu;
  1. 列出薪金比安琪拉高的所有员工。
select * from  employee 
where sal > (select sal from employee where ename='安琪拉');
  1. 列出所有员工的姓名及其直接上级的姓名。
select a.ename,ifnull(b.ename,'BOSS') as leader 
from employee a left join employee b on a.mgr=b.empno;
  1. 列出受雇日期早于直接上级的所有员工的编号、姓名、部门名称。
select a.empno,a.ename,c.dname 
from employee a 
left join employee b on a.mgr=b.empno 
left join dept c on a.deptnu=c.deptnu 
where a.hiredate < b.hiredate;
  1. 列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门。
select a.dname,b.* from dept a left join employee b on a.deptnu=b.deptnu;
  1. 列出所有文员的姓名及其部门名称,所在部门的总人数。
select b.ename,a.dname,b.job,c.zongshu from dept a ,employee b ,
(select deptnu,count(*) as zongshu from employee group by deptnu) c 
where a.deptnu=b.deptnu and b.job='文员' and b.deptnu=c.deptnu;
  1. 列出最低薪金大于15000的各种工作及从事此工作的员工人数。
select job,count(*) from employee group by job having   min(sal) > 15000;
  1. 列出在销售部工作的员工的姓名,假定不知道销售部的部门编号。
select  ename  from employee 
where deptnu = (select deptnu from dept where dname='销售部');
  1. 列出与诸葛亮从事相同工作的所有员工及部门名称。
select a.ename,b.dname from employee a 
left join dept b on a.deptnu=b.deptnu 
where a.job=(select job from employee where ename='诸葛亮');
  1. 列出薪金比 在部门30工作的员工的薪金 还高的员工姓名和薪金、部门名称。
select a.ename,a.sal,b.dname from employee a ,dept b 
where a.deptnu = b.deptnu 
and sal > (select max(sal) from employee where deptnu=30);
  1. 列出每个部门的员工数量、平均工资。
select deptnu , count(*) ,avg (sal) from employee  group by deptnu;
  1. 列出薪金高于公司平均薪金的所有员工信息,所在部门名称,上级领导,工资等级。
select a.*,c.dname,b.ename,d.grade 
from employee a,employee b,dept c ,salgrade d 
where a.mgr = b.empno 
and a.deptnu = c.deptnu 
and a.sal > (select avg(sal) from employee) 
and a.sal  between d.lowsal and d.higsal;

DCL数据控制语言

数据控制语言(DCL:Data Control Language)是用来设置或者更改数据库用户或角色权限的语句,这些语句包括GRANT、DENY、REVOKE等语句

事务、视图、触发器、存过

事务解析

数据库事务通常指对数据库进行读或写的一个操作过程。有两个目的,第一个是为数据库操作提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法;第二个是当多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰。

事务的特性(ACID):表的引擎要为innodb引擎

  1. 原子性(Atomicity):

表示将事务中所进行的操作捆绑成一个不可分割的单元,即对事务所进行的数据修改等操作,要么全部执行,要么全都不执行。

  1. 一致性(Consistency):

表示事务完成时,必须使所有的数据都保持一致状态。

  1. 隔离性(Isolation):

指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

  1. 持久性(Durability):

持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。提交后的其他操作或故障不会对其有任何影响。

事务实战

// 事务的开启
begin;   /* 或者 */   start transaction;

// 事务的提交  注:提交后,事务结束
commit;

// 事务的回滚  注:回滚后,事务结束
rollback;
  1. 查看自动提交
show global variables like 'autocommit';

+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
  1. 关闭自动提交
// 临时生效
set autocommit = 0; 
  1. 开启自动提交(默认)
// 临时生效
set autocommit = 1;

注:在事务开启后可执行任何其他操作,遇到commit;才会写入至硬盘,遇到rollback会回滚到事务开启的那个时候

视图

视图(view)是一种虚拟存在的表,是一个逻辑表,它本身是不包含数据的。作为一个select语句保存在数据字典中的。
通过视图,可以展现基表(用来创建视图的表叫做基表)的部分数据,说白了视图的数据就是来自于基表

  1. 视图的优点是
  1. 简单性:视图不仅可以简化用户对数据的理解,也可以简化他们的操作。那些被经常使用的查询可以被定义为视图,从而使用户不必为以后的操作每次都指定全部的条件。
  2. 安全性:通过视图用户只能查询和修改他们所能见到的数据。数据库中的其他数据则既看不见也取不到。
  3. 逻辑数据独立性:一旦视图的结构确定了,可以屏蔽表结构变化对用户的影响,源表增加列对视图没有影响;源表修改列名,则可以通过修改视图来解决,不会造成对访问者的影响。
  4. 不占用空间:视图是逻辑上的表,不占用内存空间。
    (使用视图的大部分情况是为了保障数据安全性,提高查询效率。)
  1. 视图的缺点
  1. 性能差:sql server必须把视图查询转化成对基本表的查询,如果这个视图是由一个复杂的多表查询所定义,那么,即使是视图的一个简单查询,sql server也要把它变成一个复杂的结合体,需要花费一定的时间。
  2. 修改限制:当用户试图修改试图的某些信息时,数据库必须把它转化为对基本表的某些信息的修改,对于简单的试图来说,这是很方便的,但是,对于比较复杂的试图,可能是不可修改的。
  1. 视图的创建、修改以及删除
// create view <视图名称> as select 语句;
create view view_study as select * from study;

// create view <视图名称> (字段) as select 语句;
create view view_study (s_id,s_name,s_age) as select id,name,age from study;

// create or replace view <视图名称> as select 语句; 
// 使用CREATE OR REPLACE VIEW语句可以修改视图
// 视图存在时,可以对视图进行修改; 视图不存在时,可以创建视图。
create or replace view  view_study as select * from study;

// 也可使用 alter view <视图名称> as select 语句;
// 不过前提是这个视图存在
alter view view_study as select * from study;

// drop view <视图名称> ;
drop view view_study;

触发器

触发器就是监视某种情况,并触发某种操作

// 创建触发器的语法 

create trigger 触发器名称  after/before   insert/update/delete on 表名  
for each row
begin
  sql语句;
end

// after/before:可以设置为事件发生前或后
// insert/update/delete:它们可以在执行insert、update或delete的过程中触发
// for each row:每隔一行执行一次动作 

// 自定义语句的结束符号
delimiter // 
create trigger trig_work after insert on work_time_delay
for each row
begin
    update employee set sal=sal-100 where empno=new.empno;
end//

// new:指的是事件发生before或者after保存的新数据

存过

存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。

  1. 存储过程的优缺点

优点是:
1)复杂操作,调用简单
2)速度快

缺点是:
1)封装复杂
2) 没有灵活性

  1. 创建存储过程语法
create procedure 名称 (参数....)
begin
   过程体;
   过程体;
end;

//参数:in|out|inout 参数名称 类型(长度)
in:表示调用者向过程传入值(传入值可以是字面量或变量)。
out:表示过程向调用者传出值(可以返回多个值)(传出值只能是变量)。
inout:既表示调用者向过程传入值,又表示过程向调用者传出值(值只能是变量)。
  1. 查看创建的存储过程命令
show create procedure <存过名称>;
  1. 存储过程的使用
//创建存过
create procedure  name(in n int)
begin
   select * from employee limit n;
 end;
 
 //给参数赋值
 set @n=5;
//调用存过
call name(@n);
//创建存过
create procedure  name()
begin
	//对参数进行赋值
 	declare  n int default 6;
 	select * from employee limit n;
end;

//调用存过
call name();

数据库引擎与索引

数据库引擎

数据库引擎是数据库底层软件组件,不同的存储引擎提供不同的存储机制,索引技巧,锁定水平等功能,使用不同的数据库引擎,可以获得特定的功能

// 如何查看数据库支持的引擎
show engines;// 查看当前数据的引擎:
show create table 表名;// 查看当前库所有表的引擎:
show table status;
// 建表时指定引擎
create table yingqin (id int,name varchar(20)) engine='InnoDB';

// 修改表的引擎
alter table 表名 engine='MyiSAm';

MyISAM与InnoDB的区别

  1. MyISAM:默认表类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法。不是事务安全的,而且不支持外键,如果执行大量的select,insert MyISAM比较适合。
  2. InnoDB:支持事务安全的引擎,支持外键、行锁、事务是他的最大特点。如果有大量的update和insert,建议使用InnoDB,特别是针对多个并发和QPS较高的情况。
    (行级锁并非绝对,当执行sql语句时不能确定范围时,也会进行锁全表例如: update table set id=3 where name like ‘a%’

使用场景

MyISAM:
• 一般来说MyISAM不需要用到事务的时候
• 做很多count计算

InnoDB:
• 可靠性要求高的,或者要求支持事务
• 想要用到外键约束的时候

推荐:
• 推荐用InnoDB

常用索引

索引是一个单独的,存储在磁盘中上的数据库结构,它们包含着对数据表里的所有记录的引用指针。使用索引可以快速的找出在某列或多列中有特定值的行。

索引的优点:

  1. 通过创建唯一索引,来保证数据库表中的每一行数据的唯一性。
  2. 可以加快数据的检索速度。
  3. 可以保证表数据的完整性与准确性

索引的缺点:

  1. 索引需要占用物理空间。
  2. 对表中的数据进行改动时,索引也需要跟着动态维护,降低了数据的维护速度。

索引的常见类型:

index:普通索引

unique:唯一索引

primary key:主键索引

foreign key:外键索引

fulltext: 全文索引

组合索引

普通索引与唯一索引

什么是普通索引:

普通索引(index)顾名思义就是各类索引中最为普通的索引,主要任务就是提高查询速度。其特点是允许出现相同的索引内容,允许空(null)值

什么是唯一索引:

唯一索引:(unique)顾名思义就是不可以出现相同的索引内容,但是可以为空(null)值

// 创建表的时候创建
create table test (
	id int(7) zerofill auto_increment not null,
    username varchar(20),
    servnumber varchar(30),
    password varchar(20),
    createtime datetime,
    unique (id)
)DEFAULT CHARSET=utf8;

// 直接为表添加索引
// alter table 表名 add 索引类型 索引名称 (字段名称); 
// 假如没有指定索引名称时,会以默认的字段名为索引名称
alter table test add index (usernmae); //普通索引
alter table test add unique unique_username (username);//唯一索引

// 直接创建索引
// create 索引类型 索引名 on 表名 (字段名);
create index index_createtime on test (createtime);

// 查看索引
// show 索引类型 from 表名\G
show unique from test;

// 删除索引
// drop 索引类型 索引名称 on 表名;
drop unique id on test;

// alter table 表名 drop index 索引名;
alter table test drop unique id;

主键索引

把主键添加索引就是主键索引,它是一种特殊的唯一索引,不允许有空值,而唯一索引(unique是允许为空值的)。指定为“PRIMARY KEY”

主键:主键是表的某一列,这一列的值是用来标志表中的每一行数据的。
注意:每一张表只能拥有一个主键

// 创建表的时候创建
create table test(
	id int primary key auto_increment comment '主键id',
	name varchar(50) not null comment '姓名'
);

// 直接为表添加主键索引
// alter table 表名 add primary key (字段名);
alter table test add primary key (id);

// 删除主键
// alter table 表名 drop primary key;
alter table test drop primary key;
// 在有自增的情况下,必须先删除自增,才可以删除主键

全文索引

全文索引是将存储在数据库中的文章或者句子等任意内容信息查找出来的索引,单位是词。全文索引也是目前搜索引擎使用的一种关键技术。指定为 fulltex。

// 创建表的时候创建全文索引
create table test(
	id int primary key auto_increment comment '主键ID',
	name varchar(50) comment '姓名',
	content varchar(250) comment '内容',
	fulltext(content)
);

// 只用于测试 其余自行补全
insert into test (content) values('remove sections from each line of files');
insert into test (content) values('复制文件或者文件夹');
insert into test (content) values('修改文件名,移动');
insert into test values('is,not,me,yes,no ...');  //停止词

// 通过alter添加
// alter table command  add fulltext(instruction);
alter table test add fulltext(content);

使用全文索引

// select * from 表名 where match  (字段名) against ('检索内容');
select * from test where match(content) against ('sections');

// 停止词:出现频率很高的词,将会使全文索引失效

// in boolean mode 模式:意思是指定全文检索模式为布尔全文检索(简单可以理解为是检索方式)
// select * from 表名 where match (字段名) against ('检索内容' in boolean mode);
select * from test where match(content) against ('sections' in boolean mode);

// 使用通配符*时,只能放在词的后边,不能放前边。
// 会检索不到
select * from test where match(content) against ('*ections' in boolean mode); 
// 应
select * from test where match(content) against ('section*' in boolean mode);

// 删除全文搜索
// alter table 表名 drop index 索引名;
alter table test drop index content;

总结:

  1. 一般情况下创建全文索引的字段数据类型为 char、varchar、text 。其它字段类型不可以
  2. 全文索引不针对非常频繁的词做索引。比如is,no,not,you,me,yes这些,我们称之为停止词
  3. 对英文检索时忽略大小写

外键约束

外键就是作用于两个表数据之间的链接的一列或多列,用来保证表与表之间的数据的完整性和准确性。

添加外键约束:

// 注意:主键跟外键的字段类型一定要相
// foreign key (字段名) references 关联的表名(关联表的字段名)

//建表时
create table test(
	id int primary key auto_increment comment '主键ID',
	name varchar(25) not null comment '姓名',
	deptno int(5) not null comment '部门编号',
	foregin key(deptno) references dept (deptno) 
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

// 通过alter添加
//  alter table 表名A add foreign key (字段名A) references 表名B(字段B);
alter table test add foreign key(deptno) references dept (deptno);

//删除
// 在干掉外键索引之前必须先把外键约束删除,才能删除索引
alter table test drop foreign key deptno;
alter table test drop index deptno;

总结:

  1. 俩个表,主键跟外键的字段类型一定要相同
  2. 要使用外键约束表的引擎一定得是InnoDB引擎,MyISAM是不起作用的
  3. 在干掉外键索引之前必须先把外键约束删除,才能删除索引

联合索引

联合索引又称组合索引或者复合索引,是建立在俩列或者多列以上的索引。

// 创建联合索引
// alter table 表名 add index(字段1,字段2,字段3);
alter table test add index(name,age,content);

// 删除联合索引
// alter table 表名 drop index 字段;
// 联合索引的最左原则 (即检索的字段中必须有name)
// 不写索引名就默认使用第一个字段名为索引名
alter table test drop index name;

/* 联合索引的效率远远高于单列索引 */

总结

  1. 索引并非越多越好,过多的索引会增加数据的维护速度还有磁盘空间的浪费。
  2. 当表的数据量很大的时候,可以考虑建立索引。
  3. 表中经常查数据的字段,可以考虑建立索引。
  4. 想要保证表中数据的唯一性,可以考虑建立唯一索引。
  5. 想要保证俩张表中的数据的完整性跟准确性,可以考虑建立外键约束。
  6. 经常对多列数据进行查询时,可以考虑建立联合索引。

sql语句优化思路

mysql的慢查询日志开启与问题定位

查看是否已经开启了慢查询日志

show variables like 'slow%';
+---------------------+--------------------------------------+
| Variable_name       | Value                                |
+---------------------+--------------------------------------+
| slow_launch_time    | 2                                    |
| slow_query_log      | OFF                                  |
| slow_query_log_file | /var/lib/mysql/90687d8dcec6-slow.log |
+---------------------+--------------------------------------+

开启慢查询日志

set global slow_query_log = on ;

日志路径也可以自定义

set global slow_query_log_file = '路径';

查看慢查询的时间临界值

show variables like '%long%';

+----------------------------------------------------------+-----------+
| Variable_name                                            | Value     |
+----------------------------------------------------------+-----------+
| long_query_time                                          | 10.000000 |
| performance_schema_events_stages_history_long_size       | 10000     |
| performance_schema_events_statements_history_long_size   | 10000     |
| performance_schema_events_transactions_history_long_size | 10000     |
| performance_schema_events_waits_history_long_size        | 10000     |
+----------------------------------------------------------+-----------+

设置慢查询的时间标准

set long_query_time=0.4;

+----------------------------------------------------------+----------+
| Variable_name                                            | Value    |
+----------------------------------------------------------+----------+
| long_query_time                                          | 0.400000 |
| performance_schema_events_stages_history_long_size       | 10000    |
| performance_schema_events_statements_history_long_size   | 10000    |
| performance_schema_events_transactions_history_long_size | 10000    |
| performance_schema_events_waits_history_long_size        | 10000    |
+----------------------------------------------------------+----------+

注意:重启mysql服务会让在交互界面设置的慢查询恢复到默认

/* 永久生效的设置方法:修改配置文件 vi /etc/my.cnf */

[mysqld]
slow_query_log = 1
long_query_time = 0.1
slow_query_log_file =/usr/local/mysql/mysql_slow.log

/* 最后必须重启服务才能生效! */

sql语句执行过程解析

查看性能详情是否开启

show variables like '%profiling%';

+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| have_profiling         | YES   |
| profiling              | OFF   |
| profiling_history_size | 15    |
+------------------------+-------+

开启性能记录功能

set profiling = on ;

+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| have_profiling         | YES   |
| profiling              | ON    |
| profiling_history_size | 15    |
+------------------------+-------+

查看性能的记录

show profiles;

+----------+----------+-----------------------------------+
| Query_ID | Duration | Query                             |
+----------+----------+-----------------------------------+
|        1 | 0.002789 | show variables like '%profiling%' |
+----------+----------+-----------------------------------+

查看语句的执行性能详情

show profile for query 1;

+----------------------+----------+
| Status               | Duration |
+----------------------+----------+
| starting             | 7.5E-5   |
| checking permissions | 1.8E-5   |
| Opening tables       | 1.8E-5   |
| init                 | 5.7E-5   |
| System lock          | 1.1E-5   |
| optimizing           | 5E-6     |
| optimizing           | 5E-6     |
| statistics           | 1.6E-5   |
| preparing            | 1.7E-5   |
| statistics           | 1.3E-5   |
| preparing            | 9E-6     |
| executing            | 9E-6     |
| Sending data         | 1E-5     |
| executing            | 5E-6     |
| Sending data         | 0.002336 |
| end                  | 1.8E-5   |
| query end            | 8E-6     |
| closing tables       | 4E-6     |
| removing tmp table   | 1E-5     |
| closing tables       | 1E-5     |
| freeing items        | 0.000117 |
| cleaning up          | 2.2E-5   |
+----------------------+----------+

性能线程官方文档 ======== >>>>> <<<<<<<< 点我就对了 >>>>>>>>

优化的五点小建议

  1. 建议一

尽量避免使用select *from ,尽量精确到想要的结果字段。

  1. 建议二

尽量避免条件使用or。

  1. 建议三

记得加上limit 限制行数,避免数据量过大消耗性能。

  1. 建议四

使用模糊查询时,%放在前面是会使索引失效。

mysql> explain select * from tau where name like '%aa%';
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | tau   | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    1 |      100 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+

explain select * from tau where name like 'aa%';
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type  | possible_keys | key  | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | tau   | NULL       | range | name          | name | 63      | NULL |    1 |      100 | Using index condition |
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
  1. 建议五

要小心条件字段类型的转换

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