该篇写的偏理论,点击查看常用指令
phpstudy的mysql目录介绍
1、bin //可执行文件
2、data //数据库
3、lib //扩展库,一般用不到
4、logs //日志
5、share //系统需要的东西,如 编码啥的
6、my.ini //配置文件。linux上后缀是.cnf
剩余的ini文件也都是配置文件,只是针对的服务器配置不同而已,如 my-smail.ini是针对内存小于64M用的,用法如下:
假如你的服务器配置小于64M,将my-smail.ini文件改名为my.ini,然后将其他的配置文件删除即可
sql语句的书写规则:
1、以分号结尾 可以用delimiter修改
2、不区分大小写
3、#注释
位、字节、字符(计量单位)的关系:
位 | 字节 | 字符(多字节) | |
英文、数字 | 8 | 1 | 1 |
汉字gbk编码 | 8 | 2 | 1(gbk中2个字节是1个字符) |
汉字utf8编码 | 8 | 3 | 1(uf8中3个字节是1个字符) |
mysql数据类型介绍:
整数型:
注意:有符号是从负数开始存,无符号是从正数0开始存;超过了最大值以最大值为准
注意:单双精度会四舍五入,和钱沾边的用decimal
字符串
注意:
1、括号里的是长度是字符。select char_length(name) from tp5_user; //该字段中,字符串所占的字符数
2、char 读写速度快,因为他在内存中是按快找,缺点 浪费内存,因为存的不够会自动补空格
时间日期
字段的其他修饰关键词:
1、unsigned #无符号
2、auto_increment #自增
3、default 默认值 #给默认值的,如 价格默认0.00。不写 默认为null
4、comment '' #字段说明(注释)
5、not null #不能为空
6、null #可以为空
7、unique #唯一索引(对该列数据进行唯一性效验,插入重复的值会报error:Duplicate entry '123' for key 'user_name')
8、key 或 index #普通索引
9、primary key #主键索引
注意:
1、一般auto_increment 和 primary key是一对,在一起不分离主键索引才自增
2、全文索引用的是MyISAM引擎,只支持英文
3、外键索引语法:foreign key (b表字段名) references a表(外键字段名)
如 a(外键)表是学生表,b(本)表是成绩表。
作用:a表中如果没有该id,b表插入不进去,保持了数据的一致性,如果想要删除a表中的数据,也是无法清空的,因为b表对a表有依赖性。
3.1、a表的id要和b表的user_id数据类型,有无符号,是否为空等完全一致。
速记:涉及数字加unsigned ,每列必加not null和commet ''
加索引的2种方式:1、在字段中加;2、所有字段书写完后统一加
SQL语句
sql语句中的运算符:
1、 = #2个意思,等于 或 赋值,系统会根据上下文判断
2、!= <> #不等于
3、< > <= >= #小于 大于 小于等于 大于等于
4、OR #或
5、AND #与
6、BETWEEN ... AND #在...之间(判断2-5范围,与的关系)
7、IN #在...之内(判断2,3,4,5范围,或的关系)
8、NOT IN #不在...之内
sql语句的分类:
线上服务器的安全:
1、不要用root连接
2、默认密码也修改掉(因为人家会用字典一个一个的破)
修改密码:去表中改
忘记密码:先停掉mysql
使用该命令,就不会查mysql自带的user表了,会给你开个新进程
在打开一个cmd输入mysql进入mysql数据库
在通过sql语句更新,mysql自带的user表里的密码,在刷新权限
3、限制登录ip
需求:如果代码和数据库不在同一个服务器中才需要改,小项目不需要改;或只允许自己的电脑连
查看mysql自带的数据库中的user表
干掉后2条,登录就要加-h 而且只能是127.0.0.1才能访问
如果直接删掉不管用,就将root用户的host改成自己电脑的ip
普通用户的创建授权及权限回收
创建用户:
注意:
1、和权限相关的,每次做完都要刷新权限
2、%不安全,因为他对所有的ip都放行
给用户权限:
撤销权限:
查看权限:
删除用户:
表的存储引擎
怎么理解这个引擎呢??
将mysql理解成显示器,引擎可以理解为cpu。因为mysql是开源的,这些引擎有好多都不是官方的,而是开源爱好者提供的。
为啥要弄这么多引擎啊??
不同的引擎,是解决不同的场景,是解决不同场景遇到问题的。
如 csv 对应的excel入库 用这个快还好
表锁:每次写操作都会锁整张表,这整张表就不能进行任何读、写操作了
行锁:每次写操作都会锁整行,这行记录就不能进行任何读、写操作了
sql_mode的模式
往MySQL数据库中插入一组数据时,出错了!数据库无情了给我报了个错误:ERROR 1365(22012):Division by 0;意思是说:你不可以往数据库中插入一个 除数为0的运算的结果。于是乎去谷歌了一番,总算是明白了其中的原因:是因为MySQL的sql_mode 模式限制着一些所谓的‘不合法’的操作。
解析
这个sql_mode,简而言之就是:它定义了你MySQL应该支持的sql语法,对数据的校验等等。。
一、如何查看当前数据库使用的sql_mode:
mysql> select @@sql_mode;如下是我的数据库当前的模式:
二、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:
如果需要的存储引擎被禁用或未编译,那么抛出错误。不设置此值时,用默认的存储引擎替代,并抛出一个异常
另外还有一些,这里仅对我本地当前值做解释分析。。。。。
三、据说是MySQL5.0以上版本支持三种sql_mode模式:ANSI、TRADITIONAL和STRICT_TRANS_TABLES。
1、ANSI(默认)模式:宽松模式,更改语法和行为,使其更符合标准SQL。对插入数据进行校验,如果不符合定义类型或长度,对数据类型调整或截断保存,报warning警告。对于本文开头中提到的错误,可以先把sql_mode设置为ANSI模式,这样便可以插入数据,而对于除数为0的结果的字段值,数据库将会用NULL值代替。
将当前数据库模式设置为ANSI模式:
mysql> set @@sql_mode=ANSI;
2、TRADITIONAL模式:严格模式,当向mysql数据库插入数据时,进行数据的严格校验,保证错误数据不能插入,报error错误,而不仅仅是警告。用于事物时,会进行事物的回滚。 注释:一旦发现错误立即放弃INSERT/UPDATE。如果你使用非事务存储引擎,这种方式不是你想要的,因为出现错误前进行的数据更改不会“滚动”,结果是更新“只进行了一部分”。
将当前数据库模式设置为TRADITIONAL模式:
mysql> set @@sql_mode=TRADITIONAL;
3、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中代码复用)。先定义,后调用
1、将sql结尾的;改成其他符号(防止冲突,将存储过程提前结束。因为你存储过程中也会用到分号)
delimiter /// #将sql结束符改成///
2、定义存储过程
语法:create procedure 相当于php的 public function
查看存储过程
3、使用存储过程
4、不想要了,直接删除
视图的创建删除及使用场景
主要作用:涉及到安全方面
场景1:别的公司想调用咱们的用户,就可以给他创建一个视图。他只能调用这个视图(调用我们想给他暴露的数据)
场景2:cto不想让开发知道更多的用户信息
场景3:新手不会写复杂的sql(如 连表啊,子查询啊),老司机就给他个视图就ok了,因为视图的后面就是sql语句
视图和存储过程的区别:
1、存储过程:中可以是各种sql语句,是方便我们自己使用
2、视图:中只能是select,是方便我们给外人使用,会生成一张表
总结:相当于是as后面得sql结果存到了test_view表中(show tables;就能看出来),然后使用视图的时候查test_view表
创建视图:
注意:as后面是sql语句,写不写where条件都可以
查看视图:
使用视图:
删除视图:
触发器
对某个(文章)表做了某些操作,它会触发另一些操作(统计表+1)
场景1:文章表每发送一篇文章,统计表中+1(创建一个触发器),删掉一篇文章-1(在创建一个触发器)
总结:相当于php框架中的钩子
1、准备数据,创建文章表和统计表
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);
2、创建增加的触发器
往article表中插入数据
insert into article (title) values('woshi_title');
查看total_num统计表
3、创建删除的触发器
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;
4、查看触发器:
5、删除触发器:
慢查询日志、优化
1、首先查看慢查询日志是否开启
注意:平常不要开,只有分析的时候才开(因为开启后sql语句需要往日志里写,也要耗时间)。
注意:5.6以上的版本,开启慢查询是slow_query_log这个变量
show global log_slow_queries=on; //打开慢查询日志,临时生效,永久生效需要写在my.cnf中
mysql> set long_query_time=0.2; //设置为200ms算慢查询
2、看日志,找出执行时间超过200ms的慢查询sql
3、分析慢的原因
思路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 //
对应了:数据类型是字符串,查询时不加引号,索引会失效
数据库缓存
缓存默认是开启的
看缓存命中率