zoukankan      html  css  js  c++  java
  • MySQL数据库基础概念

     一、数据库管理软件的由来:

      基于我们之前所学,数据要想永久保存,都是保存于文件中,毫无疑问,一个文件仅仅只能存在于某一台机器上。

      如果我们暂且忽略直接基于文件来存取数据的效率问题,并且假设程序所有的组件都运行在一台机器上,那么用文件存取数据,并没有问题。

    1、程序所有的组件就不可能运行在一台机器上
    #因为这台机器一旦挂掉则意味着整个软件的崩溃,并且程序的执行效率依赖于承载它的硬件,而一台机器机器的性能总归是有限的,受限于目前的硬件水平,就一台机器的性能垂直进行扩展是有极限的。
    
    #于是我们只能通过水平扩展来增强我们系统的整体性能,这就需要我们将程序的各个组件分布于多台机器去执行。

    2、数据安全问题

    #根据1的描述,我们将程序的各个组件分布到各台机器,但需知各组件仍然是一个整体,言外之意,所有组件的数据还是要共享的。但每台机器上的组件都只能操作本机的文件,这就导致了数据必然不一致。
    
    #于是我们想到了将数据与应用程序分离:把文件存放于一台机器,然后将多台机器通过网络去访问这台机器上的文件(用socket实现),即共享这台机器上的文件,共享则意味着竞争,会发生数据不安全,需要加锁处理。。。。

    3、并发 

    根据2的描述,我们必须写一个socket服务端来管理这台机器(数据库服务器)上的文件,然后写一个socket客户端,完成如下功能:

    #1.远程连接(支持并发)
    #2.打开文件
    #3.读写(加锁)
    #4.关闭文件

    总结:

    #我们在编写任何程序之前,都需要事先写好基于网络操作一台主机上文件的程序(socket服务端与客户端程序),于是有人将此类程序
    写成一个专门的处理软件,这就是mysql等数据库管理软件的由来,但mysql解决的不仅仅是数据共享的问题,还有查询效率,安全性等一系列问题
    ,总之,把程序员从数据管理中解脱出来,专注于自己的程序逻辑的编写。

    二 数据库概述 

    1 什么是数据(Data) 

    描述事物的符号记录称为数据,描述事物的符号既可以是数字,也可以是文字、图片,图像、声音、语言等,数据由多种表现形式,它们都可以经过数字化后存入计算机

    在计算机中描述一个事物,就需要抽取这一事物的典型特征,组成一条记录,就相当于文件里的一行内容。

    单纯的一条记录并没有任何意义,如果我们按逗号作为分隔,依次定义各个字段的意思,相当于定义表的标题

    2 什么是数据库(DataBase,简称DB)

    数据库即存放数据的仓库,只不过这个仓库是在计算机存储设备上,而且数据是按一定的格式存放的

    过去人们将数据存放在文件柜里,现在数据量庞大,已经不再适用

    数据库是长期存放在计算机内、有组织、可共享的数据即可。

    数据库中的数据按一定的数据模型组织、描述和储存,具有较小的冗余度、较高的数据独立性和易扩展性,并可为各种 用户共享

    3 什么是数据库管理系统(DataBase Management System 简称DBMS)

    在了解了Data与DB的概念后,如何科学地组织和存储数据,如何高效获取和维护数据成了关键

    这就用到了一个系统软件---数据库管理系统

    如MySQL、Oracle、SQLite、Access、MS SQL Server

    mysql主要用于大型门户,例如搜狗、新浪等,它主要的优势就是开放源代码,因为开放源代码这个数据库是免费的,他现在是甲骨文公司的产品。
    oracle主要用于银行、铁路、飞机场等。该数据库功能强大,软件费用高。也是甲骨文公司的产品。
    sql server是微软公司的产品,主要应用于大中型企业,如联想、方正等。

    4 数据库服务器、数据管理系统、数据库、表与记录的关系(重点理解!!!)

    记录:1 刘海龙  324245234 22(多个字段的信息组成一条记录,即文件中的一行内容)

    表:student,scholl,class_list(即文件)

    数据库:oldboy_stu(即文件夹)

    数据库管理系统:如mysql(是一个软件)

    数据库服务器:一台计算机(对内存要求比较高)

    总结:

        数据库服务器-:运行数据库管理软件

        数据库管理软件:管理-数据库

        数据库:即文件夹,用来组织文件/表

        表:即文件,用来存放多行内容/多条记录

    三 mysql介绍

    MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下公司。MySQL 最流行的关系型数据库管理系统,在 WEB 应用方面MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。

    mysql是什么
    #mysql就是一个基于socket编写的C/S架构的软件
    #客户端软件
      mysql自带:如mysql命令,mysqldump命令等
      python模块:如pymysql

    数据库管理软件分类

    #分两大类:
      关系型:如sqllite,db2,oracle,access,sql server,MySQL,注意:sql语句通用
      非关系型:mongodb,redis,memcache
    
    #可以简单的理解为:
        关系型数据库需要有表结构
        非关系型数据库是key-value存储的,没有表结构

    四 下载安装

    五 mysql软件基本管理

    2. 登录,设置密码

    初始状态下,管理员root,密码为空,默认只允许从本机登录localhost
    设置密码
    # mysqladmin -uroot password "123"        设置初始密码 由于原密码为空,因此-p可以不用
    # mysqladmin -uroot -p"123" password "456"        修改mysql密码,因为已经有密码了,所以必须输入原密码才能设置新密码
    
    命令格式:
    # mysql -h172.31.0.2 -uroot -p456
    # mysql -uroot -p
    # mysql                    以root用户登录本机,密码为空

    3. 忘记密码

    Windows平台下:

    #1 关闭mysql
    #2 在cmd中执行:mysqld --skip-grant-tables
    #3 在cmd中执行:mysql
    #4 执行如下sql:
    update mysql.user set password=password('') where user = 'root' and host="localhost";
    flush privileges;
    
    #5 tskill mysqld #或taskkill -f /PID 7832
    #6 重新启动mysql
     
     

    六 初识sql语句

    有了mysql这个数据库软件,就可以将程序员从对数据的管理中解脱出来,专注于对程序逻辑的编写

    mysql服务端软件即mysqld帮我们管理好文件夹以及文件,前提是作为使用者的我们,需要下载mysql的客户端,或者其他模块来连接到mysqld,然后使用mysql软件规定的语法格式去提交自己命令,实现对文件夹或文件的管理。该语法即sql(Structured Query Language 即结构化查询语言)

    SQL语言主要用于存取数据、查询数据、更新数据和管理关系数据库系统,SQL语言由IBM开发。SQL语言分为3种类型:
    #1、DDL语句    数据库定义语言: 数据库、表、视图、索引、存储过程,例如CREATE DROP ALTER
    #2、DML语句    数据库操纵语言: 插入数据INSERT、删除数据DELETE、更新数据UPDATE、查询数据SELECT
    #3、DCL语句    数据库控制语言: 例如控制用户的访问权限GRANT、REVOKE
    #1. 操作文件夹
            增:create database db1 charset utf8;
            查:show databases;
            改:alter database db1 charset latin1;
            删除: drop database db1;
    
    
    #2. 操作文件
        先切换到文件夹下:use db1
            增:create table t1(id int,name char);
            查:show tables
            改:alter table t1 modify name char(3);
                alter table t1 change name name1 char(2);
            删:drop table t1;
        
    
    #3. 操作文件中的内容/记录
            增:insert into t1 values(1,'egon1'),(2,'egon2'),(3,'egon3');
            查:select * from t1;
            改:update t1 set name='sb' where id=2;
            删:delete from t1 where id=1;
    
            清空表:
                delete from t1; #如果有自增id,新增的数据,仍然是以删除前的最后一样作为起始。
                truncate table t1;数据量大,删除速度比上一条快,且直接从零开始,
    
                auto_increment 表示:自增
                primary key 表示:约束(不能重复且不能为空);加速查找
     
     
     
     

     

    库相关操作

    一 系统数据库

    information_schema: 虚拟库,不占用磁盘空间,存储的是数据库启动后的一些参数,如用户表信息、列信息、权限信息、字符信息等

    performance_schema: MySQL 5.5开始新增一个数据库:主要用于收集数据库服务器性能参数,记录处理查询请求时发生的各种事件、锁等现象 
    mysql: 授权库,主要存储系统用户的权限信息
    test: MySQL数据库系统自动创建的测试数据库

    二 创建数据库

    1 语法(create database)

    charset指定字符编码,数据库的表就会继承库的字符编码。

    create database 数据库名 charset utf8;

    2 数据库命名规则:

    可以由字母、数字、下划线、@、#、$
    区分大小写
    唯一性
    不能使用关键字如 create select
    不能单独使用数字
    最长128位

    三 数据库相关操作

    1 查看数据库
    show databases;
    show create database 数据库名; //根据数据库名查看当初创建数据库怎么创的 
    select database();
    2 选择数据库 use 数据库名;

    3 删除数据库 drop database 数据库名;

    4 修改数据库 alter database 数据库名 charset utf8; //数据库唯一能改的就是字符编码
     
     
     表相关操作

    创建表:

    首先是要切到要创建表的这个数据库:

    use 数据库名;
    建表的完整语法:
    create table 表名(
    字段名1 类型[(宽度) 约束条件],
    字段名2 类型[(宽度) 约束条件],
    字段名3 类型[(宽度) 约束条件]
    );
    中括号内可以不写。
    宽度是字符长度,比如name char(10)意思是最长输入10个字符。
    约束条件:是否为空,唯一,自定增长,是在数据类型条件之上为字段附加的额外的限制。
    注意:
    最后一个字段一定不能加逗号,加了就报错。
    同一张表字段名不能重复。
    宽度和约束条件可以不写,字段名和类型是必须的。

    创建一个表时必须有一个id字段int类型不为空并且不允许重复,不为空且唯一就是在这个字段的数据类型上加的额外的约束。

    create table t2(id int not null unique);
    相当于primary key主键:
    create table t2(id int primary key);
    既然是记录编号,最好每次自己增长:
    create table t2(id int primary key auto_increment,name char(15));
     

    如果没有切换就这么写:

    create table 数据库名.表名 (id int primary key unipue,name char(15));

    查看当前所在的数据库或者文件夹:

    select database();

    查看当前数据库的所有表:

    show tables;

    查看刚刚建的那一个表:

    show create table 表名;

    查看表的数据结构描述信息:

    describe 表名;
    可以简写为:
    desc 表名;

    改表无非是改表的字段

    删除表:

    drop table 表名;
    -------------------------------------------------------------------------------------------------------------------------------
     
    建表字段常用的数据类型:
    一、数值类型
    整型类型:tinyint smallint mediumint int bigint
    作用:存储年龄、登记、id、各种号码等等。
    注意:整型类型后面的宽度限制的是显示宽度。
    浮点型:float double decimal
    作用:存储薪资、身高、体重、体质参数等等。
    注意:decimal的精度最准确
    二、日期类型
    date 2020-4-4
    time 09:30:00
    datetime/timestamp 2020-4-4 09:30:00
    year 2020
    建表语句:
    create table student1 (
        id int primary key auto_increment,
        name char(16),
        reg_time datetime,
        born_year year,
        birth date,
        class_time time
        );
    插入记录:
    insert into student1(name,reg_time,born_year,birth,class_time)values
                        ('zhangrenguo1',20180605,1994,19940113,'08:30:00'),
                        ('yangjing1','2018-6-7',1993,'1993-02-23',083000);
    datetime和timestamp的区别:
        1、datetime日期范围是1001-9999年,timestamp的事件范围是1970-2038年。
        2、datetime存储于时区无关,timestamp存储与时区有关,显示的值也依赖于时区,在MySQL服务器,操作系统以及客户端连接都有时区的设置。
        3、datetime使用8字节存储空间,timestamp使用4字节存储空间。因此timestamp比datetime的空间利用率高。
        4、datetime的默认值时null,timestamp的字段默认不为空,默认值为当前时间(current_time),如果不做特殊处理,并且update语句中没有指定该列的更新值,则默认更新为当前时间。
    datetime和timestamp的区别:
    三、字符串类型
    宽度指的是限制字符个数。
    char:定长
    varchar:变长
    注意:mysql在查询时针对where 字段="值 "会忽略掉右面的空格,即按照where 字段="值"
    如果是like这种模糊匹配就不会右面的空格。

    四、枚举类型与集合类型
    枚举enum可以括号括起来指定一个范围,枚举意思就是从指定的范围中只取一个。多选一。
    集合set从指定范围可以选取多个。多取多。
       建一个员工表:
    create table emp(
        id int primary key auto_increment,
        name varchar(15),
        sex enum('male','female'),
        hobbies set('play basketball','music','travel','read'),
        addr char(20));

       插入记录:

    insert into emp(name,sex,hobbies,addr)values('yangjing','female','music,read','huaian');
     
    表的完整性约束
    创建表的完整语法:
    create table 表名(
        id int primary key unique,
        name varchar(15)
        );
    
    create table 表名(
        字段名1 类型[(宽度)约束条件],
        字段名2 类型[(宽度)约束条件],
        字段名3 类型[(宽度)约束条件]
        );
    约束条件就是在字段的数据类型之外附加的额外条件。
    一、not null和default
    不为空,如果为空设置个默认值:
    create table t3(
        id int primary key auto_increment,
        name varchar(15) not null,
        sex enum('male','female') not null default 'male'
        );
    
    insert into t3(name) values('python'),('django'),('vue');
    二、auto_increment
    三、primary key 主键 在约束角度看就是not null 加 unique
    但凡建表必须要有而且只有一个主键,而主键通常对应为id字段。
    四、foreign key 外键 用来表之间建立关联关系。
    1、被关联的字段必须是一个key,通常是primary key!!
    2、创建表时被关联的必须先被建立起来,才能建立关联表。
    3、插入记录是必须先往被关联的表插入记录,才能往关联表中插入记录。
    4、删除时应该先删除关联表中的记录,才能删除被关联表对应的记录。
    5、修改

    比如员工管理系统
    建员工信息表与部门信息关联起来:
    create table emp(
        id int primary key unique auto_increment,
        name varchar(15),
        age int,
        sex enum('male','female'),
        education varchar(15),
        salary float,
        dep_id int,
        foreign key(dep_id) references dep(id)
        on delete cascade
        on update cascade
        );
    create table dep(
        id int primary key unique auto_increment,
        dep_name varchar(20),
        dep_info varchar(20));
    插入记录:
    insert into dep(dep_name,dep_info)values
        ('it','研发'),
        ('sale','营销'),
        ('hr','人事');
    insert into emp(name,age,sex,education,salary,dep_id)values
        ('zhangrenguo',26,'male','大专',20000,1),
        ('yangjing',27,'female','本科',10000,2),
        ('zhanglin',52,'male','大专',10000,3),
        ('zhufengxiang',53,'female','小学',9000,1),
        ('zhanghaiou',27,'female','大专',15000,1);
    五、unique key   唯一
    联合唯一的写法:unique key (字段1,字段2);




     
    表与表之间的三种关系
    一对多:
      窍门:两张表,先站在左表的角度找左表的多条记录能不能对应到右表的一条记录。再跑到右表的角度去找右表的多条记录能不能对应左表的一条记录。
      怎么实现单向的多对一?  
      在记录多的那个表里新增一个少的表的id字段,该字段外键关联少表的id。
    多对多:
      双向的多对一。
      怎么实现多对多?
      建第三张表,专门放两张表之间的关系。第三张表有一个字段外键一张表,再有一个字段外键另一张表。
    建表:
    create table book(
        id int primary key auto_increment,
        b_name varchar(15),
        price decimal);
    
    create table author(
        id int primary key auto_increment,
        a_name varchar(15),
        age int);
    
    create table author_book(
        id int primary key auto_increment,
        book_id int,
        author_id int,
        foreign key(book_id) references book(id) on update cascade on delete cascade,
        foreign key(author_id) references author(id) on update cascade on delete cascade);

    插入记录:

    insert into book(b_name,price)values
        ('平凡的世界',35),
        ('西游记',36),
        ('水浒传',28),
        ('红楼梦',77);
    
    insert into author(a_name,age)values
        ('张仁国',26),
        ('杨静',27);
    
    insert into author_book(book_id,author_id)values
        (1,1),
        (2,2),
        (3,2),
        (4,1),
        (2,1);
    一对一:左表的一条记录唯一对应右表的一条记录。
      如何实现?
      foreign key + unique
     
     
    修改表alter table
    一、改表名:
        alter table 表名 rename 新表名;
    
    二、增加字段:可以添加多个字段,用逗号隔开,最后一个用分号。
        alter table 表名 add 要添加的字段名 数据类型 宽度 约束条件,
                        add 要添加的字段名 数据类型 宽度 约束条件...
                        add 要添加的字段名 数据类型 宽度 约束条件;
                        
        alter table 表名 add 要添加的字段名 数据类型 宽度 约束条件 first;    first意思是:把这个字段变成第一个字段
          
        alter table 表名 add 要添加的字段名 数据类型 宽度 约束条件 after 字段名;   意思是把这个字段放到某个字段之后。
    
    三、单独删除某个字段:
        alter table 表名 drop 字段名;
        
    四、修改字段:
        alter table 表名 modify 字段名 数据类型 宽度 约束条件;
        
        alter table 表名 change 旧字段名 新字段名 旧数据类型 完整性约束条件;
        
        alter table 表名 change 旧字段名 新字段名 新数据类型 完整性约束条件;

    删表

    把表里的记录都删掉:
    delete from t2;
    
    删表:
    drop table 表名;

    复制表

    拷贝就是把查询结果不打印在屏幕上,放在一张新的表里。
    create table author select * from author;
    
    拷贝表结构:把查询结果写成一个加的,查询结果就是一个表结构没有记录。
    create table author1 select * from author where 3<1 ;
     
     
     
     
     
     
     
     
     
    记录相关操作
     

    一 介绍

    MySQL数据操作: DML

    ========================================================

    在MySQL管理软件中,可以通过SQL语句中的DML语言来实现数据的操作,包括

    1. 使用INSERT实现数据的插入
    2. UPDATE实现数据的更新
    3. 使用DELETE实现数据的删除
    4. 使用SELECT查询数据以及。

    ========================================================

    本节内容包括:

    插入数据
    更新数据
    删除数据
    查询数据

    二 插入数据INSERT

    1. 插入完整数据(顺序插入)
        语法一:
        insert into 表名(字段1,字段2,字段3…字段n) values(值1,值2,值3…值n);
    
        语法二:
       insert into 表名 values (值1,值2,值3…值n);
    
    2. 指定字段插入数据
        语法:
        insert into 表名(字段1,字段2,字段3…) values (值1,值2,值3…);
    
    3. 插入多条记录
        语法:
        insert into 表名(字段名1,字段名2,字段名3,字段名4...字段名n) values
            (值1,值2,值3…值n),
            (值1,值2,值3…值n),
            (值1,值2,值3…值n);
            
    4. 查询插入结果
        语法:
        insert into 表名(字段1,字段2,字段3…字段n) 
        select (字段1,字段2,字段3…字段n) from 表2 where …;

    三 更新数据UPDATE

    语法:
        UPDATE 表名 SET
            字段1=值1,
            字段2=值2,
            WHERE CONDITION;
    
    示例:
        UPDATE mysql.user SET password=password(‘123’) 
            where user=’root’ and host=’localhost’;

    四 删除数据DELETE

    语法:
        DELETE FROM 表名 
            WHERE CONITION;
    
    示例:
      delete from t1 where id >=2;
    

    五 查询数据select

      单表查询:必须要有的关键字如下:select 字段 form 表名;

    完整语法语法级别关键字的排列顺序如下:
        select distinct 字段,字段2...from 表名       distinct去重
                            where 约束条件
                            group by field         按照什么依据分组
                            having 筛选             过滤条件
                            order by field         排序
                            limit 限制条数           显示条数
                            ;
    运行角度关键字先运行:
        from
        where
        group by
        having
        distinct
        order by
        limit
    distinct去重去的是记录的重复,不是字段。
    在字段查询的基础上可以进行四则运算,比如算年薪。
    可以给字段起别名,as可写可不写。
        select name salary*12 as yearly_salary from emp;
        select name salary*12 yearly_salary from emp;
    可以自定义样式,字符串拼接用concat:多用于数据库迁移时。
        select concat('年龄:',name)concat('年龄',age)from emp;
        select concat(name,':',age)from emp;
        select concat_ws(':',name,age,sex)from emp;  concat_ws自动以:为分隔符进行拼接。
    结合case语句:流程控制。
    where关键字约束:
        where字句中可以使用:
            1、比较运算符 > >= < <= !=
                select * from emp where id >=10 and id<=20;
            2between and ;    在什么与什么之间
                select * from emp where id >=10 and id<=20;
                select * from emp where id between 10 and 20;
            3in      在里面
                select * from emp where id =10 and id = 15 and id =20;
                select * from emp where id in (10,15,20);
            4like '%'       任意一个字符
               like '_'       任意单个字符
            5、逻辑运算符 and or not
    group by 分组:
        什么是分组:按照所有记录相同的属性进行归类。一定是区分度比较低的字段
        为什么要分组:当我们要以组为单位进行统计时就必须分组,比方说统计每个部门的最高工资。
        分组是在where之后发生的。
    
    select * from emp group by dep;
    分组之后只能查到分组的字段以及组内多条记录聚合的成果。
    聚合函数:
        max
        min
        avg
        sum
    
    先确定表在哪?再确定有没有where?然后看需不需要分组?
    select dep avg(salary) from emp where age>=30 group by(dep);
    
    group_concat:组相关的拼接,
    select dep group_concat(name,':',age) from emp group by(dep);
    having 过滤条件
        having是在分组之后的过滤,即在分组之后专门针对聚合的结果进行进一步的筛选。
        where是在分组之前的过滤,即在分组之前做了一次整体性的筛选。
    
    
    select dep from emp group by dep having avg(salary)>10000;
    order by 排序
        可以直接排序默认是升序排序asc。
        降序 desc
        可以写多个,先按照年龄升序排列。如果年龄相同在按照薪资升序或降序排,用逗号隔开即可。
    limit 限制显示的条数。
        可以做分页显示的功能。
        select * from emp limit 0,5;    从0开始往后取5条。 再查就是从5开始往后查5条: select * from emp limit 5,5;
    正则表达式:regexp

     

     

      多表关联查询:

    多表关联查询:分析清楚查询需求跟哪几张表有关系,先用连接的方式把几张表连接到一张大表,再基于这一张大表用where、group by...当成单表去查。
        笛卡尔积:将左表的每一条记录跟右表的所有记录全部建一个对应关系。
            写法:
                select * from emp,dep;
                select * from emp,dep where emp.dep_id = dep.id;
                select * from emp,dep where emp.dep_id = dep.id and dep.dep_name = "it";
    
        联表操作:
            1、内连接:只取两张表有对应关系的记录。
                写法:on是连表的条件。
                    select * from emp inner join dep on emp.dep_id = dep.id;
                    select * from emp inner join dep on emp.dep_id = dep.id where dep.dep_name="it";
            2、左连接:在内连接的基础上保留左表没有对应关联关系的记录。
                写法:
                    select * from emp left join dep on emp.dep_id = dep.id;
            3、全连接:在内连接的基础上保留左右表没有对应关联关系的记录。
                写法:
                    select * from emp left join dep on emp.dep_id = dep.id
                    union
                    select * from emp right join dep on emp.dep_id = dep.id;
            4、右连接:在内连接的基础上保留右表没有对应关联关系的记录。
                写法:
                    select * from emp right join dep on emp.dep_id = dep.id;
    
    
    
    多张表怎么实现连表?
        两两之间连,连完之后,再跟第三或者第四张表连。可以把一条查询语句放到一个括号里,然后可以把这个括号当做另外一个查询语句的条件去用,或者可以把这个查询结果当做一张表去用。
    
    
    
    子查询:指的是把一个查询语句的结果用括号括起来,当做另外一个查询语句的条件去用。
        写法:
            当做调价:
            select id from dep where dep_name="it";
            select * from emp where dep_id = (select id from dep where dep_name="it");
    
            select id from dep where dep_name="it" or dep_name="hr";
            select * from emp where dep_id in (select id from dep where dep_name="it" or dep_name="hr");
    
            当做一张表:
            (select id from dep where dep_name="it" or dep_name="hr") as t1;
            select * from t1;
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    视图
     
     
     
     
     
     
     
     
     
     
    触发器
     
     
     
     
     
    事务
     
     
     
     
    存储过程
     
     
     
     
     
    函数
     
     
     
     
     
     
    流程控制
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    222 
     
     
     
     
     
     
     
     
     
     
     索引原理与慢查询优化
    一、介绍
      1、完整的查询sql语句:
        1、完整的查询sql语句:
        select distinct 字段名... from 表名 where 条件
                                group by 分组
                                hvaing 筛选
                                order by 排序
                                limit 显示条数
                                ;
      2、写一个基于网络通信的软件,但凡涉及永久保存数据就一定要用到数据库。对数据库的操作无非两类,一是写(一般写没有效率问题),二是查。
        3、查询过程:
    1、Python的应用程序作为客户端基于网络向mysql服务端发送了一条sql语句
    2、mysql服务端接收到这条指令后,解析sql语句,找到sql语句中的库和表,打开它本地的文件,把数据开始往内存读。
    3、读好了再沿着网络发给应用程序。

      4、基于数据可以优化的两点:

        a、优化网速

        b、mysql服务端如何更精准的定位到客户端要找的符合条件的那些数据,以更少的io从mysql服务器那台机器上的本地硬盘里把数据读到内存里。

      5、如何精准找到那一块内容?
          生活中比如书的目录。
     
      6、什么是索引?
        索引在mysql中也叫做"键",是存储引擎用于快速找到记录的一种数据结构。
    primary key    
    unique key       
    index key      

      7、加索引怎么加?

        按id条件查,就给id字段加索引。

        一张表有很多字段怎么加?

          只给比较常见的查询字段加索引。不然的话索引是建在硬盘里的,会增加io。

      应该对哪些字段做索引?

        1、应该对数据量小的字段做索引

        2、应该对区分度高的字段做索引

        3、索引字段不要参与运算

      索引遵循最左前缀匹配原则!!

    二、索引的原理
      本质就是:通过不断地缩小查询范围来减少查询次数从而提高查询效率。
    通过不断地缩小想要获取数据的范围来筛选出最终想要的结果,同时把随机的事件变成顺序的事件,也就是说,有了这种索引机制,我们可以总是用同一种查找方式来锁定数据。

      了解一下什么是磁盘io与预读。

    三、索引的数据结构
      索引的数据结构就是b+树的结构。
     
    每一个节点就是每一个浅蓝色的块称之为磁盘块,做一次io(从硬盘读取)就读入一个磁盘块。
    一个磁盘块里面深蓝色的称之为数据项,黄色的称之为指针。
    根节点17和35是存的数据项(即存的什么样的数据)。
    根节点p1,p2,p3代表的意思是,p1代表的意思是比17小的那个磁盘块,p2代表的意思是17到25之间的磁盘块,p3代表的意思是大于35的磁盘块。
     
    b+树只有叶子节点才存放真正的数据。其中根节点和树枝节点它们都是为了建立这种树形结构而帮你算出来的一些虚拟的数据。
     
     
    对空间较小的字段加索引!!!
     
     
    四、聚集索引与辅助索引
    索引分为两大类:聚集索引和辅助索引
      聚集索引和辅助索引的相同点:
      聚集索引和辅助索引的不同点:
     
    聚集索引是什么?
      主键,innodb存储引擎必须建主键,通常主键是id字段。
      特点:叶子节点上会存放一整条记录。这条记录完整的信息都放在叶子节点上。
     
     
    辅助索引是什么?
      除了聚集索引之外的全是辅助索引。
      特点:叶子节点只放辅助索引的值以及这个值所在的这条记录的主键的值。
     
      覆盖索引:查询条件和查询结果是一致的。
     
     
     
     
    创建索引
    create index 
    起一个名
    idx_id
    针对哪个表
    on emp
    针对表里哪个字段
    (id)
    结束;
    完整:
    create index idx_id on emp(id);

    建索引速度非常慢。

    删索引:

    drop index idx_id on emp;
     
    五、mysql索引管理
     
     
     
     
     
    六、测试索引
     
    是不是针对字段加上索引就完事大吉了?
    1、在没有索引的前提下测试查询速度
      很慢
    2、在表中已经存在大量数据的前提下,为某个字段建立索引,建立索引速度会很慢
    3、在建立完毕后,以该字段为查询条件,查询速度提升明显
    4、有索引的情况下,大范围查询依旧很慢
    5、模糊查询也很慢
    6、如果查询的字段不是索引字段依旧很慢
     
     
     
     
     
    七、正确使用索引
     
    1、索引未命中
      范围问题
      
     
     
     
    八、联合索引与覆盖索引
     把你优先匹配的可以将范围缩小的那个字段放在最坐标,依次排列。
     
     
    九、查询优化神器 explain
     
     
     
    十、慢查询优化的基本步骤
     
     
     
     
    十一、慢日志管理
     
     
     
     
     
     
     
     
     
     
     
     
     
    11
  • 相关阅读:
    LintCode 17.子集
    JS时间操作
    Ajax总结
    Ajax请求文件下载操作失败的原因和解决办法
    遍历Map的几种方式
    java获取文件大小的方法
    Ajax详细介绍
    第31课
    30-React JSX IN DEPTH
    28-React state提升、组件组合或继承
  • 原文地址:https://www.cnblogs.com/zhangrenguo/p/9995740.html
Copyright © 2011-2022 走看看