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列中索引的位图,并且是冗余的。
原文地址:https://www.cnblogs.com/lzh1118/p/6953317.html