mysql从入门到精通

该篇写的偏理论,点击查看经常使用指令php

phpstudy的mysql目录介绍

一、bin //可执行文件html

二、data //数据库mysql

三、lib //扩展库,通常用不到linux

四、logs //日志sql

五、share //系统须要的东西,如 编码啥的数据库

六、my.ini //配置文件。linux上是my.cnf编程

剩余的ini文件也都是配置文件,只是针对的服务器配置不一样而已,如 my-smail.ini是针对内存小于64M用的,用法以下:vim

假如你的服务器配置小于64M,将my-smail.ini文件更名为my.ini,而后将其余的配置文件删除便可缓存

*默认路径:/usr/local/mysql/varphp框架

mysql> show variables like 'general_log_file';		#日志文件路径
mysql> show variables like 'log_error';			#错误日志文件路径
mysql> show variables like 'slow_query_log_file';	#慢查询日志文件路径

七、https://www.cnblogs.com/songanwei/p/9167326.html  #使用了哪一个配置文件

 

sql语句的书写规则:

一、以分号结尾 能够用delimiter修改

二、不区分大小写

三、#或--注释

位、字节、字符(计量单位)的关系:

 

  字节 字符(多字节)
英文、数字 8 1 1
汉字gbk编码 8 2 1(gbk中2个字节是1个字符)
汉字utf8编码 8 3 1(uf8中3个字节是1个字符)

 

 

 

mysql数据类型介绍:

整数型:

注意:有符号是从负数开始存,无符号是从正数0开始存;超过了最大值以最大值为准

注意:单双精度会四舍五入,和钱沾边的用decimal

字符串

注意:

一、括号里的是长度是字符。select char_length(name) from tp5_user; //该字段中,字符串所占的字符

二、char 读写速度快,由于他在内存中是按快找,缺点 浪费内存,由于存的不够会自动补空格

时间日期

*datetime的默认值是 '1970-01-01 00:00:00'

*timestamp的默认值是0,详见 http://www.javashuo.com/article/p-orbditbx-de.html

字段的其余修饰关键词:

一、unsigned #无符号

二、auto_increment #自增

三、default 默认值 #给默认值的,如 价格默认0.00。不写 默认为null

四、comment '' #字段说明(注释)

五、not null #不能为空

六、null #能够为空

七、unique #惟一索引(对该列数据进行惟一性效验,插入重复的值会报error:Duplicate entry '123' for key 'user_name')

八、key 或 index #普通索引

九、primary key #主键索引

注意:

一、通常auto_increment 和 primary key是一对,在一块儿不分离偷笑主键索引才自增

二、全文索引用的是MyISAM引擎,只支持英文

三、外键索引语法:foreign key (b表字段名) references a表(外键字段名)

如 a(外键)表是学生表,b(本)表是成绩表。

做用:a表中若是没有该id,b表插入不进去,保持了数据的一致性,若是想要删除a表中的数据,也是没法清空的,由于b表对a表有依赖性。

注意:数据不一致,俩个表的id数据不一致,就是b表中的id在a表中没有,会报1452;俩个id的数据类型、长度等不一致报1215

3.一、a表的id要和b表的user_id数据类型,有无符号,是否为空等彻底一致。

速记:涉及数字加unsigned ,每列必加not null和commet '' 

加索引的2种方式:一、在字段中加;二、全部字段书写完后统一加

SQL语句

 

sql语句中的运算符:

一、 = #2个意思,等于 或 赋值,系统会根据上下文判断    

二、!= <> #不等于

三、< > <= >= #小于 大于 小于等于 大于等于

四、OR #或

五、AND #与

六、BETWEEN ... AND #在...之间(判断2-5范围,与的关系)

七、IN #在...以内(判断2,3,4,5范围,或的关系)

八、NOT IN #不在...以内

sql语句的分类:

线上服务器的安全:

一、不要用root链接

二、默认密码也修改掉(由于人家会用字典一个一个的破)

修改密码:去表中改

三、win的忘记密码:先停掉mysql

使用该命令,就不会查mysql自带的user表了,会给你开个新进程

在打开一个cmd输入mysql进入mysql数据库

在经过sql语句更新,mysql自带的user表里的密码,在刷新权限

四、linux的忘记密码

  • 修改MySQL的配置文件(默认为/etc/my.cnf),在[mysqld]下添加一行skip-grant-tables

  • 保存配置文件后,重启MySQL服务 service mysqld restart

  • 再次进入MySQL命令行 mysql -uroot -p,输入密码时直接回车,就会进入MySQL数据库了,这个时候按照常规流程修改root密码便可。

    依次输入:

    >use mysql;    更改数据库

    >UPDATE user SET PASSORD =password("passwd") WHERE USER= 'root';  重设密码

    >flush privileges;  刷新MySQL的系统权限相关表,以防止更改后拒绝访问;或或者重启MySQL服务器

  • 密码修改完毕后,再按照步骤1中的流程,删掉配置文件中的那行,而且重启MySQL服务,新密码就生效了。

五、限制登陆ip

需求:若是代码和数据库不在同一个服务器中才须要改,小项目不须要改;或只容许本身的电脑连

查看mysql自带的数据库中的user表

干掉后2条,登陆就要加-h 并且只能是127.0.0.1才能访问

若是直接删掉无论用,就将root用户的host改为本身电脑的ip

普通用户的建立受权及权限回收

 

建立用户:

注意:

一、和权限相关的,每次作完都要刷新权限

二、%不安全,由于他对全部的ip都放行

给用户权限:

撤销权限:

查看权限:

删除用户:

 

表的存储引擎

怎么理解这个引擎呢??

将mysql理解成显示器,引擎能够理解为cpu。由于mysql是开源的,这些引擎有好多都不是官方的,而是开源爱好者提供的。

为啥要弄这么多引擎啊??

不一样的引擎,是解决不一样的场景,是解决不一样场景遇到问题的。

如 csv 对应的excel入库 用这个快还好

表锁:每次写操做都会锁整张表,这整张表就不能进行任何读、写操做了

行锁:每次写操做都会锁整行,这行记录就不能进行任何读、写操做了

sql_mode的模式

 

往MySQL数据库中插入一组数据时,出错了!数据库无情了给我报了个错误:ERROR 1365(22012):Division by 0;意思是说:你不能够往数据库中插入一个 除数为0的运算的结果。因而乎去谷歌了一番,总算是明白了其中的缘由:是由于MySQL的sql_mode 模式限制着一些所谓的‘不合法’的操做。

解析

这个sql_mode,简而言之就是:它定义了你MySQL应该支持的sql语法,对数据的校验等等。。

1、如何查看当前数据库使用的sql_mode:

mysql> select @@sql_mode;

以下是个人数据库当前的模式:

 

2、sql_mode值的含义:

ONLY_FULL_GROUP_BY:

对于GROUP BY聚合操做,若是在SELECT中的列,没有在GROUP BY中出现,那么将认为这个SQL是不合法的,由于列不在GROUP BY从句中

STRICT_TRANS_TABLES:

在该模式下,若是一个值不能插入到一个事务表中,则中断当前的操做,对非事务表不作任何限制

NO_ZERO_IN_DATE:

在严格模式,不接受月或日部分为0的日期。若是使用IGNORE选项,咱们为相似的日期插入'0000-00-00'。在非严格模式,能够接受该日期,但会生成警告。

NO_ZERO_DATE:

在严格模式,不要将 '0000-00-00'作为合法日期。你仍然能够用IGNORE选项插入零日期。在非严格模式,能够接受该日期,但会生成警告

ERROR_FOR_DIVISION_BY_ZERO:

在严格模式,在INSERT或UPDATE过程当中,若是被零除(或MOD(X,0)),则产生错误(不然为警告)。若是未给出该模式,被零除时MySQL返回NULL。若是用到INSERT IGNORE或UPDATE IGNORE中,MySQL生成被零除警告,但操做结果为NULL。

NO_AUTO_CREATE_USER

防止GRANT自动建立新用户,除非还指定了密码。

NO_ENGINE_SUBSTITUTION:

若是须要的存储引擎被禁用或未编译,那么抛出错误。不设置此值时,用默认的存储引擎替代,并抛出一个异常

另外还有一些,这里仅对我本地当前值作解释分析。。。。。

 

3、听说是MySQL5.0以上版本支持三种sql_mode模式:ANSI、TRADITIONAL和STRICT_TRANS_TABLES。

一、ANSI(默认)模式:宽松模式,更改语法和行为,使其更符合标准SQL。对插入数据进行校验,若是不符合定义类型或长度,对数据类型调整或截断保存,报warning警告。对于本文开头中提到的错误,能够先把sql_mode设置为ANSI模式,这样即可以插入数据,而对于除数为0的结果的字段值,数据库将会用NULL值代替。

将当前数据库模式设置为ANSI模式:

mysql> set @@sql_mode=ANSI;

二、TRADITIONAL模式:严格模式,当向mysql数据库插入数据时,进行数据的严格校验,保证错误数据不能插入,报error错误,而不只仅是警告。用于事物时,会进行事物的回滚。 注释:一旦发现错误当即放弃INSERT/UPDATE。若是你使用非事务存储引擎,这种方式不是你想要的,由于出现错误前进行的数据更改不会“滚动”,结果是更新“只进行了一部分”。

将当前数据库模式设置为TRADITIONAL模式:

mysql> set @@sql_mode=TRADITIONAL;

三、STRICT_TRANS_TABLES模式:严格模式,进行数据的严格校验,错误数据不能插入,报error错误。若是不能将给定的值插入到事务表中,则放弃该语句。对于非事务表,若是值出如今单行语句或多行语句的第1行,则放弃该语句。

将当前数据库模式设置为STRICT_TRANS_TABLES模式:

mysql> set @@sql_mode=STRICT_TRANS_TABLES;

没有最好与最坏的模式,只有最合适的模式。须要根据本身的实际状况去选择那个最适合的模式!!!

另外说一点,这里的更改数据库模式都是session级别的,一次性,关了再开就不算数了!!!

也能够经过配置文件设置:vim /etc/my.cnf
在my.cnf(my.ini)添加以下配置:
[mysqld]
sql_mode='你想要的模式'

DTL事物控制语言

 

一条sql语句就是一个事务。事务能够保证一组sql语句,要么都成功,要么都失败。默认自动提交

注意:执行sql语句的时候,会默认提交(就给数据写到硬盘中了)。修改完是临时生效

多个事务,同时并发执行的例子:多人同时转帐。

数据库编程--面向过程函数【存储过程】

 

把多条sql语句,写到一个函数中(它是一条或多条sql语句的集合)

做用:sql语句的复用(php中代码复用)。先定义,后调用

一、将sql结尾的;改为其余符号(防止冲突,将存储过程提早结束。由于你存储过程当中也会用到分号)

delimiter ///    #将sql结束符改为///

二、定义存储过程

语法:create procedure 至关于php的 public function

查看存储过程

三、使用存储过程

四、不想要了,直接删除

 

视图的建立删除及使用场景

 

主要做用:涉及到安全方面

场景1:别的公司想调用我们的用户,就能够给他建立一个视图。他只能调用这个视图(调用咱们想给他暴露的数据)

场景2:cto不想让开发知道更多的用户信息

场景3:新手不会写复杂的sql(如 连表啊,子查询啊),老司机就给他个视图就ok了,由于视图的后面就是sql语句

视图和存储过程的区别

一、存储过程:中能够是各类sql语句,是方便咱们本身使用

二、视图:中只能是select,是方便咱们给外人使用,会生成一张表

总结:至关因而as后面得sql结果存到了test_view表中(show tables;就能看出来),而后使用视图的时候查test_view表

建立视图:

注意:as后面是sql语句,写不写where条件均可以。test_view(这里的字段名叫啥无所谓,带不能用''括起来,个数要和as后面输出的对上)

查看视图:

使用视图:

删除视图:

 

触发器

对某个(文章)表作了某些操做,它会触发另外一些操做(统计表+1)

场景1:文章表每发送一篇文章,统计表中+1(建立一个触发器),删掉一篇文章-1(在建立一个触发器)

总结:至关于php框架中的钩子

一、准备数据,建立文章表和统计表

mysql> create table article(
    -> id int unsigned not null auto_increment primary key,
    -> title varchar(20) not null
    -> );
mysql> create table total_num(
    -> id int unsigned not null auto_increment primary key,
    -> type tinyint unsigned not null comment '1统计文章,2统计用户',
    -> num int unsigned not null
    -> );

先插入2条数据,否则他统计无法+1

insert into total_num (type,num) values(1,0);
insert into total_num (type,num) values(2,0);

二、建立增长的触发器

 

 
往article表中插入数据
insert into article (title) values('woshi_title');

查看total_num统计表

 

三、建立删除的触发器

mysql> create trigger delete_total_num after delete on article for each row
    -> begin
    -> update total_num set num=num-1 where type=1;
    -> end///

删除文章表的数据,触发删除触发器

delete from article where id=1;

 

四、查看触发器:

 

五、删除触发器:

 

mysql中的日志

 

MySQL中的日志包括:错误日志、二进制日志、通用查询日志、慢查询日志等等。

这里主要介绍下通用查询日志

通用查询日志记录创建的客户端链接和执行的语句

在学习通用日志查询时,须要知道几个数据库中的经常使用命令

一、 show variables like '%version%';

效果图以下:

上述命令,显示当前数据库中与版本号相关的东西。

二、show variables like '%general%';

 

能够查看,当前的通用日志查询是否开启,若是general_log的值为ON则为开启,为OFF则为关闭(默认状况下是关闭的)。

 

三、 show variables like '%log_output%';    //查看当前日志输出的格式

 

能够是FILE(存储在数数据库的数据文件中的hostname.log),

 

也能够是TABLE(存储在数据库中的mysql.general_log)

 

问题:如何开启MySQL通用查询日志,以及如何设置要输出的通用日志输出格式呢?

开启通用日志查询: set global general_log=on;

关闭通用日志查询: set globalgeneral_log=off;

设置通用日志输出为表方式: set globallog_output=’TABLE’;

设置通用日志输出为文件方式: set globallog_output=’FILE’;

设置通用日志输出为表和文件方式:set global log_output=’FILE,TABLE’;

注意:上述命令只对当前生效,当MySQL重启失效,若是要永久生效,须要配置my.cnf

日志输出的效果图以下:

记录到mysql.general_log表中的数据以下(从链接客户端开始执行的全部指令):

 

记录到本地中的.log中的格式以下(找不到,不知道这日志生成在哪了):

 

 

my.cnf文件的配置以下:

 

general_log=1  #为1表示开启通用日志查询,值为0表示关闭通用日志查询

log_output=FILE,TABLE#设置通用日志的输出格式为文件和表

四、在MySQL中有一个变量专门记录当前慢查询语句的个数

输入命令:show global status like ‘%slow%’;

 

 

 

 

 

慢查询日志、优化

 

慢查询日志:记录全部执行时间超过long_query_time秒的全部查询或者不使用索引的查询

该日志能够写入文件或者数据库表,若是对性能要求高的话,建议写文件。超过1秒的就算慢查询了。

通常来讲,慢查询发生在大表(好比:一个表的数据量有几百万),且查询条件的字段没有创建索引,此时,要匹配查询条件的字段会进行全表扫描,耗时查过long_query_time,则为慢查询语句。

一、首先查看慢查询日志是否开启

第1种:超过long_query_time时间的慢查询

注意:日常不要开,只有分析的时候才开(由于开启后sql语句须要往日志里写,也要耗时间)。

set global slow_query_log=on;   //打开慢查询日志,临时生效,永久生效须要写在my.cnf中

set long_query_time=0.2;    //设置为200ms算慢查询。注意:设置这个参数的时候不要加global

第2种:不使用索引的慢查询

注意:若是只是将log_queries_not_using_indexes设置为ON,而将slow_query_log设置为OFF,此时该设置也不会生效,即该设置生效的前提是slow_query_log的值设置为ON),通常在性能调优的时候会暂时开启。

总结:俩种方式加一块儿,看下图这4个就够了

二、实际在学习过程当中,如何得知设置的慢查询是有效的

很简单,咱们能够手动产生一条慢查询语句,

好比,若是咱们的慢查询log_query_time的值设置为1,则咱们能够执行以下语句:

select sleep(1);

该条语句便是慢查询语句,以后,即可以在相应的日志输出文件或表中去查看是否有该条语句。

三、看日志,找出执行时间超过200ms的慢查询sql

 

慢查询的日志记录myql.slow_log表中,格式以下:

 

慢查询的日志记录到hostname.log文件中,格式以下:

 

 

能够看到,无论是表仍是文件,都具体记录了:

 

是那条语句致使慢查询(sql_text),

该慢查询语句的查询时间(query_time),

锁表时间(Lock_time),

以及扫描过的行数(rows_examined)等信息。

四、分析慢的缘由

思路1:使用explain sql语句; 查看详细信息作对比;

思路2:

mysql> set  profiling=on;    //打开性能

执行一遍慢的sql语句

而后输入 show profiles; 查看执行过程

思路:不知道怎么优化,直接给时间长的粘百度上,看别人咋解决的

案例1:若是执行过程当中缓存锁(xxxxx query cache lock)太耗时,颇有可能缓存出问题了,这时候就给缓存关掉

案例2:不要在字段或字段的值上作运算(这样也索引会失效)

 

starting //开启

checking permissions //检测权限

opening tables    //打开表

system lock    //表锁、行锁的那个锁

init //初始化

optimizing    //

statistics    //

preparing    //预编译(这时候就体验出存储过程了,存储过程会提早预编译好,直接调用执行便可)

executing    //编译完执行

sending data    //搜索数据并返回(发送给我)

end    //结束

query end    //

closing tables    //关闭表

freeing items    //

logging slow query    //若是发现该条sql慢,会记录到慢日志中

cleaning up    //

对应了:数据类型是字符串,查询时不加引号,索引会失效

 

数据库缓存

缓存默认是开启的

看缓存命中率