Mysql的使用基础

本文为作者原创,未经允许请勿转载

   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;

MyISAMInnoDB区别(面试重点)

         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;

PDOmysqli

主从配置之前的克隆虚拟机步骤:


原文地址:https://www.cnblogs.com/hoewang/p/10257288.html