zoukankan      html  css  js  c++  java
  • 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

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


  • 相关阅读:
    java集合(5)-List集合
    String.matches()的用法
    1.在配置XML文件时出现reference file contains errors (http://www.springframework.org/schema/beans/...解决方案
    SVN教程(包括小乌龟) 全图解
    刚刚进公司不会SVN 菜鸟感觉好蛋疼-----------SVN学习记
    第二部分初始阶段 第六章 用例
    第二部分初始阶段 第五章 进化式需求
    SQL中分页与distinct冲突解决方案
    Java项目打war包的方法
    H5不能少的功能-滑动分页
  • 原文地址:https://www.cnblogs.com/hoewang/p/10257288.html
Copyright © 2011-2022 走看看