本文为作者原创,未经允许请勿转载
Mysql
Password_hash密码加密:
加密存入:$_POST['pwd'] = password_hash($_POST['pwd'],PASSWORD_DEFAULT );
将密码拿出对比:第一个参数是明文,第二个参数是hash加密过的密文。
if(password_verify($_POST['pwd'],$arr['pwd'])){
echo'OK';
}else{
echo'no';
}
聚合函数:
count(字段/*) 统计行数
max(字段) 求字段中的值的最大值
min(字段) 求字段中的值的最小值
avg(字段) 求字段中值的平均
sum(字段) 求字段的值的总和
group_concat()将组中成员拼接起来
all()跟所有进行对比
分组:
1. 查出有哪些部门的情况
a) select distinct(dept) fromstaff;
b) select dept from staff group bydept;
2. 聚合函数必须放在字段列表当中或者having之中,放在其他地方会出错
3. select 字段 from 表名 where where条件 group by 分组条件 having having条件
order by 字段 asc/desc limitoffset, row
4. 查询总条件的怎么样的组别的什么1和什么2:
Select 什么1,什么2 from 表名where 总条件group by 分组名 having 怎么样的组的条件;
5. group by 只能在where和order中间这个顺序
6. where是在分组前的限制条件,having是分组后的限制条件
7. 除聚集计算语句外,SELECT语句中的每个列都必须在GROUP BY中给出
//错误,由于name字段没有写到group by之后
selectcount(id),name,sex from user group by sex;
//正确写法
selectcount(id),name,sex from user group by sex,name;
但是这个mysql版本问题,不同版本不一定会出错。 猜测是规范写法应该是会以group by后的字段用于分组,后面的用于规范,不同于我的版本会以所以字段分组,得到的不是自己的需求
多表查询
1. 连接:1、左连接(left join) 2、右连接(right join) 3、内连接(inner join) 内连接其实就是where 4、交叉连接(cross join)
2.左连接: 会查询出左表(表1)的所有的数据,就算右表(表2)没有与左表对应的
3.左连接: 语法: select 字段 from 表1 left join 表2 on 表1.字段=表2.字段 where uid > 2 group by
4.内连接:
selectname,sex,city,u.id,create_time from orders as o inner join user as u ono.uid=u.id
inner joinuser_detail d on u.id = d.uid;
字段要求:不管左还是右,主表对应的字段字段要是两个表都有的话要加是哪个表的即表名.字段名,或者全部加上要加上。
子查询
1.子查询这种方式where条件字段要和查询字段对齐
select playerno from players where (sex, town) = (
select sex, town from players where playerno = 100);
2.获取到所有罚过款的球员信息(重点)
selectplayerno from penalties;//1,2,3,4
select * from players where playerno in(1,2,3,4);
select * from players where playerno in( select playerno from penalties);
3.获取和100号球员性别相同并且居住在同一城市的球员号码
select playernofrom players where (sex,town) = (select sex,town from players where playerno =100 );
Grant权限
//jack用户只能从192.168.32.28登录到数据库服务器去
mysql> grant 权限 on 库名.表名 to 用户名@IP地址 IDENTIFIED BY 密码
grant all onlamp31.* to 'jack'@'192.168.32.28' identified by '123456';
1. 这里是在linux的主机192.168.32.128设置了一个用户可以通过192.168.32.28的主机来访问我192.168.32.128这台主机的数据库。
2. 那么用户jack可以在192.168.32.28这台机子上连接192.168.32.128的数据库
mysql -ujack -p123456-h192.168.32.128;
权限:All所有
select只能查询。。。
3. 修改用户密码
set password for '用户名'@'ip'=PASSWORD('123456');
4. 删除用户
drop user '用户名'@'ip'
如: mysql> drop user test@localhost;
5. * 查看用户的权限
grants for '用户名'@'ip'
6.文件放在linux的apache2的www目录下,通过浏览器输入浏览就是通过linux的IP来进行浏览。就不是通过window的ip来使用数据库,而是linux自己的mysql账号。而给自己ip中添加一个不能@本机ip而是应该是localhost。
7.查看mysql的用户账号和ip:
Usemysql;
selectuser,host from user;
MyISAM与InnoDB区别(面试重点)
a.对事务处理支持情况不同
Innodb支持事务处理,MyISAM不支持
b.查询速度不同
在MySQL5.6之前,一般认为MyISAM查询会快。但是在MySQL5.6之后,两个引擎速度相差无
c.存储数据方式不同,产生文件不同
MyISAM引擎产生三个文件,.frm存放表结构,.MYD存放表的数据,.MYI存放表的索引的。
InnoDB引擎产生了一个.frm存放表结构,InnoDB引擎数据都是放在ibdata开头的文件
d.锁机制不同
MyISAM支持表锁,
InnoDb支持行锁、表锁
e.索引支持情况不同
在MySQL5.6之前,只有MyISAM引擎支持全文索引(fulltext),Innodb不支持。
MySQL5.6之后,MyISAM,InnoDB也支持fulltext.
数据库的锁
分类:1. 行锁
行锁:进行某个操作的时候会将某一行、某几行锁住。行锁是影响了一行、或者某几行、有的时候也可能影响一个表。
2. 表锁
表锁:进行某种操作的时候会整个表锁住。
行锁特点: 加锁慢、并发度高、锁定粒度小、消耗大
表锁特点: 加锁快,并发度低
3. 共享锁(读锁)
共享、排他锁:关注的锁的发生时机。
共享锁(读锁):在进行读操作(select)的时候。
共享锁特点:可以一起读,正在读,其他人不能写。读锁不阻塞其他读,阻塞其他写操作。
4. 排他锁(写锁)
排他锁:在进行写操作(update/delete/insert)的时候。 排他锁:写锁阻塞其他读、写。
当我们user表引擎是Innodb, 如果A用户对user表插入了一个数据。 会产生一个写锁,这个写锁的影响范围是一行。与此同时,其他用户不能再写同一行,不能读那一行。
当我们user表引擎是MyISAM, 如果A用户对user表插入了一个数据。会产生一个写锁,这个写锁的影响范围是整个表。 与此同时,其他用户不能再写,不能读。
当我们user表引擎是MyISAM, 如果A用户对user表查询了一个数据。 会产生一个读锁,这个读锁的影响范围是整个表。与此同时,其他用户可以去查询,不能再修改。
当我们user表引擎是Innodb, 如果A用户对user表查询了一个数据。 会产生一个读锁,这个读锁的影响范围是一行。与此同时,其他用户可以去查询,不能再修改那一行,其他行可以改。
Innodb支持的是行锁和表锁,而MYISAM支持的是表锁。在对不同的表引擎的表进行写操作产生的写锁属于不同的锁,innodb的写锁和读锁都是行锁,MYISAM则都是表锁。
事务处理
在代码我们是用了PDO类进行mysql的连接,就会需要使用到里面的方法来进行事务处理
开启事务处理:$pdo->beginTransaction();
进行各种判断,如果失败了就进行回滚处理:$pdo->rollBack();
如果成功了就进行提交:$pdo->commit();
MySQL操作事务的语法:
1. 只有Innodb支持事务
/mysql的事务处理语法
//开启一个事务
mysql> begin
//做保存点
mysql>savepoint 保存点名称
//事务回滚
mysql>rollback
或 回滚到某个保存点
mysql> rollbackto 保存点名称
//事务确认
mysql> commit
写到begin与commit 或 begin与rollback之间的sql语句就是一个事务。
另外开启事务也可以使用 start transaction;事务处理是有限制的:
1. 只能作用于表引擎为innodb的
2. 事务处理对于查询和修改表结构是没有作用的
3. 事务处理只对insert/update/delete有作用
Mysqli的事务处理
预处理
1. 模板:即准备好sql语句用PDO的prepart方法进行发送模板:
a) $sqlTpl = "insertinto(name,pass) values(?, ?)";
b) $sqlTpl = "insertinto(name,pass) values(:name, :pass)";
c) $stmt = $pdo->prepare($sqlTpl);
2. 绑定参数
a.$stmt->bindParam(1,$name); $stmt->bindParam(2,$pass);
b.$stmt->bindParam(‘:name’,$name) $stmt->bindParam(‘:pass’,$pass);
3.进行预处理处理
$stmt->execute();可以不传参数直接处理
$stmt->execute([‘haha’ , ’123’ ]);问号传参进行绑定参数就是一个索引数组
$stmt->execute([‘:name’=>‘haha’ ,’:pass’=> ’123’ ]);冒号传参进行绑定参数就是一个关联数组
3. PDO的调用prepare方法后返回的对象是实例化PDOStatement类后的对象
a) 一开始我们发送模板的时候使用了pdo内的prepare方法
b) 发送模板之后返回的是一个对象PDOStatement类的实例化
c) 绑定参数的bindParam()和execute()都是这个对象的方法。
如何防止SQL注入(面试重点)
1. 利用正则、系统函数过滤、转义掉特殊符号(' " # -- ;)
2. 利用预处理功能
索引
索引分类:
1. 主键索引
2. 唯一索引
a. 唯一索引意味着字段中的值不能有相同的值
b. 唯一的索引所在的列不能为空字符串
c. 唯一索引所在的列可以为null
3. 全文索引
全文索引只能建立在char,varchar,text等字符串类型上,不能建立在int等数字类型上。并且在mysql5.6之前myisam引擎支持全文索引,innodb不支持。但在mysql5.6(包含)后,innodb也支持全文索引
3. 普通索引
创建索引:
一.表建好的时候
普通索引:alter table 表名 add index 索引名(字段1,字段2….)
唯一索引:alter table 表名 add unique 索引名(字段1,字段2…)
主键索引:alter table 表名 add primarykey (id);
全文索引:alter table 表名 add fulltext(字段1,字段2…)
联合索引
user:id name passemail
//联合索引: 两个字段的索引名字相同
alter table user add index idx(pass,email);第二个字段不起效果
☆:联合索引要两个字段,当where使用到第一个字段的时候,这个索引会其效果,用来改变查询类型和降低扫描行数,而第二个字段的索引不起效果,一样是全局扫描
二.建表的时候创建索引
Create table haha(
Id int unsignedauto_increment,
Namevarchar(150),
Primary key(id),
Unique idx_name(name);
Index idx_name(name);
Fulltext (name);
) engine=innodbdefault charset=utf8;
创建索引的时候唯一索引和普通索引要加上索引名,
删除索引
删除普通,唯一,全文索引:
Altertable haha drop index索引名;
删除主键索引
Alter tablehaha drop primary key;
查看索引:
Showindex from 表名G;
知道一句sql语句有没有用到索引:
Descsql语句G;
结果显示:
id:1
select_type:SIMPLE 表只有一条数据几乎不存在的情况
table: user 表名
type: ALL 查询类型:All代表全局扫描
possible_keys: NULL 可能用上的索引
key: NULL 真正用上的索引
key_len: NULL
ref: NULL
rows: 4 扫描行数
Extra:
二进制日志文件:
二进制日志文件以二进制方式记录着是写操作类型(增删改)的SQL语句。
二进制日志文件(binary log)简称:bin-log
* bin-log文件的作用
1. 在数据灾难性恢复
2. 利用bin-log做读写分离
* bin-log文件在哪里
在data目录,以mysql-bin开头都是bin-log文件
* 如何查看bin-log的内容
/usr/local/mysql/bin/mysqlbinlog /usr/local/mysql/data/mysql-bin.000004
/usr/local/mysql/bin/mysqlbinlog /usr/local/mysql/data/mysql-bin.000001--start-position=264 --stop-position=734
* bin-log命令
//查看当前生效的bin-log文件
mysql> show master status;
//生成一个新bin-log文件
mysql> flush logs;
//将所有bin-log清空
mysql> reset master;
二进制日志恢复的实例
1. 在8:00的时候进行了备份
/usr/local/mysql/bin/mysqldump –uroot –ptest –l –F > '/tmp/test201507/sql'
备份test数据库到/tmp/test201507.sql
-l 备份时加锁,在整个备份期间,只允许读操作
-F 即flushlogs 可以重新生成新的bin-log日志文件
2. 查看binglog日志:
mysql>show master status;
3. 产生一个新的bin-log文件,完整备份完成之后,所有对数据库的操作,将会记录到这个新的bin-log文件中
4. 接下来,模拟8:05进行新操作:
mysql> insert into usersvalues(3,'jack');
mysql> update users setname='mary' where id=2;
5. 然后模拟一次误操作,所有数据库被清空:
mysql> delete from users;
6. 准备恢复丢失的数据,开始一个新的bin-log日志(目的是保留需要原来的bin-log日志):
mysql>flush logs;
7. 先恢复到之前的完整备份文件:
mysql –uroot –p test –f <'/tmp/test201507.sql';(这句在linux中敲,不是mysql中。)
8. 接着恢复后面的操作(8:05分),需要从bin-log日志中恢复:
[root@localhost/]#/usr/local/mysql/bin/mysqlbinlogmysql-bin.0000009 --start-position='106' –stop-position='306' |mysql –uroot –p
9.备注:
/usr/local/mysql/bin/mysqlbinlog 使用mysql提供的mysqlbinlog命令
--start-position 代表开始的位置
--stop-position 结束的位置,只会将开始位置和结束位置之间的SQL语句拿到
数据库优化:
建表需要注意的优化的一些建议:ie小数预三段!
1. 建表一般需要遵守数据库三范式,但是很多时候都需要打破范式,以达到以空间换取时间效果。
2. 一个表的字段个数尽量不要超过50个,尽量将字段类型比较大,不常用的字段划分到其他表
3. 为了考虑到项目扩展性,一般给每个表预留几个字段
4. 字段类型尽量选择更小,但是也要考虑到扩展性
5. 字段类型尽量选择数字类型
6. 表引擎一般选择innodb
7. 根据表存放的数据来决定选择哪种字符集。一般选择是utf8,如果想要存放emoji表情,那么字符集需要使用utf8mb4
SQL语句优化 l*l冗索运子
1. 尽量不要使用*,只查需要的字段
2. 尽量给每条查询SQL语句加上LIMIT,减小传输数据的大小
3. 尽量根据索引来检索数据
4. 适当冗余字段,减少在查询SQL语句使用多表查询
5. 尽量减少在SQL语句中使用MySQL函数、做运算
6. 尽量减少使用LIKE,因为LIKE会导致全表扫描
7. 避免使用子查询
索引常见用法
* 依据where查询条件建立索引
select a,b from tab a where c= ? //应该给c建立索引
* 使用联合索引,而不是多个单列索引
select * from tab where a = ?and b =?
//给(a,b)建立联合索引,而不是分别给a,b建立索引
alter table tab add indexin_ab(a,b);
* 联合索引中索引字段的顺序根据区分度排,区分度大的放在前面
//(name,sex);//将name放前面,因为name的区分度更大。因为sex只有0 1 2 这个三个值。
* 合理创建联合索引,避免冗余
//(a),(a,b),(a,b,c)只要给(a,b,c)建立索引就行
* order by 、group by 、 distrinct字段添加索引
用不到索引的情况(避免) L联函数 o o o o
* 字段使用函数,将不能用到索引
select createtime from aa wheredate(createtime) = curdate();
//where后面的字段(createtime)使用函数,将不会使用到索引。
* 用数字当字符类型,数字一定要加引号
select * from user where name =123 //这SQL语句用不到name索引
select * from user where name ='123' //这样写才会用到name字段上的索引
* 在使用like关键字进行查询的语句中,如果匹配字符串的第一个字符为"%",索引不会起作用。
//用不到索引的
desc select* from t where name like "%j%"G;
//用到索引
desc select* from t where name like"j%"G;
* 联合索引,只有查询条件中使用了这些字段中第一个字段时,索引才会被使用
create index in_name onuser(name,email)
explain select * from userwhere name = 'jack'; //用到索引
explain select * from userwhere email = 'jack@qq.com'; //用不到索引
* 使用OR关键字的查询语句
* 查询语句的查询条件中只有OR关键字,且OR前后的两个条件中的列都是索引时,查询中才使用索引。否则查询将不使用索引。
* order by 的字段混合使用asc和desc用不到索引
select * from user order by iddesc,name asc;
* where 子句使用的字段和order by 的字段不一致
select * from user where name ='jack' order by id;
* 对不同关键字使用order by 排序
select * from user order byname,id;
PDO与mysqli:
主从配置之前的克隆虚拟机步骤: