mysql数据库

 

数据库的分类:

分类

概念

常见的关系型非关系型数据库系统

关系型数据库

(SQL)

采用SQL语言管理,采用"数据表格"存储数据。(前期必须将表格式设计合理,后期难以修改)通常用于企业的网站、OA信息系统

mysql-server(SUN公司-->Oracle公司)、SQL Server(微软)、Oracle数据库(商用,银行、金融公司会用)

非关系型数据库

(No SQL)

不采用SQL语言管理,采用"键值对"来存储数据。(不采用表存储数据后期修改很灵活)通常用户大数据分析处

redis、mongodb……

 

数据库的概念

名称

用Excel类比理解


库文件(数据库database/db)

可以理解成一个Excel文件。

一个库(database)文件中可以有0~n张表(table)

mysql的库文件默认保存在/var/lib/mysql目录中,库文件在linux系统中是以"目录的形式存在的",库目录中存放的是此数据库的表。

可以理解成Excel文件中的一张表。一张表中可以有1~n个字段。

表在linux系统中是以文件名的形式保存在库的目录中。

字段

可以理解成Excel表中表头的列标题。一个字段可以包含0~n行记录(record)。

字段和记录是以正文的形式保存在表文件中的。

 

mysql的库文件、表文件默认的保存路径

/var/lib/mysql

库文件类型(以什么类型的文件存储在硬上)

以目录的形式存储在/var/lib/mysql目录中

表文件

以普通文件的形式存储字库的目录中

 

SQL的三种语言

SQL(Structured Query Language 即结构化查询语言)

SQL语言主要用于存取数据、查询数据、更新数据和管理关系数据库系统,SQL语言由IBM开发

名称

作用

例子

DDL语句 数据库定义语言(Data Definition Language)

数据库、表、视图、索引、存储过程

CREATE DROP ALTER 

DML语句 数据库操纵语言(Data Manipulation Language)

插入数据INSERT、删除数据DELETE、更新数据UPDATE、查询数据SELECT

insert  delete  ……

DCL语句 数据库控制语言(Data Control Language)

控制用户的访问权限GRANT(授予权限)、REVOKE(收回权限)


 

MySQL数据类型

在 MySQL 中,有三种主要的类型:文本、数字和日期/时间类型。


MySQL数据库_MySQL的存储过程

MySQL数据库_读写分离_02

 


MySQL数据库_主从复制_03

 

库、表、记录的操作

库、表的增、删、改、查命令?数据记录的增、删、改、查命令?

(database)的操作

增(创建)

删:

选择(打开)数据库:

show databases;

create database 库名 选项;

drop database 库名;

use 数据库名

(table)的操作

查看表:

(创建)

查表结构(表属性)

查看表详细结构:

删除表:

修改表:

复制表:

show   tables;

create   table   表名(字段名1  数据类型,字段2   数据类型, ...)engine=innodb   编码设置;

desc    表名;  或:( describe  表名;)

show  create  table  表名

drop  table   表名;

alter   table

create   table ...

显示修改表的命令帮助:help   alter   table;(插入或删除一列,修改某列的属性[即字段名和数据类型])

在表中最后新增指定的列字段:

在表中第一列或字段名A列之后新增指定的列字段: 

删除表中的某列字段:

alter  table  表名   add   字段名   数据类型;

alter  table  表名   add   字段名   数据类型  [first| after  字段名A]; 

alter   table   表名   drop   字段名;

修改某列的属性[即字段名和数据类型])

修改某列的数据类型:

 

修改某列的字段名和数据类型:

alter  table   表名   modify   字段名   新数据类型  [first| after  字段名A];;

alter  table   表名   change   旧字段名    新字段名    新数据类型   [first| after  字段名A];;

 ALTER TABLE 表名 CHANGE 旧字段名 新字段名 旧数据类型 [完整性约束条件…];

记录(record)的操作(插入一行)

查:

增(插入): 

更新: 

删:

select * from 表名 [where 条件]

insert into 表名[(字段1,字段2,...)] values(值1,值2,...),(值1,值2,...);

update [库名.]表名 set 字段名='新值' [where 条件];

delete  from [库名.]表名 [where 条件];

 

MySQL用户

mysql-server的root用户分别设置本地、远程登录密码root

格式:

刷新权限表

grant all on *.* to root@'localhost' identified by 'root';

grant all on *.* to root@'%' identified by 'root';

grant  all on *.* to 用户名@’主机号/IP’  identified  by ‘密码’

flush   privileges;   

更新mysql数据库中user表中的root用户的密码为01:

update  mysql.user  set  password=password("01") where  user="root"  and host="localhost";

创建一个拥有全部权限的jin用户账号

grant  all   on  *.*  to  jin@'%'   identified  by   'jin'   with  grant  option;

创建允许本地登录的jin账号

grant  all   on  *.*  to  jin@'localhost'   identified  by   'jin'   with  grant  option;

 

授权管理(用户安全管理)

 

常用命令

格式

mysql库中user表的user、host、password字段的数据记录:(查mysql系统中的用户账号)

select  user,host,password   from  mysql.user;

mysql中创建一个跟root账号相同权限的新账号admin:

grant  all  on  *.*  to  admin@'%' identified  by  '密码'  with grant  option;

查看root账号的授权信息

show  grants  for  root@'localhost';

回收admin账号的insert、update、delete权限

revoke  insert,update,delete  on  *.*  from  admin@'主机名或IP';

删除admin账号

drop  user  admin@'主机名或IP';

 

 

表的完整性约束

表完整性约束.....

作用:用于保证数据的完整性和一致性

约束条件

说明

主键:

(可以唯一的标识记录,不可以为空)

外键:

实现子表与父表之间的关联

唯一键:

 

索引

 

primary key (PK)

UNIQUE + NOT NULL

foreign  key (FK)

NOT NULL

unique key (UK)

(标识此字段的值是唯一的,可以为空)

index   unique...

engine=innodb;

AUTO_INCREMENT 

DEFAULT 

UNSIGNED

ZEROFILL

标识此字段的值自动增长(整数类型,而且为主键),通常用在“序号”字段

为此字段设置默认值,用户不填写此信息是默认填写此值

无符号,正数

使用0填充,如填写0000001这种记录是可以使用此约束

说明:

1、是否允许为空,默认NULL,可设置NOT NULL,字段不允许为空,必须赋值

2、字段是否有默认值,缺省的默认值是NULL,如果插入记录时不给字段赋值,此字段使用默认值。(default: 指定默认值)

3、唯一约束:控制此列的值不允许重复,必须是唯一的一个值。

4、主键约束primary key字段的值是不允许重复,且不允许为空NULL(UNIQUE + NOT NULL)

单列做主键   

多列做主键(复合主键)应用场合需要用两列的值来标识数据的唯一性。

5外键的作用就是实现在子表中引用父表中某列的值,这样子表中外键的值是依赖于父表的。

注:

1父表中的主键才能作为子表中的外键。

2当父表中的记录修改时,子表也会同步修改

3当父表中删除记录,子表也会同步删除

 

 

如何在select查询时对表中的某列数据进行排序(升序、降序)?

用order by 字段名 [asc升序|desc降序]

按指定的条件查询表中的数据记录。

where中用like做值的模糊匹配,_匹配任意单个字符,%匹配任意一串字符

 

update命令语法:

update   库名.表名   set   字段名=新值(可用mysql函数)   where   匹配条件

 

忘记了MySQL密码

 

mysql的root密码忘了,如何处理?做如下操作:

1、首先,修改/etc/my.cnf主配置文件

vim /etc/my.cnf

[mysqld]

skip-grant-table      跳过权限表验证(添加此行)

 

2、重启mariadb服务:systemctl restart mariadb

 

3、在mysql-server服务器本地免密码登录,做更新root密码的操作。

mysql

update  mysql.user   set  password=password("01")   where   user='root'  and  host='localhost';

flush  privileges;

exit

 

4、修改/etc/my.cnf主配置文件。

vim /etc/my.cnf

[mysqld]

#skip-grant-table 注释或删除此行

 

5、重启mariadb服务:systemctl restart mariadb

 

6、在mysql-server服务器本地使用root账号和新密码登录。

mysql -uroot -p01 登录成功,就说明密码重设成功

 

 

数据库的备份

mysql库和表的逻辑备份工具mysqldump

逻辑备份就是将数据中的表备份成create table、insert into等表和数据记录的SQL语句。
物理备份就是就是将数据库、表的源文件(/var/lib/mysql/库名目录)复制或tar打包压缩一份到别的目录中。

 

逻辑备份

单库全表备份

mysqldump   -uroot   -p'密码'   库名   >   备份文件名.sql

例:

mysqldump   -uroot   -p01   test   >   test-all.sql

more   test-all.sql

注:备份文件中主要是create table、insert into等SQL语句

单库全表恢复

1、创建一个空库:mysql -uroot -p01  -e  'create database 库名;show databases;'

2、恢复所有表到库中:mysql   -uroot   -p01    库名   <  备份文件名.sql

例:

mysql  -uroot  -p01  -e  'create  database  test_all;show  databases;'

mysql   -uroot   -p01    test_all   <  test_all.sql

mysql   -uroot   -p01  -e  'use  test_all;show  tables;'

单库单表备份

mysqldump   -uroot  -p'密码'    库名  表名  >  备份文件名.sql

例:mysqldump   -uroot  -p01   test  tby   >  tby.sql

more   tby.sql

注:备份文件中主要是create  table、insert  into等SQL语句

单库单表恢复

1、创建一个空库:mysql  -uroot  -p01   -e   'create  database  库名;show  databases;'

2、恢复tby表到ku_tby库中:mysql   -uroot   -p01    库名   <  备份文件名.sql

例:

mysql   -uroot   -p01   -e   'create database ku_tby;show databases;'

mysql   -uroot   -p01    ku_tby   <  tby.sql

mysql   -uroot   -p01  -e  'use  ku_tby;show  tables;select  *  from  tby;'

 

物理备份的模式:

冷备份:首先,停止数据库的服务,然后用cp、tar命令对数据库文件进行备份。

热备份:直接在数据库服务运行的状态下做备份,需要用mysql的第三方备份和恢复工具进行操作。

 

练习:将192.168.11.11主机上的mysql的所有库做冷备份,备份到/opt/mysql-2019-03-07目录中。

grep  'datadir'   /etc/my.cnf      查看mysql主配置文件中的数据库文件存储路径

mkdir   -pv   /opt/data/mysql-$(date +%F)

systemctl   stop   mariadb && systemctl  status  mariadb

cp  -arv   /var/lib/mysql/*     /opt/data/mysql-$(date +%F)   

#删除mysql的所有库和表,重启服务后,查库、查表,发现test库中没有表。

rm  -rfv   /var/lib/mysql/*

systemctl   restart   mariadb

mysql  -uroot   -e   'show  databases;use  test;show  tables;'

#冷恢复数据库、表。

systemctl    stop   mariadb

\cp   -afrv    /opt/data/mysql-$(date +%F)/*    /var/lib/mysql/

systemctl   restart   mariadb

mysql  -uroot  -p456   -e   'show  databases;use  test;show  tables;'

 

 

 

MySQL环境的部署

查软件是否已安装

安装mariadb软件

启动服务器端的服务

允许开机自动启动

内测

rpm  -q  mariadb-server  mariadb

yum  install  -y  mariadb-server  mariadb

systemctl  restart  mariadb

systemctl  enable  mariadb

mysql

exit     (\q)

 

主从复制

作用:

简称AB复制,在A主机上做create、update、insert、drop、delete等数据库、表、记录的增、删、改操作,B主机上会自动做数据库、表、记录的同步更新。

AB复制的工作原理(即工作过程):

1. 在主库上把数据更改记录到二进制日志(Binary Log)中。

2. 备库将主库上的日志复制到自己的中继日志(Relay Log)中。

3. 备库读取中继日志中的事件,将其重放到备库数据库之上。

 

AB复制的配置思路:

1.在A主机(master)上的/etc/my.cnf主配置文件中开启binlog二进制日志文件功能,并且给主机设置server-id唯一标识编号。重启mariadb服务。

2.在A主机上创建用于AB主从复制的用户账号,并查看master状态中的binlog日志文件的position位置数值。

3.在B主机上的/etc/my.cnf主配置文件中设置server-id唯一标识编号。。重启mariadb服务。

4.在B主机上用help change master查命令帮助,并用change master命令告诉B主机他的master主人的正确信息。

5.在B主机上用start slave启动mariadb的随从服务,并用show slave status查看AB主从复制的数据同步状态,要确认两个线程的yes状态。

 

 

AB复制的一主一从模式工作过程:

A主机   create  database  db1    ---->    会将此命令自动写入本机的二进制日志文件中

B主机   

I/O线程    监测并读A主机上的二进制日志文件新增的内容,且将新内容写入到B主机自己的中继日志文件中

SQL线程   读取B主机上中继日志文件中心的SQL语句,并且自动执行这些SQL语句。最终在B主机上创建了db1这个库。

 

 

网络拓扑:(1主1从)

mysql主服务器(master主人):192.168.11.11

mysql从服务器(slave随从、奴隶):192.168.11.12

准备工作:

1停止master、slave主机上的mariadb服务,并且清空/var/lib/mysql的所有数据。

systemctl   stop   mariadb

rm   -rfv   /var/lib/mysql/*

 

2重启master、slave主机上的mariadb服务。并且查库、test库中是否有表(无表就OK)。

systemctl   restart   mariadb

mysql   -uroot   -e   'show   databases;use  test;show  tables;'

 

 

 

AB复制的配置实施:

1在A主机(master)上的/etc/my.cnf主配置文件中开启binlog二进制日志文件功能,并且给主机设置server-id唯一标识编号。重启mariadb服务。

vim   /etc/my.cnf   做如下修改

[mysqld]    找到此行,添加如下蓝色字的3行功能选项

server-id=11               指定server-id为11,通常用本机IP的最后一组数

log-bin=master-bin      添加此行,指定二进制日志文件名为master-bin

skip_name_resolv=1    跳过域名解析功能

 

重启mariadb服务:

systemctl   restart   mariadb

 

2在A主机上创建用于AB主从复制的用户账号,并查看master状态中的binlog日志文件的position位置数值。

mysql  -uroot  -e  "grant  replication  slave  on  *.*  to  'rep'@'192.168.11.%'  identified  by  'rep';"

mysql  -uroot  -e  'select  user,host,password  from  mysql.user;

mysql  -uroot  -e   'reset  master;show   master   status;'

 

3在B主机上的/etc/my.cnf主配置文件中设置server-id唯一标识编号。重启mariadb服务。

vim   /etc/my.cnf   做如下修改

[mysqld]    找到此行,添加如下蓝色字的3行功能选项

server-id=12               指定server-id为12,通常用本机IP的最后一组数

#log-bin=slave-bin      添加此行,指定二进制日志文件名为slave-bin

skip_name_resolv=1    跳过域名解析功能

 

重启mariadb服务:

systemctl   restart   mariadb

mysql  -urep   -prep   -h192.168.11.11   -e   'status;'     测试rep用户是否能远程访问master主机的数据库服务

 

4在B主机上用help   change  master查命令帮助,并用change  master命令告诉B主机他的master主人的正确信息。

mysql

help   change  master  to;

CHANGE MASTER TO

  MASTER_HOST='192.168.11.11',

  MASTER_USER='rep',

  MASTER_PASSWORD='rep',

  MASTER_PORT=3306,

  MASTER_LOG_FILE='master-bin.000001',

  MASTER_LOG_POS=542,

  MASTER_CONNECT_RETRY=10;            //是指从和主连不上是重试连接的时间为10秒

 

5在B主机上用start slave启动mariadb的随从服务,并用show slave status查看AB主从复制的数据同步状态,要确认IO和SQL两个线程的yes状态。

mysql -uroot -p

start slave;

show slave status\G 注: \G 是分组(group)显示信息。

 

6测试主从复制的数据同步。

首先,在A主机(192.168.11.11)上创建一个名称为db1的库,并查库。

mysql

create   database   db1;

show  database;

SHOW  PROCESSLIST;        查mysql的内部进程(即线程)清单

然后,在B主机上查库,看到了db1库,说明AB主机的数据自动同步成功。

mysql   -uroot   -e   'show  databases;'

 

注:change  master  to设置的信息默认保存在/var/lib/mysql/master.info文件中,relay中继日志的设置信息默认保存在/var/lib/mysql/relay-log.info文件中。

ls  /var/lib/mysql/

cat   /var/lib/mysql/master.info

cat   /var/lib/mysql/relay-log.info

cat   /var/lib/mysql/mysql.sock      此套接字设备文件无法查看,是正常现象

 

 

 

读写分离

 

1. 基于程序代码内部实现

在代码中根据 select、insert 进行选择分类; 这类方法也是目前生产环境应用最广泛的。优点是性能较好,因为在程序代码中实现,不需要增加额外的设备作为硬件开支。缺点是需要开发人员来实现,运维人员无从下手。

 

2. 基于中间代理层实现

代理一般是位于客户端和服务器之间, 代理服务器接到客户端请求后通过判断然后转发到后端数据库。目前主要有两个代表性程序:

mysql-proxy: mysql-proxy 为 MySQL 开源项目,通过其自带的 lua 脚本进行 SQL 判断,虽然是 MySQL 官方产品,但是 MySQL 官方并不建议将 mysql-proxy 用到生产环境。

 

amoeba: 由陈思儒开发,作者曾就职于阿里巴巴,现就职于盛大。该程序由 java 语言进行开发,目前只听说阿里巴巴将其用于生产环境。另外,此项目严重缺少维护和推广。

 

mysql的读写分离集群架构图:

client----->mysql-proxy/Atlas代理(数据库代理商)----->mysql-server服务器A(Read/Write可读可写)

                                                                ----->mysql-server服务器B(ReadOnly可读)

                                                                ----->mysql-server服务器C(ReadOnly可读)

                                                                ----->mysql-server服务器D(ReadOnly可读)

 

 

采用Atlas实现MySQL读写分离

 

Atlas的优点

(1)、基于mysql-proxy-0.8.2进行修改,代码完全开源;

(2)、比较轻量级,部署配置也比较简单;

(3)、支持DB读写分离;

(4)、支持从DB读负载均衡,并自动剔除故障从DB;

(5)、支持平滑上下线DB;

(6)、具备较好的安全机制(IP过滤、账号认证);

(7)、版本更新、问题跟进、交流圈子都比较活跃。

 

过程

1、安装和配置atlas软件

rpm  -ivh  Atlas-2.2.1.el6.x86_64.rpm

rpm  -ql   Atlas

echo "PATH=$PATH:/usr/local/mysql-proxy/bin/"   >  /etc/profile.d/atlas.sh

source  /etc/profile.d/atlas.sh     加载环境配置文件

ll /usr/local/mysql-proxy/

 

 

cd /usr/local/mysql-proxy/bin/

./encrypt  01   生成加密密码,并复制此密码

注:此处的密码01是mysql-server服务器上admin用户账号的密码,请在后端的mysql-server服务器上用grant   all   on  *.*   to  admin@'%'   identified   by   '01'   with  grant   option;来创建admin这个用户。

cd /usr/local/mysql-proxy/conf/        切换到atlas的配置文件目录中

cp -av  test.cnf  test.cnf.bak    //备份test.cnf配置文件

vi  test.conf     修改后的读写分离的完整配置文件内容(以下红字是要改的内容)

[mysql-proxy]

admin-username = user

admin-password = pwd

proxy-backend-addresses = 192.168.100.25:3306     后端负责读写的服务器IP和端口号

proxy-read-only-backend-addresses = 192.168.100.26:3306@1,192.168.100.27:3306@2

#以下的pwds是后端的mysql-server服务器上的用户账号和密码,必须正确,否则mysql-proxyd服务无法启动。

pwds = admin:VFnEp9P4Vu4=, rep:VFnEp9P4Vu4=     //后端MYSQL的用户名和encrypt命令生成的加密密码

 

daemon = true

keepalive = true

event-threads = 8

log-level = message

log-path = /usr/local/mysql-proxy/log   //日志文件路径

proxy-address = 0.0.0.0:3306          //Atlas监听的管理接口IP和端口  

admin-address = 0.0.0.0:2345         //Atlas监听的管理接口IP和端口

 

启动atlas服务:/usr/local/mysql-proxy/bin/mysql-proxyd  test  start

atlas端口号:lsof  -i  :3306     lsof  -i  :2345

重启atlas服务:/usr/local/mysql-proxy/bin/mysql-proxyd  test  restart

 

访问atlas代理服务器的测试:

yum  install  -y  mariadb         安装mariadb客户端软件

mysql  -uadmin  -p01  -h 192.168.10.11 -P3306

 

登录到atlas管理端:mysql  -uuser  -ppwd  -h 192.168.10.11 -P2345

 

tcpdump抓包: tcpdump -i ens33 port 3306

说明:抓取经过192.168.10.11代理主机的ens33网卡的3306端口的数据包,验证读写分离效果。

 

 

MySQL事务

 

事务:这个词的字面意思是什么?    

答:要做的一件事情和任务。mysql中采用事务功能可以实现有选择性胡对表中数据操作做回滚、提交。

MYSQL默认处理任务的原则:执行增、删、改操作会自动保存数据到库、表、记录中。

MYSQL的事务处理主要有两种方法

一、用begin , rollback , commit来实现

begin

开始一个事务,然后执行create、update、insert等操作

rollback

事务回滚(相当于word中的ctrl+Z撤消

commit

事务确认(提交,相当于word中的ctrl+s保存

 

 

二、直接用set来改变mysql的自动提交模式

MYSQL默认是自动提交的,也就是你提交一个QUERY,它就直接执行!我们可以通过

show   variables \G

查看MYSQL环境变量

show   variables  like 'autocom%';      

查看autocommit环境变量的状态

set  autocommit=0

禁止自动提交(临时设置) (即自动开启事务功能,并不需要用begin开始事务,但是必须用commit提交操作,或用rollback撤消操作)

set autocommit=1  

开启自动提交(必须用begin开始一个事务,用commit或rollback结束事务

 

MySQL触发器

触发器(trigger)是一个特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件(event)来触发。比如当对A表进行操作事件( insert,delete, update)时就会激活它执行。触发器经常用于加强数据的完整性约束和业务规则等。

 

作用

A表做增insert、删delete、改update操作,B表自动会执行某个SQL操作。

 

创建Trigger

语法:

   CREATE  TRIGGER  触发器名称  BEFORE | AFTER  触发事件

   ON  表名  FOR  EACH  ROW

   BEGIN

触发器程序体;

   END

 

内容

解释说明

<触发器名称>

最多64个字符,它和MySQL中其他对象的命名方式一样

{ BEFORE  |  AFTER }

触发器时机

{ INSERT  |  UPDATE  |  DELETE }

触发的事件

ON <表名称>

标识建立触发器的表名,即在哪张表上建立触发器

FOR  EACH  ROW

触发器的执行间隔:FOR EACH ROW子句通知触发器 每隔一行 执行一次动作,而不是对整个表执行一次

<触发器程序体>

要触发的SQL语句:可用顺序,判断,循环等语句实现一般程序需要的逻辑功能

 

 

例:

1、创建表

mysql> use  test;

mysql> create table stu(

id int unsigned auto_increment primary key not null,

name varchar(50)

);

mysql> insert into stu(name) values('jack');

mysql> create table stu_total(total int);

mysql> insert into stu_total values(1);

 

2、创建触发器stu_insert_trigger

mysql> delimiter   $$          临时定义命令的结束符为$$号 (或:\d 

mysql> create  trigger  stu_insert_trigger  after  insert

    -> on   stu   for   each   row

    -> BEGIN

    ->     update  stu_total  set  total=total+1;

    -> END$$

mysql> delimiter  ;      临时定义命令的结束符为;

3、优化过的正确触发器

触发器stu_insert_trigger

drop  triggers  stu_insert_trigger;

delimiter   $$

create   trigger  stu_insert_trigger  after insert

    on  stu  for  each  row

    BEGIN

        update   stu_total  set total=(select  count(*)  from  stu);

    END$$

delimiter  ;

 

 

查看触发器

1. 通过SHOW TRIGGERS语句查看

SHOW TRIGGERS\G

2. 通过系统表triggers查看

USE information_schema

SELECT * FROM triggers\G

SELECT * FROM triggers WHERE TRIGGER_NAME='触发器名称'\G

 

测试触发器

说明:插入两条记录,然后查stu表、stu_total表中的数据变化,验证触发器功能是否生效。

insert  into  stu  values(2,'tom');

insert  into  stu  values(3,'alice');

select  *   from  stu;

select  *   from  stu_total;

delete   from  stu  where   id=3;

select  *   from  stu;

select  *   from  stu_total;

 

删除触发器

通过DROP TRIGGERS语句删除

DROP TRIGGER 解发器名称

 

小结

    以上案例是在stu表中插入一条记录,stu_total表中的total字段的值就会自动加1,

在stu表中删除一条记录,stu_total表中的total字段的值就会自动减1。

    此例的触发器故障bug:如果stu_total表中的初始统计数据不正确,以上定义的这个触发器会导致stu_total表中统计的total值跟stu表中的总记录数信息不对称,所以这个触发器是有问题的。正确的解法是用count函数来统计stu表中的记录数,不应该用加1或减1这种做法。

 

MySQL视图

 

概念

MySQL视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。但是,视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。对其中所引用的基础表来说,MySQL视图的作用类似于筛选。

定义视图的筛选可以来自当前或其它数据库的一个或多个表,或者其它视图。通过视图进行查询没有任何限制,通过它们进行数据修改时的限制也很少。

视图是存储在数据库中的SQL查询语句,它主要出于两种原因:

安全原因,视图可以隐藏一些数据,如:一些敏感的信息

使复杂的查询易于理解和使用。

 

视图类似于excel中的筛选功能。

通俗理解:就是将一张表中经常要查询的列和记录创建成一张虚拟的表,其实viewer视图中存放的是select语句。视图中看到的数据会随着原始表格的更新而动态更新。

 

作用

视图其实就是将一条SQL的select查询语句取个名字保存起来,当用select语句查询这个视图时,数据库底层就是执行视图中所保存的select语句。可以用视图来提高数据库的安全性。

 

创建视图

语法一:

CREATE   [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE} ] 

  VIEW  视图名 [(字段1,字段2…)]

  AS  SELECT语句

  [WITH [CASCADED | LOCAL] CHECK OPTION ];

语法二:

CREATE  VIEW 视图名

  AS  SELECT语句;

 

 

 

查看视图

1、SHOW TABLES      查看视图名

    SHOW TABLES;

2、 SHOW  TABLE  STATUS

示例:查看数据库mysql库中视图及所有表详细信息

   SHOW    STATUS   FROM   mysql \G

示例:查看数据库mysql中视图名view_user详细信息

   SHOW   TABLE   STATUS   FROM   mysql   LIKE   'view_user' \G

  

命令格式:show  table  status   from  库名   where   条件

例如:show table status from shop where Comment='VIEW'\G

3. SHOW CREATE VIEW

   示例:查看视图定义信息

   SHOW CREATE VIEW  视图名\G

4. DESCRIBE

   示例:查看视图结构

   DESC   视图名;

 

修改视图

方法一:删除后新创建

DROP VIEW view_user ;

CREATE VIEW view_user

AS SELECT user,host FROM mysql.user;

SELECT * FROM view_user;

方法二:ALTER修改视图

语法:

ALTER VIEW 视图名

AS  SELECT语句;

 

示例:

ALTER VIEW view_user

AS  SELECT user,password FROM mysql.user;

 

通过视图操作基表

查询数据SELECT

SELECT   *   FROM   view_user;

更新数据UPDATE

删除数据DELETE

 

删除视图

语法:

DROP VIEW view_name [,view_name]…;

 

示例:

USE   mysql;

DROP   VIEW   view_user ;

 

 

存储过程

概念

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

本质作用

定义数据存储的过程,存储过程中允许对库、表、记录做增、删、改、查等操作。

\d   $$         等同于delimiter  $$,设置命令的界定符(也称结束符)

 

例:创建一个名称为dba的库文件,在dba库中创建一张名称为tb1的表,表中有id、name这两个字段。创建一个名称为ad1的存储过程,ad1存储过程的功能是插入三条记录到tb1表中

mysql>create  database  dba;

mysql>use  dba;

mysql>create  table   tb1(id  int,name   char(20));

mysql> \d   $$         等同于delimiter  $$,设置命令的界定符(也称结束符)

mysql> create procedure  ad1()    创建ad1这个存储过程(类似于shell脚本)

    -> BEGIN

    -> declare i int default 1;

    -> while(i<=3)do

    -> insert into dba.tb1 values(i,'ccc');

    -> set i=i+1;

    -> end while;

    -> END$$

mysql> \d   ;

 

mysql> select    *   from   tb1;

mysql> call  ad1();    调用此存储过程

mysql> select    *   from   tb1;

 

 

练习:定义一个名称为ak的存储过程,功能是实现创建一个名称为dbak的库,在dbak库中创建tbak表,tbak表中有id、name这两个字段,在tbak表中插入2条记录1、tom和2、alice的信息。测试ak这个存储过程的调用。

1)首先,创建存储过程。

\d  $$

create   procedure   ak()

BEGIN

    create   database   dbak;

    create  table  dbak.tbak(id  int,name   char(20));

    desc   dbak.tbak;

    insert   into   dbak.tbak  values(1,'tom'),(2,'alice');

    select   *   from  dbak.tbak;

END$$

 

2)然后,调用存储过程:call   ak();

 

常用函数

查看当前的时间:select   now();

查看版本号:select   version();

 

存储过程(procedure)和函数(function)的主要区别:

      存储过程是针对表中的数据记录进行处理的SQL语句集合,就类似于shell脚本。

      函数通常是针对记录中的某个字段的值进行处理。

 

 

索引

概念

索引在MySQL中也叫做“键”,是存储引擎用于快速找到记录的一种数据结构。索引对于良好的性能非常关键,尤其是当表中的数据量越来越大时,索引对于性能的影响愈发重要。

索引优化应该是对查询性能优化最有效的手段了。索引能够轻易将查询性能提高好几个数量级。

索引相当于字典的音序表,如果要查某个字,如果不使用音序表,则需要从几百页中逐页去查。

我的理解:索引,就是检索引导的意思。是通过一定的算法将数据库中的记录按一定的规律进行分组,查信息时可以缩小数据的搜索范围,从而提高了查询效率。

 

 

索引为什么可以提高数据查询速度?

索引底层的工作是会将表中的数据记录按一定算法(规律)进行分组,用户在查数据时会自动到所对应的组中去查,这样就缩小了查询范围,所以提高了效率。

 

过程

创建索引

创建表时创建索引

CREATE在已存在的表上创建索引

ALTER TABLE在已存在的表上创建索引

查看并测试索引

删除索引

 

分类

普通索引

唯一索引

全文索引:只有MYISAM存储引擎支持全文索引,innodb存储引擎不支持全文索引。

单列索引

多列索引

空间索引

 

创建索引

创建表时

语法:

CREATE TABLE 表名 (

字段名1 数据类型 [完整性约束条件…],

字段名2 数据类型 [完整性约束条件…],

[UNIQUE | FULLTEXT | SPATIAL ] INDEX | KEY

[索引名] (字段名[(长度)] [ASC |DESC])

);

CREATE对已存在的表创建索引

语法:

CREATE  [UNIQUE | FULLTEXT | SPATIAL ]  INDEX  索引名

       ON 表名 (字段名[(长度)]  [ASC |DESC]) ;

 

ALTER  TABLE在已存在的表上创建索引

语法:

ALTER TABLE 表名 ADD  [UNIQUE | FULLTEXT | SPATIAL ] INDEX

    索引名 (字段名[(长度)]  [ASC |DESC]) ;

 

例1:

CREATE TABLE dept10 (

dept_id INT,

dept_name VARCHAR(30) ,

comment VARCHAR(50),

INDEX index_dept_name (dept_name)        将表中的dept_name字段指定为普通索引字段

);

例2:创建唯一索引示例:(此方法要指定索引名称)

CREATE UNIQUE INDEX index_dept_name ON dept6 (dept_name);

例3:

用创建普alter通索引示例:

ALTER   TABLE   dept   ADD   INDEX   index_dept_name    (dept_name);

命令格式:alter   table   表名  add   index   索引名   (字段名); 

 

 

管理索引

查看索引:

SHOW CRETAE TABLE 表名\G

测试示例:

EXPLAIN   SELECT * FROM   dept   WHERE   dept_name='hr';

删除索引:

  show create table employee6;

  DROP INDEX 索引名 ON 表名;

 

 

MySQL多表查询

 

多表连接查询

交叉连接:

生成笛卡尔积,它不使用任何匹配条件(很少用)

内连接:

只连接匹配的行,需要用where指定条件

外连接之左连接:

会显示左边表内所有的值,不论在右边表内匹不匹配

外连接之右连接:

会显示右边表内所有的值,不论在左边表内匹不匹配

全外连接:

包含左、右两个表的全部行

 

复合条件连接查询

1:以内连接的方式查询emp6和dept6表,并且emp6表中的age字段值必须大于25

mysql> select emp_id, emp_name, age, dept_name   from emp6,dept6  where emp6.dept_id = dept6.dept_id and age>25;

即:找出公司所有部门中年龄大于25岁的员工

 

子查询

子查询是将一个查询语句嵌套在另一个查询语句中。

内层查询语句的查询结果,可以为外层查询语句提供查询条件。

子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字

还可以包含比较运算符:= 、 !=、> 、<等

将一个select查询语句的结果作为另一个select查询语句的条件。

例:select   *   from   A表   where   id   in  (select   id  from   B表   where   id=3)

 

 

 

MySQL常用语句总结

 

SQL语句总结:

登录和退出MySQL

mysql  -uroot  -p密码

exit  或者:\q

示例:

mysql  -h192.168.5.240  -P 3306 - u root  -p123  mysql  -e  ‘select user,host from user’

    -h  指定主机名

    -P  MySQL服务器端口

    -u  指定用户名

    -p  指定登录密码

此处mysql为指定登录的数据库

    -e  接SQL语句

库的操作:

1查库:show  databases;

2建库:create  database  库名  [选项];

3开库:use  库名;

4删库:drop  database  库名;

表的操作:

1查表(显示库中的表文件):show   tables;

2建表:create  table  表名(字段1  类型  约束,字段2  类型  约束,...);

3查表结构:desc   表名;

4表中新增一列(在最后):alter   table  表名  add  字段名  类型  约束;

5删除表中的sex这个字段(列):alter  table  表名  drop  sex;

6删除表:drop   table   表名;

记录操作:

1查表中的所有记录:select  *   from   表名;

2查test库中表tb1的id<=3的所有记录:select  *   from   test.tb1  where  id<=3;

3在tb1表中插入一行记录:insert   into  tb1  values(值1,值2,...);

4更新tb1表中name为jack的记录,将他的name值更新成jacker:

update  tb1 set  name='jacker'  where  name='jack';

5删除tb1表中id<=3的记录:delete  from  tb1  where  id<=3;

授权管理(用户安全管理):

1查mysql库中user表的user、host、password字段的数据记录:(查mysql系统中的用户账号)

select  user,host,password   from  mysql.user;

 

2在mysql中创建一个跟root账号相同权限的新账号admin:

grant  all  on  *.*  to  admin@'%' identified  by  '密码'  with  grant  option;

 

3查看root账号的授权信息:

show  grants  for  root@'localhost';

 

4回收admin账号的insert、update、delete权限:

revoke  insert,update,delete  on  *.*  from  admin@'主机名或IP';

 

5删除admin账号:

drop  user  admin@'主机名或IP';