• MySQL基础学习


    MySQL数据库基础知识

    一,数据库的安装,连接

       官网下载:https://www.mysql.com/downloads/  下载最新版本和其他所需插件

        数据库安装有两种方式

          1,在windows下使用安装包直接安装,在安装过程中,软件会自动配置好环境变量,图形界面。软件自动检测系统环境是否完整,在发现不完整后会自动安装所需组件,只要傻瓜式的点击下一步就可以安装完成。

          2,使用zip压缩包进行安装:  1):官网下载zip包,解压到自定义文件。

                        2):打开解压后的文件,进入bin目录下,在文件下有 mysqld  ,mysql两个文件

                       (mysql数据这类软件都是基于socket C/S模式进行操作的,所以在安装之前我们要分清客户端与服务端软件,先安装服务端(mysqld),再打开客户端使用(mysql))

                        3):复制bin文件路径,打开命令行窗口,粘贴路径,进入bin目录下。

                        4):使用命令   mysqld --initialize-insecure命令,初始化数据库,安装服务端(如果数据库安装不成功,到安装文件目录下确认是否有data这个文件夹,有些安装不成都是因为在解压后就已经存在data目录,数据库在初始化时不成功,导致无法启动,需要删除重新使用命令 mysqld --initialize 进行初始化操作)

                        5):在初始化安装后,配置环境变量,将bin目录文件路径添加到windows环境变量中。

                        6):安装windows启动服务,使用命令 mysqld --install(此处没有添加成功,可以把bin文件路径添加后再安装服务)

                        7):使用命令 net start MySQL 启动服务(启动不成功的,需要重启一下系统)

                        8):启动命令行窗口,使用命令mysql -u root -p 连接服务端。(mysql初始化有一个root用户,密码为空)

     二,MySQL数据库基本操作

      使用数据库我们需要连接登录,在数据库初始化时会自动创建一个root用户,我们也可以自己创建用户,方便数据的使用,维护。

    创建用户:

        create user "username/用户名"@“指定的ip主机”  identified by '123123';

        (在指定ip地址主机的时候可以使用 % 匹配任何主机

    设置用户权限:

         grant select,insert,update  on db1.t1 to 'alex'@'%';(设置该用户权限为增,查,改)


                grant all privileges  on db1.t1 to 'alex'@'%'; (设置该用户超级用户,用户完整的表操作权限)

         revoke all privileges on db1.t1 from 'alex'@'%';(去除该用户的用户权限)

    数据库的基本操作

        1,显示数据库信息,显示数据表名  show命令

            show databases        :显示数据库名称

            show tables         :显示数据表名 

        2,数据库的创建,使用,操作

            使用:

              use 数据库名        :进入该数据库

            创建:

              create database 数据库名     :创建数据库

                  在创建数据库的时候需要指定字节编码,default charset="编码格式",推荐使用utf8

            删除:

              drop database 数据库名    :删除数据库

        3,数据表操作

            创建:

              create table 表名 (

                        列名1 int auto_increment primary key not null ,

                        列名2 char(10)

                            )engine=innodb default charset="utf8"     :创建数据表

                  auto_increment 自增键,该列数值会随着行数的增加而进行加操作,一般都设置为行ID

                  primary key      设置该列为主键,主键就是一种索引,可以加速数据的查找

                  在创建数据表的时候也需要指定字节编码,default charset="编码格式",推荐使用utf8,同时需要创建事务 engine=innodb 操作回滚

                  innodb:数据库引擎,事务操作,对关键数据的改增,在发生意外后,有回滚操作

                  default charset  :指定字节编码

            清除:

              delete from tablename    :清空数据表数据

              truncate table tablename   :清空数据表及自增量数值归零

                在设置自增列,清空数据表后,自增量不会改变,插入数据会根据已增加量为起始值进行自增,所以需要truncate清空自增量

            删除:

              drop table 表名    :删除表

        4,数据行操作

            查看:

              select * from tablename           :查看数据表所有行内容

              select * from tablename where 列名 表达式  :带条件查看符合的行数据

              select 列名 from tablename              :只显示该指定列数据

              select 列1,列2 from tablename        :查询该表的多列数据

              增加:

              insert into tablename  (列名1,列名2)   value(数值1,数值2)

              insert into tablename  (列名1,列名2)   values(数值1,数值2),(数值3,数值4)   这句与上一句的区别在于可以一次插入多行数据。

            修改:

              updata tablename set 列名=更新的数值

              updata tablename set 列名=更新的数值 where 列名+条件表达式

            删除:

              delete from tablename  where 列名+条件表达式

        5,数据表的关系操作

           主键:

        主键是索引的一种,并且是唯一性索引,且必须定义为primary key。一个表只有一个主键,主键可以由多列组成。

        声明主键的关键字为:primary key

    简单的一个声明主键的示例:

    create table score(sid int auto_increment primary key)engine=innodb default charset=utf8    
    primary key为声明的关键字。

      外键

        如果一个实体的某个字段指向另一个实体的主键,就称为外键。

        被指向的实体,称之为主实体(主表),也叫父实体(父表)。
        负责指向的实体,称之为从实体(从表),也叫子实体(子表)。

      作用:用于约束处于关系内的实体。增加子表记录的时候,是否有与之对应的父表记录,如果主表没有相关的记录,从表不能插入。

    外键示例代码:

    #创建被关联的子表
    create table class(cid int auto_increment primary key,clname char(20))engine=innodb default charset=utf8;
    #插入数据
    insert into class(clname) values("三年级"),("一年级"),("四年级"),("二年级");
    
    #创建主表(父表)
    create table student(sid int auto_increment primary key,sname char(12), class_id int,constraint fk_id_class foreign key(class_id) references class(cid))
    engine=innodb default charset=utf8;
    #constraint fk_id_class foreign key(class_id) references class(cid)关键词,foreign key后跟父表列名,reference后加子表列名。
    insert into student(sname,class_id) values("stu1"),("stu2"),("stu3");

     外键变种:

    外键与主键都有唯一索引,且都不能重复。区别就是主键不能为空,外键的唯一索引可以为空。

    外键变种分为以下几种关系:

    一对多,一对一,多对多

    1,一对一关系:

                    create table userinfo1(
                        id int auto_increment primary key,
                        name char(10),
                        gender char(10),
                        email varchar(64)
                    )engine=innodb default charset=utf8;
    
                    create table admin(
                        id int not null auto_increment primary key,
                        username varchar(64) not null,
                        password VARCHAR(64) not null,
                        user_id int not null,
                        unique uq_u1 (user_id),#关键字,指定外键的一对一关系
                        CONSTRAINT fk_admin_u1 FOREIGN key (user_id) REFERENCES userinfo1(id)
                    )engine=innodb default charset=utf8;

    2,一对多关系

    3,多对多关系

    create table userinfo2(
                        id int auto_increment primary key,
                        name char(10),
                        gender char(10),
                        email varchar(64)
                    )engine=innodb default charset=utf8;
    
                    create table host(
                        id int auto_increment primary key,
                        hostname char(64)
                    )engine=innodb default charset=utf8;
    
    
                    create table user2host(
                        id int auto_increment primary key,
                        userid int not null,
                        hostid int not null,
                        unique uq_user_host (userid,hostid),#关键字,指定为多对多的关系语句
                        CONSTRAINT fk_u2h_user FOREIGN key (userid) REFERENCES userinfo2(id),
                        CONSTRAINT fk_u2h_host FOREIGN key (hostid) REFERENCES host(id)
                    )engine=innodb default charset=utf8;

    数据表的操作:

    插入,修改,选择,删除数据:

       

    #一次插入多条数据的方式:
    insert into student(sname,class_id) values("stu1"),("stu2"),("stu3");
    
    #修改表内数据
    update student set sname="stu10"
    
    #操作显示表数据
    select sid,sname from student;#显示学生表的id与学生名字
    select sid,sname from student where sid>3;显示表中sid大于3,的学生id与姓名
    
    #删除表数据
    delete from student where id=1;#删除表中id为1的数据

      where条件语句

      where:条件限制语句,在数据操作中需要对数据进行按条件筛选,就需要用到where语句。在使用时徐注意:

          where函数条件后不允许加聚合函数条件

      语法:  where 条件表达式

        条件表达式的运算符

    模糊匹配的关键字   like

    模糊匹配补充 _下划线   指的是该字符之后的一个任意数值,示例:where username like"a_"

    自增数据操作

      在数据表的会经常设置自增数据,自增数据是可以对其进行修改查看等操作的。由于mysql的步长是基于会话操作的,每次修改针对的是每一个会话而不是全局,如果需要对全局进行修改要是global

      查看:

     show session variables like 'auto_inc%';
    +--------------------------+-------+
    | Variable_name            | Value |
    +--------------------------+-------+
    | auto_increment_increment | 1     |
    | auto_increment_offset    | 1     |
    +--------------------------+-------+
    2 rows in set, 1 warning (0.00 sec)

      修改自增步长:

     set session auto_increment_increment=2;
    Query OK, 0 rows affected (0.00 sec)
     show session variables like 'auto_inc%';
    +--------------------------+-------+
    | Variable_name            | Value |
    +--------------------------+-------+
    | auto_increment_increment | 2     |
    | auto_increment_offset    | 1     |
    +--------------------------+-------+
    2 rows in set, 1 warning (0.00 sec)

     全局查看:

    全局查看是基于关键字global。

    设置全局步长值:set global auto_increment_increment=2;

     show global variables like 'auto_inc%';
    +--------------------------+-------+
    | Variable_name            | Value |
    +--------------------------+-------+
    | auto_increment_increment | 1     |
    | auto_increment_offset    | 1     |
    +--------------------------+-------+
    2 rows in set, 1 warning (0.00 sec)

    索引:

      作用:约束,和加速查找

      索引有以下几种:

          主键索引:加速查找,主键不能为空且不能重复

          普通索引:加速查找

          唯一索引:加速查找,且键值不能为空

          联合索引(多列组合)

                联合主键索引

                联合唯一索引

                联合普通索引

          全文索引:对文本的内容进行分词,进行搜素。

      数据表无索引的时候,数据行从前到后一次查找,速度相对较慢

      当数据表有索引时,查找速读快,但是对于表的增删改会减慢速度,因为在建立索引的时候会建立一张索引表,在对表进行增删改的操作时,需要对索引文件进行操作。

        索引的种类:

              hash:哈希索引,特点时速度快,但是对于范围文件的查找,速度较慢

              btree:二叉树,索引文件的建立查找会以二分形式树形结构向下发展

      索引的建立可以加速数据的查找,1,使用额外的文件保存特殊的数据结构

                     2,查询快,插入更新删除慢(因为额外的文件需要操作)

                     3,命中索引

      索引建立:

          主键索引: primary key 

          普通索引:create index 索引名称  on 表名(列名)

               删除索引:

                    drop index 索引名称 on 表名

          唯一索引: create unique index 索引名称 on 表名(列名)

               删除索引:

                    drop unique index 索引名称 on 表名

          组合索引(遵循最左前缀匹配):

              create unique index 索引名称 on表名(列名1,列名2)

              删除索引:

                  drop unique index 索引名称 on 表名(列名1,列名2)

              最左前缀匹配的概念实操:

                建立一个组合索引:

                  create index  索引名称 on 表名 (name,email)

                  例子1  select * from 表名 where name=“alex”(符合最左前缀匹配,在查找时可以加速查找)       

                  例子2  select * from 表名 where name=“alex” and email="1234@qq.com"(符合最左前缀匹配)

                  例子3  select  * from 表名 where email='1234@qq.com';(这种查询方式不符合最左前缀匹配的规则,无法加速查找)

          索引合并:

               索引合并中的索引列,每一个都可以单独使用,没有规则限制,但是索引合并的效率要小于组合索引

        名词:

          覆盖索引:

              在索引文件中直接获取数据:

                create index 索引名 on  表名 (id)

                select id from 表名     (直接使用索引名称,获取索引值的方式就叫覆盖索引)

          索引合并:

              把多个单列索引合并使用

      建立索引的原则,就是根据我们的工作需求,去对某列建立索引,频繁使用操作的列应该建立索引

      我们建立了索引,索引会加快我们对数据的查找速度,但是有时候即使我们建立了索引,也会出现速度很慢的情况,这就牵扯了一个索引命中的问题,在什么情况下,我们建立的索引会失效

        1,like   "%ss"      语句中含有模糊匹配

        2,函数,内置函数还有自定义函数     

        3,or 条件语句

            select * from tb1 where nid = 1 or name = 'seven@live.com';

            例外:当or条件中有未建立索引的列才失效

             select * from tb1 where nid = 1 or name = 'seven';
                           select * from tb1 where nid = 1 or name = 'seven@live.com' and email = 'alex'

        4,类型不一致

         列与传入查找的列的数值类型应该相同,不同的话,索引将失效    

        5,!=   在查找语句中,where 条件表达式有不等于操作,索引将失效

            例外:如果该列为主键,查找将走索引

        6,>     select * from tb1 where email > 'alex'      
                       例外:如果是主键或索引是整数类型,则还是会走索引
                            select * from tb1 where nid > 123
                            select * from tb1 where num > 123

        7,order by

          select name from tb1 order by email desc;
                      当根据索引排序时候,选择的映射如果不是索引,则不走索引
                      特别的:如果对主键排序,则还是走索引:
                            select * from tb1 order by nid desc;

        8,组合索引最左前缀

          组合索引为(name,email)

          name and email       -- 使用索引
                     name                     -- 使用索引
                     email                      -- 不使用索引

        索引的目的是为了加快数据库的搜索,所以我们要避免以下操作出现

          1,避免使用select *   尽量不要对全表进行搜索,这样会只会拖慢整体速度,做到按需操作

          2,count(1)或count(列)代替count(*)

          3,创建表时能用char就不要用varchar,对于定长的char,数据库可以很快的对字符进行筛选

          4,表的字段顺序固定长度的字段优先

          5,组合索引代替多个单列索引(在经常使用多个条件查询时)

          6,尽量使用短索引

          7,使用连接来代替子查询

          8,连表时注意条件类型需一致

          9,索引的散列值不适合建立索引

      limit分页操作

       

     select 
            * 
        from 
            tb1 
        where 
            nid < (select nid from (select nid from tb1 where nid < 当前页最小值 order by nid desc limit 每页数据 *【页码-当前页】) A order by A.nid asc limit 1)  
        order by 
            nid desc 
        limit 10;
    
    
    
        select 
            * 
        from 
            tb1 
        where 
            nid < (select nid from (select nid from tb1 where nid < 970  order by nid desc limit 40) A order by A.nid asc limit 1)  
        order by 
            nid desc 
        limit 10;
    
    
    下一页:
    
        select 
            * 
        from 
            tb1 
        where 
            nid < (select nid from (select nid from tb1 where nid > 当前页最大值 order by nid asc limit 每页数据 *【当前页-页码】) A order by A.nid asc limit 1)  
        order by 
            nid desc 
        limit 10;
    
    
        select 
            * 
        from 
            tb1 
        where 
            nid < (select nid from (select nid from tb1 where nid > 980 order by nid asc limit 20) A order by A.nid desc limit 1)  
        order by 
            nid desc 
        limit 10;

     

        执行计划

          explain +查询sql  可以显示sql执行信息参数,根据参考信息可以进行sql优化

          

          图中内容显示该表查询类型为all,全表逐条查询。没有设置主键,没有索引,这张表的速度将会很慢

          

     select_type
            查询类型
                SIMPLE          简单查询
                PRIMARY         最外层查询
                SUBQUERY        映射为子查询
                DERIVED         子查询
                UNION           联合
                UNION RESULT    使用联合的结果
                ...
        table
            正在访问的表名
    
    
        type
            查询时的访问方式,性能:all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const
                ALL             全表扫描,对于数据表从头到尾找一遍
                                select * from tb1;
                                特别的:如果有limit限制,则找到之后就不在继续向下扫描
                                       select * from tb1 where email = 'seven@live.com'
                                       select * from tb1 where email = 'seven@live.com' limit 1;
                                       虽然上述两个语句都会进行全表扫描,第二句使用了limit,则找到一个后就不再继续扫描。
    
                INDEX           全索引扫描,对索引从头到尾找一遍
                                select nid from tb1;
    
                RANGE          对索引列进行范围查找
                                select *  from tb1 where name < 'alex';
                                PS:
                                    between and
                                    in
                                    >   >=  <   <=  操作
                                    注意:!=> 符号
    
    
                INDEX_MERGE     合并索引,使用多个单列索引搜索
                                select *  from tb1 where name = 'alex' or nid in (11,22,33);
    
                REF             根据索引查找一个或多个值
                                select *  from tb1 where name = 'seven';
    
                EQ_REF          连接时使用primary key 或 unique类型
                                select tb2.nid,tb1.name from tb2 left join tb1 on tb2.nid = tb1.nid;
    
                CONST           常量
                                表最多有一个匹配行,因为仅有一行,在这行的列值可被优化器剩余部分认为是常数,const表很快,因为它们只读取一次。
                                select nid from tb1 where nid = 2 ;
    
                SYSTEM          系统
                                表仅有一行(=系统表)。这是const联接类型的一个特例。
                                select * from (select nid from tb1 where nid = 1) as A;
        possible_keys
            可能使用的索引
    
        key
            真实使用的
    
        key_len
            MySQL中使用索引字节长度
    
        rows
            mysql估计为了找到所需的行而要读取的行数 ------ 只是预估值
    
        extra
            该列包含MySQL解决查询的详细信息
            “Using index”
                此值表示mysql将使用覆盖索引,以避免访问表。不要把覆盖索引和index访问类型弄混了。
            “Using where”
                这意味着mysql服务器将在存储引擎检索行后再进行过滤,许多where条件里涉及索引中的列,当(并且如果)它读取索引时,就能被存储引擎检验,
            因此不是所有带where子句的查询都会显示“Using
    where”。有时“Using where”的出现就是一个暗示:查询可受益于不同的索引。 “Using temporary” 这意味着mysql在对查询结果排序时会使用一个临时表。 “Using filesort” 这意味着mysql会对结果使用一个外部索引排序,而不是按索引次序从表里读取行。mysql有两种文件排序算法,这两种排序方式都可以在内存或者磁盘上完成,
            explain不会告诉你mysql将使用哪一种文件排序,也不会告诉你排序会在内存里还是磁盘上完成。 “Range checked
    for each record(index map: N)” 这个意味着没有好用的索引,新的索引将在联接的每一行上重新估算,N是显示在possible_keys列中索引的位图,并且是冗余的。
  • 相关阅读:
    网络安全之数字签名
    python爬取并分析淘宝商品信息
    循环与分支——python
    线性相关与线性无关
    linux之文件传输协议(FTP)与本地用户测试
    递归下降语法分析
    MySQL:索引
    一个基础又很重要的知识点:JDBC原理(基本案例和面试知识点)
    Tomcat的部署、虚拟主机及优化
    二叉树深度
  • 原文地址:https://www.cnblogs.com/lzh1118/p/6953317.html
Copyright © 2020-2023  润新知