关于数据库管理系统DBMS--关系型数据库(MySQL/MariaDB)

数据库的结构(3种):层次,网状,关系型(用的最多);

DBMS的三层模型:
    视图层;面向最终用户;
    逻辑层;面向程序员或DBA;
    物理层;面向系统管理员;

关系型数据库管理系统——RDBMS:
    主要的组成部分是表;表是由行(实例,实体,记录)和列(字段,域)组成;

关系型数据库管理系统的实现:
    商业方案:Oracle,Sybase{为微软提供了思路出现SQL-server},Infomix{IBM收购},DB2{IBM}
    开源方案:PostgreSQL,mysql,MariaDB

SQL:Structured Query Language,结构化查询语言;
ANSI(美国国家标准协会): 1986年定义SQL系列标准,89年实施:
    SQL-86(草案)、SQL-89、SQL-92、SQL-99、SQL-2003(现在使用的标准)

关于{RDBMS(关系型数据库管理系统)设计范式基础概念

设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。

目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴德斯科范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。满足最低要求的范式是第一范式(1NF)。在第一范式的基础上进一步满足更多规范要求的称为第二范式(2NF),其余范式以次类推。一般说来,数据库只需满足第三范式(3NF)就行了。

  (1) 第一范式(1NF)

      所谓第一范式(1NF)是指在关系模型中,对域添加的一个规范要求,所有的域都应该是原子性的,即数据库表的每一列都是不可分割的原子数据项,而不能是集合,数组,记录等非原子数据项。即实体中的某个属性有多个值时,必须拆分为不同的属性。在符合第一范式(1NF)表中的每个域值只能是实体的一个属性或一个属性的一部分。简而言之,第一范式就是无重复的域。

      说明:在任何一个关系数据库中,第一范式(1NF)是对关系模式的设计基本要求,一般设计中都必须满足第一范式(1NF)。不过有些关系模型中突破了1NF的限制,这种称为非1NF的关系模型。换句话说,是否必须满足1NF的最低要求,主要依赖于所使用的关系模型。

  (2) 第二范式(2NF)

      第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或记录必须可以被唯一地区分。选取一个能区分每个实体的属性或属性组,作为实体的唯一标识。

      第二范式(2NF)要求实体的属性完全依赖于主关键字(主键)。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的唯一标识。简而言之,第二范式就是在第一范式的基础上属性完全依赖于主键。

  (3) 第三范式(3NF)

      第三范式(3NF)是第二范式(2NF)的一个子集,即满足第三范式(3NF)必须满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个关系中不能包含已在其它关系已包含的非主关键字信息。简而言之,第三范式就是属性不依赖于其它非主属性,也就是在满足2NF的基础上,任何非主属性不得传递依赖于主属性。

}

NoSQL:Not-Only SQL,反关系型数据库;         //针对关系型数据库提出
    Memcached、Redis:键入值,并将数据存储在内存中,查询效率极高
    MangoDB:完成数据库切片
    Hbase:配合大数据,文档型数据库用来存放大型数据

MySQL:http://www.mysql.com
MariaDB:http://mariadb.org  主流的发行版本有两个:5.5.x 和 10.x.y
Percona XtraDB/MySQL:https://www.percona.com

MySQL/MariaDB:
C/S架构,客户端/服务器架构形式:
客户端工具:
命令行工具:mysql, mysqladmin, mysqldump, ...
图形工具:phpMyAdmin, SQLyog, navicot, ... 
服务器端程序:
mysqld_safe(默认)、msyqld、mysqld_multi

客户端到服务器端的连接方式:
    1.客户端和服务器端在同一台主机上:
        1) Unix Socket
        2) IPv4 Socket
        3) IPv6 Socket
    2.客户端和服务器端分别在不同主机上:
        1) IPv4 Socket
        2) IPv6 Socket

关系型数据库管理系统:
数据模型:关系模型,这里说的是二维关系
1.表:为了满足范式的设计要求,将一个数据集拆分成多个; //在一个表中,可以没有任何一行,但至少保证有一列;
行:row(实例,实体,记录); //记录数据的特征;
列:column(字段,域); //记录数据的某种属性;
2.视图:view,虚表;包含已知表中的部分列;
3.索引:index,将表中的某一个或某些字段抽取出来,单独将其组织成一个独特的数据结构,以便于提高数据检索效率;
支持B-tree(平衡树)索引{默认使用的索引方式}、hash(哈希)索引、空间索引

如果服务器端的应用程序想要访问数据库,就要有访问数据库的能力,应用程序就需要一个SQL接口,使用SQL语句通过SQL接口发送给数据库管理系统,从而管理数据库。数据库管理系统需要通过存储引擎来存储或删除存储设备中的文件。
SQL接口:计划执行器,分析器,操作求解器,优化器;
    提供了一种能够跟数据库管理系统做交互式操作的接口(1),类似于shell;也可以提供编程功能(2);
        (1)交互式接口功能:通过SQL接口处理SQL语句;
                DDL:Data Definition Language,数据定义语言:CREATE,ALTER,DROP
                DML:Data Manipulation Language,数据操纵语言:INSERT,DELETE,UPDATE,SELECT
                DCL:Data Control Language,数据控制语言:GRANT,REVOKE
        (2)编程功能:变量,函数,循环,选择;
                存储过程:Procedure,使用CALL语句调用;
                存储函数:Function,使用SELECT语句调用;
                触发器(类似条件选择):Trigger;
                事件调度器(Event Schedule);基于事件的条件选择,类似于触发器但基于事件
                例程:Routine,过程 + 函数

**事务**:Transaction,组织多个操作为一个整体,这个整体所包含的所有操作,要么全部都执行,要么全部不执行;只要有任何操作没有被成功执行,则整个事务回滚(Rollback);
    在MySQL中,事务是存储引擎的属性;是否支持事务的判断标准,即:ACID标准(事务四大特性);
        A:Atomicity,原子性(不可分割);
        C:consistency,一致性(执行开始的状态和结束的结果保持一致);
        I:Isolation,隔离性(加锁,多个事务分隔开来不能同时进行);
        D:Durability,持久性(对数据修改结果要不发生变化);

**约束**:Constraint,向数据表中插入的数据必须遵守的限制规则(范式);
    (1.主键约束:
        主键:一个或多个字段构建的能够唯一标识记录的组合;
        主键约束:填入主键的数据,必须不能和已经填写的数据相同,而且不能为空;
    (2.外键约束:也称为"引用性约束";
        外键:一个表中的某个字段和其他表中的字段表达的意义相同;
        外键约束:一个表中的某个字段能插入的数据,取决于另一个表的主键中包含的数据;
    (3.唯一键约束:
        唯一键:一个或多个字段构建的能够唯一标识记录的组合;
        唯一键约束:填入唯一键的数据,必须不能和已经填写的数据相同,但可以为空;
    (4.检查性约束:
        也称为"表达式约束";取决于表达式的书写规范;

关系运算:
    选择:根据指定的条件挑选出符合条件的行;
    投影:根据指定的条件挑选出符合条件的列;
    连接(具有多种连接方式):多表的关联操作;

**数据抽象分布:**
    物理层(最底层):决定数据的存储格式,即:如何将数据组织成物理文件;
    逻辑抽象层(中间层:存储引擎,用来上下两个层次的衔接转换):描述了数据库存储什么样的数据,以及数据之间存在怎样的关系;
    视图层(最顶层):描述了数据库中全部或部分数据,以表的形式进行展示;

关系模型的分类:关系模型、实体-关系模型(E-R模型)、基于对象的关系模型、半结构化的关系模型:XML

MySQL和MariaDB:
共同点:
1.都支持插件式的存储引擎(把存储引擎当做功能模块来使用); //存储引擎就是表类型;
2.MySQL/MariaDB服务端口号:3306/TCP

MariaDB的特性:
    1.相对于MySQL而言,可以包含更多的存储引擎;
        1)MyISAM:检索高效但是不支持事务;
                Aria:增强版的MyISAM,改善了MyISAM中的崩溃处理机制;
        2)InnoDB:支持事务;行级锁;
                Percona-XtraDB:增强版的InnoDB;
    2.诸多的扩展和新特性;
    3.提供了非常多的测试组件;
    4.Truly Open Source(MariaDB的发行机制:真正开源)

MySQL的发行机制(2种):
    Enterprise:企业版,提供了丰富的组件和功能;如:线程池,强大的可视化监控组件等;
    Community:社区版,只有简单的数据库功能

安装MySQL或MariaDB:
1.基于包管理器格式的程序包直接安装,如:rpm包,deb包等;
1) OS发行商在光盘镜像中提供; //版本比较老旧
2) 由程序官方提供;
2.官方提供的通用二进制程序包;直接解压缩程序包即可使用;
3.源代码包:编译安装之前,需要先编译安装cmake

安装命令:
    CentOS 6:yum install mysql-server
    CentOS 7:yum install mariadb-server

MySQL的程序环境:
    服务器端程序:mysql-server(CentOS6), mariadb-server(CentOS7)
        服务启动脚本:
            /etc/rc.d/init.d/mysqld
        常用的二进制文件:
            /usr/bin/mysql_install_db            //做数据库的初始化安装
            /usr/bin/mysql_secure_installation   //做安全初始化安装;对使用的管理员用户做密码设置,默认是空密码;删除空用户和空数据表;只允许root用户本地登录不允许远程登录
            /usr/bin/mysqld_multi          //多实例启动mysql,可以一次启动多个mysql进程,不同的进程监听不同的端口号
            /usr/bin/mysqld_safe          //默认启动safe选项,安全服务进程
        数据目录:
            /var/lib/mysql          //默认的初始化数据库目录,未初始化之前目录中没有内容
        主配置文件:
            /etc/my.cnf       

    客户端程序:mysql, mariadb
        常用的二进制文件:
            /usr/bin/mysql         //客户端连接工具
            /usr/bin/mysqladmin    //非交互式的数据库管理工具
            /usr/bin/mysqlbinlog   //二进制日志的查看和管理工具
            /usr/bin/mysqldump     //温备份工具

主配置文件:/etc/my.cnf
    ini风格的配置文件:在整个配置文件中,以"[]"划分成多个配置段,每个配置指令仅针对于其上方直接归属的"[]"中表示的组件生效;

        在mariadb版本中/etc/my.cnf中添加:
            innodb_file_per_table = ON   //打开对创建或删除表的影响,主要是删除InnoDB存储引擎的表耗用时间应该更长
            skip_name-resolve = ON     //跳过名称解析,不做名称反解
        保存后重启服务(MariaDB版本一般在CentOS7中):systemctl restart mariadb.service   //如果重启不成功,使用 rm -rf /var/lib/mysql/*文件内容清空,因为有其他数据库内容,不能重启数据库

使用rpm包安装的mysql或mariadb的默认配置文件加载顺序:
    /etc/mysql/my.cnf (默认文件不存在)--> /etc/my.cnf(一般默认先加载) --> ~/.my.cnf        //后加载的配置项会覆盖先前配置项,越靠后的文件生效越优先

            在使用mysqld_safe命令启动mysqld服务进程时,可以通过一些选项来更改或附加配置文件的读取顺序;
                -c, --defaults-file=name 
                          Like --config-file, except: if first option, then read
                          this file only, do not read global or per-user config
                          files; should be the first option
            如果在命令行中给出此选项,则此选项必须是第一个选项,此时,仅从此选项指定的配置文件中读取参数值,不会再读取任何其他的配置文件,包括全局的和个人的;

            -e, --defaults-extra-file=name 
                          Read this file after the global config file and before
                          the config file in the users home directory; should be
                          the first option
            如果在命令行中给出此选项,则此选项必须是第一个选项,此时,将所有其他的配置文件按照指定顺序读取完成之后,最后再附加读取此选项指定的配置文件中参数值配置,只要有参数配置冲突,则必然以此选项指定的文件中的参数中为最终生效的参数值;

        配置文件的风格:
            ini风格的配置文件;即:分段式配置文件;
            为MySQL的各应用程序提供与之对应的配置参数信息:
                服务器端应用程序:
                    [server]
                    socket=
                    datadir=
                    basedir=
                    [mysqld]
                    socket=
                    [mysqld_safe]
                    socket=
                    [mysqld_multi]

                客户端应用程序:
                    [client]
                    user=
                    password=
                    host=
                    [mysql]
                    user=
                    password=
                    host=
                    [mysqladmin]
                    [mysqldump]

        配置文件中各参数的定义方法:
            PARAMETER_NAME = VALUE
            PARAMETER_NAME=VALUE
            PARAMETER_NAME

            innodb_file_per_table = ON
            innodb-file-per-table = ON
            defaults-file=/tmp/my.cnf
            defaults_file=/tmp/my.cnf

            skip_name_resolve=ON
            skip_name_resolve

**mysql相关基本命令:
    mysql命令 - 基本的交互式命令行客户端工具;**
    格式:mysql [options] [db_name]
    常用选项:
        --database=db_name, -D db_name
            用于指定使用mysql客户端程序连接到mysql服务器之后,默认使用哪个数据库;如果不给定该选项,默认为NULL;
        --execute=statement, -e statement
            连接至mysql服务器并将后面的SQL语句交给服务器运行之后返回执行结果并直接退出交互式登录模式,返回bash命令提示符;
        --host=host_name, -h host_name
            用于指定此次mysql程序所连接的mysql服务器的主机名称或主机IP地址;默认是localhost(127.0.0.1);
        --user=user_name, -u user_name
            用于指定连接mysql服务器时使用的用户名;默认的用户名为:'root'@'localhost'
                mysql的用户名:USERNAME@HOSTNAME
                    USERNAME表示登录的用户名称;
                    HOSTNAME表示用户通过哪个特定的客户端主机连接到mysql服务器;
                    如:用户'root'@'172.16.0.1':表示只有172.16.0.1主机可以通过root用户连接至myslq服务器;
                        HOSTNAME中可以使用通配符:
                            _:任意单个字符; 
                            %:任意长度的任意字符;
                        如:'root'@'172.16.%.%'
                            表示172.16.0.0/16网段中的所有主机都可以使用root用户连接至mysql服务器;
                        如:'root'@'172.16._.%'
                            表示172.16.0.0~172.16.9.255地址的主机都可以使用root用户连接至mysql服务器;

                    注意:默认情况下,所有用户均为空密码,并且还有匿名用户存在,因此,为了增强安全性,可以使用mysql_secure_installation命令完成账户安全初始化;使得mysql服务器仅能让root用户在本地登录,并且移除匿名用户和test数据库;

        --password[=password], -p[password]
            用于指定连接mysql服务器时,为对应用户指定身份验证所需密码;如果密码部分省略不写,执行命令后需要在新行中给出密码,这种方式相对更安全;

    mysql命令提示符下的交互式命令:
        客户端命令:mysql程序自身完成或执行的命令,在客户端所在地运行;
            clear     (c):停止发送当前正在键入的命令或语句并直接返回提示符;
            delimiter (d):设置语句结束标记;默认的语句结束标记为";";
            ego       (G):将其前面的语句送往mysql服务器运行,并将返回的结果纵线显示;
            go        (g):无需输入语句结束标记,直接将其前面的语句送往服务器执行;
            exit,quit (q):退出mysql程序的交互式模式;
            status    (s):获取mysql服务器的状态信息;
            use       (u):将指定的数据库作为当前正在使用的数据库;
            source    (.):可以在mysql交互式模式中执行SQL脚本文件;
            ?,help    (?):获取客户端命令的帮助信息;
        服务器端命令:mysql客户端程序通过mysql协议向mysql服务器端发送的SQL语句;
            注意:在书写服务器端命令时,每个SQL语句都必须以指定的结束标记结尾,默认是";",修改结束标记的命令为:mysql >d
                服务器端命令代表的SQL语句,可以分为三类:
                    DDL:数据定义语言,主要用于管理数据库及数据库的各组件;
                        组件例如:数据库,表,视图,索引,用户,存储过程,存储函数,触发器,事件等;
                        常用的SQL语句:CREATE,DROP,ALTER,SHOW
                    DML:数据操纵语言,主要用于管理表中的数据,实现数据的增,删,改,查等操作;
                        常用的SQL语句:INSERT,DELETE,UPDATE,SELECT
                    DCL:数据控制语言,主要用于管理数据访问的授权;
                        常用的SQL语句:GRANT,REVOKE

                    获取指定的SQL语句的帮助信息(所有的SQL语句本身,不区分字符大小写;建议使用小写字母书写SQL语句);
                        mysql> help SQL_STATEMENT_KEYWORK    //mysql版本数据库,一般在CentOS6及以前的版本中
                        MariaDB [(none)]> help SQL_STATEMENT_KEYWORK   //MariaDB版本数据库,一般在CentOS7中使用的默认数据库

                    在mysql中,database(数据库)和schema(方案)这两个单词是一样的;

利用mysql客户端工具实现mysql数据库的相关管理操作:
数据库管理:
创建数据库:
格式:CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name [ create_specification ]
create_specification:
[DEFAULT] CHARACTER SET [=] charset_name 
| [DEFAULT] COLLATE [=] collation_name
示例:
创建一个名为mydb的数据库并设定字符集是utf8:
mysql> create database mydb character set = utf8;

        字段含义:
            DATABASE | SCHEMA:表示要创建的对象的类型为"数据库"或"方案";
            IF NOT EXISTS:如果指定要创建的数据库已经存在,则不报错也不执行创建操作;
            db_name:要创建的数据库的名称;
            CHARACTER SET [=] | charset_name:为新创建的数据库指定其默认的字符集;
                示例:mysql> show character set:查看mysql服务器所支持的所有字符集及默认排序规则;
            COLLATE [=] | collation_name:
                为新创建的数据库指定字符集的排序规则;
                示例:mysql> show collation:查看mysql服务器上每种字符集所支持的所有的排序规则;

    修改数据库的属性(如果数据库中已经有表,且表中已经插入数据时,更改数据库的字符集和排序规则可能会导致已存数据的乱码):
        ALTER {DATABASE | SCHEMA} [db_name] alter_specification ...   //要指定数据库名称,否则删除所有存在的数据库
            alter_specification:
                [DEFAULT] CHARACTER SET [=] charset_name :修改字符集
                | [DEFAULT] COLLATE [=] collation_name:修改字符集的排序规则

    删除数据库:
        DROP {DATABASE | SCHEMA} [IF EXISTS] db_name      //加上[IF EXISTS],删除一个不存在的数据库执行但不会报错,如果不加[IF EXISTS]删除一个不存在的数据库会执行然后报错,*一定要指定数据库名称,否则或删除所有库*

表管理(关系型数据库的核心,数据都存储于表中):
    表:二维表,包括行和列;
        行(实体,实例,记录):用来描述某个具体事物的某些属性;对于表来说,表中可以没有任何一行数据,此类表称为"空表";
        列(字段,域):用来定义或描述某个具体的属性的格式或定义方式;对于表来说,没有列的表是无意义的,表中至少要有一列;

            数据类型:
                定义数据类型的意义:
                    1.决定数据的存储格式;
                    2.决定数据所能参与的运算;
                    3.决定数据可以表示的有效范围;

                对于mysql来说,支持的数据类型:
                    数值型:
                        精确数值型:
                            MySQL数据类型    括号中m的值(bits)   有符号范围                                       无符号范围
                            tinyint(m)          1个字节            (-128~127)                                       (0~256)
                            smallint(m)         2个字节                        (-32768~32767)                              (0~65536)   
                            mediumint(m)        3个字节                        (-8388608~8388607)                      (0~1677216)
                            int(m)                  4个字节                        (-2147483648~2147483647)            (0~2147483648*2)
                            bigint(m)               8个字节                        (+-(9.22*10)^18)                            (0~((9.22*10)^18)*2)

                            是否有符号,可以在定义时规定,默认为有符号,可以用unsigned标识来表示无符号
                            通过规定数据的显示宽度,达到统一显示的目的。
                            注意定义格式:alter table tbl_int add c tinyint(2) zerofill;    //需要使用前导零来填充以达到目的:zerofill;其中若数大于显示宽度,则直接显示原数字

                        近似数值型:
                            FLOAT:单精度浮点数
                                示例:一个字段定义为float(5,3),如果插入一个数123.45678,实际数据库里存的是123.457,但总个数还以实际为准,即6位
                            DOUBLE:双精度浮点数

                    字符串型:
                        变长字符型:
                            VARCHAR(length):字符不区分大小写;最大存放65536个字符;
                                VARCHAR(30)
                                    chenliang$ -- 字符只占了VARCHAR总空间30字节大小中的10字节,末尾的$用来表示字符结束并将字符占用VARCHAR空间大小+1,如果空间已满则不显示$
                            VARBINARY(length):字符区分大小写;最大存放65536个字符;
                        定长字符型
                            CHAR(length):字符不区分大小写;256个字符;
                                CHAR(30)
                                    chenliang -- 字符虽然只占了9字节存储空间,但是必须要占用30字节的空间
                            BINARY(length):字符区分大小写;256个字符;

                    对象存储类型(大型的数据用于存储文本块或图像、声音文件等二进制数据类型,比指定类型支持的最大范围大的值将被自动截短):
                        TEXT:存储大量的纯文本信息;
                            TINYTEXT:可最大存放256字节
                            TEXT:可最大存放65536字节
                            MEDIUMTEXT:可最大存放16777736字节
                            LONGTEXT:可最大存放43亿9千万字节
                        BLOB:存储非纯文本信息经过流式化处理之后的二进制数据;
                            TINYBLOB:可最大存放256字节
                            BLOB:可最大存放65536字节
                            MEDIUMBLOB:可最大存放16777736字节
                            LONGBLOB:可最大存放43亿9千万字节

                    日期时间型:
                        类型          名称              大小(字节)           格式   
                        DATE        日期型                     3           YYYY-MM-DD
                        TIME        时间型                 3                     HH:MM:SS
                        TIMESTAMP 时间戳类型             8         YYYYMMDD HHMMSS
                        DATETIME  日期时间型         8       YYYY-MM-DD HH:MM:SS
                        YEAR            年份           2/4            YY/YYYY

                    内置特殊类型:
                        集合类型:
                            SET:集合,插入的数据可以是集合中各个元素的任意组合;
                                SET('a','b','c','d')
                                    a
                                    aa
                                    aab
                                    abdc
                        枚举类型:
                            ENUM:枚举,只能存放列举出来的固定的字符或字符串;
                                ENUM('F','M')
                                    F
                                    M

                数据类型相关的修饰符:
                    与整数类型相关的:
                        UNSIGNED,无符号整数;   //UNSIGNED修饰符必须紧跟在精确数值类型标识符之后;
                        AUTO_INCREMENT [=] Value:
                            整型数据的自动递增或自动递减;
                    通用修饰符:
                        NOT NULL:非空约束;一般是为主键做约束;
                        DEFAULT Value:为字段设置默认值;

    创建表:
        CREATE TABLE [IF NOT EXISTS] tbl_name (create_definition,...) [table_options] 
            create_definition(创建定义项):表中各个列是怎么定义的,列的格式,列的类型
                col_name :列的名称
                 格式:data_type [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY] [COMMENT 'string'] [COLUMN_FORMAT {FIXED|DYNAMIC|DEFAULT}] [STORAGE {DISK|MEMORY|DEFAULT}] [reference_definition]
                        选项:
                            data_type [NOT NULL | NULL]:数据类型 [不为空|空]
                            [DEFAULT default_value]:是否设置默认值为多少
                            [AUTO_INCREMENT]:默认自动增长步长为1
                            [UNIQUE [KEY]:定义唯一键
                            [PRIMARY] KEY]:定义主键
                            [COMMENT 'string']:定义注释内容
                            [COLUMN_FORMAT {FIXED|DYNAMIC|DEFAULT}]:列的格式{静态|动态|默认格式}
                            [STORAGE {DISK|MEMORY|DEFAULT}]:存储方式{磁盘|内存|默认位置}
            table_options:表选项
                ENGINE [=] engine_name | AUTO_INCREMENT [=] value

        示例:
            mysql> create table stu_info (SID tinyint unsigned not null auto_increment primary key,SName varchar(50) not null,SAge tinyint unsigned,Gender enum('F','M'));

        显示表的结构:mysql> desc stu_info;
        显示创建表的SQL语句:mysql> show create table stu_info;

    删除表:
        DROP [TEMPORARY] TABLE [IF EXISTS] tbl_name [, tbl_name] ...
        示例:mysql> drop table stu_info;

    修改表:修改表的各个字段的属性和定义的内容;
        ALTER TABLE tbl_name [alter_specification [, alter_specification] ...]
        增加表的字段:
            ADD [COLUMN] col_name column_definition [FIRST | AFTER col_name ]
                示例:mysql> alter table stu_info add Stel_num varchar(20) not null after SAge;
        修改表的字段属性
            CHANGE [COLUMN] old_col_name new_col_name column_definition  [FIRST|AFTER col_name]
            MODIFY [COLUMN] col_name column_definition [FIRST | AFTER col_name]
                示例:
                    mysql> alter table stu_info change column Stel_num SMobile char(11) not null after Gender;
                    mysql> alter table stu_info modify SAge tinyint unsigned after Gender;
        删除表的字段:
            DROP [COLUMN] col_name       //删除字段的操作可能会引起数据的变化,所以,删除字段时要慎重;
                示例:mysql> alter table stu_info drop SMobile;

数据管理:实质上就是管理表中的数据;
    向表中添加数据:
        INSERT [INTO] tbl_name [(col_name,...)] {VALUES | VALUE} ({expr | DEFAULT},...),(...),...         //如果列名(col_name,...)省略不写,则默认表示为为表的每一列添加数据
        Or:
        INSERT [INTO] tbl_name SET col_name={expr | DEFAULT}, ... 

        示例:
            mysql> insert into stu_info values (1,'tom','M',25),(2,'jerry','F',28);
            mysql> insert into stu_info (SName) values ('Alice'),('James');
            mysql> insert into stu_info set SName='zhangsan',Gender='M',SAge=20;
        注意:
            1.如果向表中插入的value是字符串,则value必须使用引号引用;
            2.如果向表中插入的value是数字,则value一定不能用引号引用;

    查看表中的数据内容:
        SELECT select_expr [, select_expr ...] [FROM table_references] [WHERE where_condition]

        1.显示整张表:
            SELECT * FROM tbl_name;
        2.投影:显示指定的或符合要求的列;
            SELECT col_name AS con_alias[,col_name AS con_alias,...] FROM tbl_name;
            示例:mysql> select Host as Hostname,User as Username,Password as Pass from user;

        3.选择:显示符合要求或匹配条件的行;
            SELECT col_name AS con_alias[,col_name AS con_alias,...] FROM tbl_name WHERE condition;

            WHERE子句用于指明选择时依据的条件:
                col_name 操作符 value

                操作符:
                    1) 比较操作符:>, <, >=, <=, ==, !=
                    2) 逻辑操作符:与:and,或:or,非:not
                    3) 特殊操作符:
                        BETWEEN...AND...
                        LIKE "PATTERN",其中"PATTERN"中可以适当添加通配符,如:%或_;
                        RLIKE "PATTERN",使用正则表达式对字符串进行模式匹配;在使用RLIKE进行数据检索时,索引不生效,检索效率低,速度慢,不推荐使用;
                        IS NULL或IS NOT NULL:判断指定字段是否为空;

                示例:
                    mysql> select * from stu_info where SAge >= 30;
                    mysql> select * from stu_info where SAge >= 10 and SAge <=30;
                    mysql> select * from stu_info where SAge between 10 and 30;
                    mysql> select * from stu_info where Gender is [not] null;
                    mysql> select * from stu_info where SName like '%a%';
                    mysql> select * from stu_info where SName rlike '^j';
                    mysql> select * from stu_info where SName rlike 'e$';

        4.排序:
            SELECT col_name AS con_alias[,col_name AS con_alias,...] FROM tbl_name WHERE condition [ORDER BY {col_name | expr | position} [ASC | DESC], ...]

                示例:
                    mysql> select * from stu_info order by SAge; 默认升序排序;
                    mysql> select * from stu_info order by SAge desc; 降序排序;  //末尾加desc,表示降序

    修改表数据内容:
        UPDATE [LOW_PRIORITY] [IGNORE] table_reference SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ... [WHERE where_condition] [ORDER BY ...] [LIMIT row_count]
        示例:
            mysql> update stu_info set SName='Obama' where SID=5;
            mysql> update stu_info set SAge=SAge+1;
            mysql> update stu_info set SAge=SAge+100 where SID in (1,3,5,7);

        注意:修改数据时,一定要考虑清楚是否要添加where条件子句;如果不写where子句,默认修改全表;

    删除表数据:
        DELETE FROM tbl_name  [WHERE where_condition] [ORDER BY ...] [LIMIT row_count]
        示例:
            mysql> delete from stu_info where SID > 3;
            mysql> delete from stu_info;
        注意:在使用UPDATE和DELETE语句时,除非必要,否则一定要使用WHERE子句或ORDER BY + LIMIT子句来限制要操作的数据;否则即为全表操作;

    mysqladmin命令:
        mysqladmin - client for administering a MySQL server
            常用选项:
                -u, -h, -p, -P, -D, -S
                各选项功能同mysql命令的选项功能;

            常用子命令:
                create db_name:创建数据库;
                drop db_name:删除数据库;
                flush-hosts:清除服务器缓存中所有信息;
                flush-logs:清除日志,让日志滚动;
                flush-privileges:刷新授权表;
                flush-tables:为表加锁;
                password new-password:为指定的用户设置新密码;
                start-slave:在msyql的集群服务中的从节点启动用于实施复制功能的线程;
                stop-slave:在msyql的集群服务中的从节点关闭用于实施复制功能的线程;
                shutdown:停止服务;

    mysqld_safe命令:用于启动mysql服务,定义mysql的工作特性;
        格式:/usr/bin/mysqld_safe [OPTIONS]
            注意:所有给出的 OPTION(--option)都是一次性生效;如果期望配置参数永久有效,需要将此类配置参数及参数值直接定义在配置文件中即可;

            服务器运行时变量/服务器运行时参数:MySQL的运行工作特性;这里特性有两种:
                1.全局特性:
                    在全局范围均有效的服务器参数所配置定义的工作特性;将会作为每个mysql的会话连接的默认特性参数;

                2.会话特性:
                    仅针对于本次mysql的连接会话生效的特性参数;

                查看已经生效的mysql运行参数(特性,变量)
                    SHOW [GLOBAL | SESSION] VARIABLES [like_or_where]

                    示例:
                        show  [global] variables like '%innodb%';
                            查看所有名字中包含innodb字样的服务器参数及参数值;可以一次显示多个;

                        show [global] variables like 'innodb_file_per_table';
                            仅查看指定名称的服务器参数的参数值;

                        select @@[global.]innodb_file_per_table;
                            仅查看指定名称的服务器参数的参数值;

            服务器状态参数/服务器状态变量:MySQL工作时的统计信息;有两种状态参数:
                1.全局
                2.会话

                查看与状态及统计信息相关的参数/变量的值;
                    SHOW [GLOBAL | SESSION] STATUS [like_or_where]

                    示例:
                        show [global] status like '%innodb%';
                            查看所有名字中包含innodb字样的服务器状态参数及其值;可以一次显示多个;

                        show [global] staus like 'Com_select';
                            仅查看指定名称的服务器状态参数的值;

            服务器变量/服务器参数的修改或调整方法:
                1.运行时修改:
                    MariaDB [(none)]> SET [GLOBAL|SESSION] system_var_name = expr;
                    MariaDB [(none)]> SET @@[GLOBAL.|SESSION.]system_var_name = expr;

                    示例:
                        set global innodb_file_per_table=1;
                        set @@global.innodb_file_per_table=0;

                2.永久修改:
                    通过在配置文件中直接书写服务器参数或变量的赋值语句;重启服务即可生效;
                    innodb_file_per_table = ON

    mysql_secure_installation:安全初始化脚本;

**MySQL的用户和权限管理:**
    用户账号:
        'Username'@'Hostname'

        skip_name_resolve = ON
        'user'@'172.16.0.1'

        'user'@'a.qhdlink.com'
        skip_name_resolve = OFF
        Client_IP --> Client_Hostname

    在MySQL上能够实施的用户账户的管理操作:
        CREATE USER
        DROP USER
        GRANT
        RENAME USER
        REVOKE
        SET PASSWORD

    MySQL中的权限类别:管理类;程序类;库级别;表级别;字段级别;

        管理类的权限:
            CREATE USER
            DROP USER
            RELOAD
            LOCK TABLES
            REPLICATION CLIENT
            REPLICATION SLAVE
            SHUTDOWN
            FILE
            SHOW DATABASES
            PROCESS
            SUPER

        程序类的权限:
            FUNCTION
            PROCEDURE
            TRIGGER

            操作:CREATE,ALTER,DROP,EXECUTE

        库级别和表级别的权限:
            CREATE
            ALTER
            SHOW
            DROP

            INDEX

            CREATE VIEW
            SHOW VIEW

            GRANT OPTION:能够将管理员自身获得的权限生成一个副本,并转赠给目标用户;

        表级别的数据操作的权限:
            INSERT
            REPLACE
            DELETE
            UPDATE
            SELECT

        字段级别(列级别)的数据操作的权限:
            SELECT(col1,col2,...)
            UPDATE(col1,col2,...)
            INSERT(col1,col2,...)

        所有的权限:
            ALL
            ALL PRIVILEGES

        MySQL的元数据数据库:mysql
            数据字典数据库;
                host
                db
                user

                column_priv
                procs_priv
                proxies_prive
                tables_priv

                上述元数据数据库中的表统称为"授权表";

                如果对于授权表的内容进行了修改,MySQL每300秒会自动重读并使新设置生效;

                如果不打算等待,可以手动刷新授权表:
                    MariaDB [mysql]> FLUSH PRIVILEGES;

    MySQL用户管理:
        'Username'@'Hostname'

        Username:任意的字符串组合,只能包含基本意义的字符;可以包含"_"、"."、"-";
        Hostname:
            FDQN
            Domain_name
            IP_ADDRESS

            可以使用MySQL的专用通配符:%, _

            skip_name_resolve={ON|OFF}

        创建用户账户:
            CREATE USER语句:

            CREATE USER user [IDENTIFIED BY [PASSWORD] 'password' | IDENTIFIED WITH auth_plugin [AS 'auth_string']]

            示例:
                MariaDB [mysql]> create user 'testuser'@'%';
                MariaDB [mysql]> create user 'testuser'@'%' identified by 'qhdlink';

            也可以使用DML语句创建用户账户:
                INSERT INTO mysql.user SET User='testuser',Host='%',Password=PASSWORD('qhdlink');

                示例:
                    MariaDB [mysql]> insert into user set User='user1',Host='%',Password=PASSWORD('qhdlink'),ssl_cipher='',x509_issuer='',x509_subject='',authentication_string='';

        重命名用户账户:
            RENAME USER语句:

            RENAME USER old_user TO new_user [, old_user TO new_user] ...

            示例:
                MariaDB [mysql]> rename user 'testuser'@'%' to 'test'@'172.16.%.%';

            也可以使用DML语句重命名用户账户:

                示例:
                    MariaDB [mysql]> update user set User='user01',Host='172.16.75.%' where User='user1';

        删除用户账户:
            DROP USER语句:

            DROP USER user [, user] ...

            示例:
                MariaDB [mysql]> drop user 'test'@'172.16.%.%';

            也可以使用DML语句删除用户账户:

                示例:
                    MariaDB [mysql]> delete from user where User='user01';

        用户账户的密码管理:
            1.SET PASSWORD语句:

                SET PASSWORD [FOR user] = { PASSWORD('cleartext password') | OLD_PASSWORD('cleartext password') | 'encrypted password' }

                示例:
                    MariaDB [mysql]> set password for 'test'@'%' = PASSWORD('qhdlink');

            2.也可以使用DML语句修改用户账户密码:

                示例:
                    MariaDB [mysql]> update user set Password=PASSWORD('qhdlink.com') where User='test';

            3.mysqladmin工具:
                # mysqladmin -uUSERNAME -hHOSTNAME -p password 'NEW_PASSWORD'

                注意:执行此操作的MySQL用户需要对mysql.user表有修改权限;

        忘记MySQL管理员的密码的解决办法:
            方法一:
                1.停止当前的MySQL或MariaDB服务;
                2. 在/etc/my.cnf文件中加入下列两条服务器参数:
                    skip-grant-tables = ON
                    skip-networking = ON
                3.启动MySQL或MariaDB服务,使用mysql或mysqladmin客户端工具以空秘密的root用户登录,进行root用户的密码修改;
                4.从/etc/my.cnf中删除上述两条服务器参数,再重启服务即可;

            方法二:
                1.停止当前的MySQL或MariaDB服务;
                2.使用命令启动MySQL服务:
                    # mysqld_safe --skip-grant-tables --skip-networking
                3.启动另一个会话连接,并使用mysql或mysqladmin客户端工具以空密码的root用户的身份修改其密码;
                4.kill掉此前的mysqld-safe及衍生的mysqld服务;
                5.再正常启动服务即可;

    对于已经建立的用户或未建立的用户进行授权:
        GRANT语句:

        GRANT priv_type [(column_list)] [, priv_type [(column_list)]] ...
        ON [object_type] priv_level
        TO user_specification [, user_specification] ...
        [REQUIRE {NONE | ssl_option [[AND] ssl_option] ...}]
        [WITH with_option ...]

        priv_type:
                SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER, RELOAD, REPLICATION CLIENT, REPLICATION SLAVE, SHUTDOWN, FILE, SHOW DATABASES, PROCESS, SUPER

        object_type:
                TABLE | FUNCTION | PROCEDURE

            priv_level:
                * | *.* | db_name.* | db_name.tbl_name | tbl_name | db_name.routine_name

                *:表示所有的数据库;
                *.*:表示所有数据库中的所有表对象;
                db_name.*:表示指定数据库中的所有表对象;
                db_name.tbl_name:表示指定数据库中的指定的表对象;
                tbl_name:表示当前正在使用的数据库中的指定的表对象;
                db_name.routine_name:表示指定数据库中的指定存储函数后存储过程对象;通常需要使用object_type参数共同决定;

            user_specification:
                user [ IDENTIFIED BY [PASSWORD] 'password' | IDENTIFIED WITH auth_plugin [AS 'auth_string' ] ]

        ssl_option:
                SSL | X509 | CIPHER 'cipher' | ISSUER 'issuer' | SUBJECT 'subject'

            with_option:
                GRANT OPTION | MAX_QUERIES_PER_HOUR count | MAX_UPDATES_PER_HOUR count | MAX_CONNECTIONS_PER_HOUR count | MAX_USER_CONNECTIONS count

        示例:
            MariaDB [mysql]> grant all privileges on hellodb.* to 'test'@'%';
            MariaDB [mysql]> grant select,update on hellodb.students to 'test'@'%';
            MariaDB [mysql]> grant select(Name,Age,ClassID) on hellodb.students to 'test'@'%';

            也可以对某些基本表创建视图之后,再对视图进行用户权限授权:
                MariaDB [hellodb]> create view stu_base as select Name,Age,ClassID from students;
                MariaDB [hellodb]> grant all on hellodb.stu_base to 'test'@'%';

    取消授权/收回授权:
        REVOKE语句:

        REVOKE priv_type [(column_list)] [, priv_type [(column_list)]] ...
            ON [object_type] priv_level
            FROM user [, user] ...

        REVOKE ALL PRIVILEGES, GRANT OPTION
            FROM user [, user] ...

        示例:
            MariaDB [mysql]> revoke delete on hellodb.* from 'test'@'%';
            MariaDB [mysql]> revoke all on hellodb.students from 'test'@'%';
            MariaDB [mysql]> revoke select(Age,ClassID) on hellodb.students from 'test'@'%';

        注意:在取消已经做出的授权时,REVOKE语句所指定的priv_level部分应该和授权时GRANT语句所指定的priv_level保持绝对一致;否则判定此次取消授权的操作失败;

        示例:前提是testdb数据库中包含有tb1和tb2两张表;
            MariaDB [testdb]> grant all on testdb.* to 'test'@'%';
            MariaDB [testdb]> revoke all on testdb.tb2 from 'test'@'%';
            ERROR 1147 (42000): There is no such grant defined for user 'test' on host '%' on table 'tb2'

            正确的取回授权的方式:
            MariaDB [testdb]> revoke all on testdb.* from 'test'@'%';
            MariaDB [testdb]> grant all on testdb.tb1 to 'test'@'%';

            此时,'test'@'%'用户就只有对testdb数据库中tb2表有所有操作权限;

    查看用户的授权:
        SHOW GRANTS语句:
            SHOW GRANTS [FOR user]

MariaDB/MySQL的模式:
ANSI:宽松模式。对于插入的数据进行校验,如果该数据不符合字段定义的数据类型或长度要求,则对数据类型进行调整,也可以对数据进行截取保存,发送warning警告;
TRADITIONAL:严格模式。对于插入的数据进行校验,如果该数据不符合字段定义的数据类型或长度要求,报告Error错误警告,且错误数据不会被写入;
该模式用于事务时,此前可能已经进行了一系列的数据插入和修改操作,而一旦发送上述错误,此前所有的INSERT/UPDATE等操作均会被立即放弃并回滚。
该模式用于非事务时,一旦发送上述错误,则此前所有的INSERT/UPDATE等操作均不会回滚
STRICT_TRANS_TABLES:严格模式。对于插入的数据进行校验,如果该数据不符合字段定义的数据类型或长度要求,报告Error错误警告,且错误数据不会被写入;
STRICT_ALL_TABLES:严格模式。对于事务型操作,与STRICT_TRANS_TABLES模式效果一样;对于非事务操作,与TRADITIONAL模式效果一样。

    实时修改sql_mode:
        MariaDB [(none)]> set @@global.sql_mode=TRADITIONAL;

    注意:
        1.没有最好或最差的模式,只有最合适的模式;
        2.使用上述SQL命令只能一次性生效,如果想要永久修改,则需要编辑配置文件;

SQL:
DDL:数据库对象;
获取DDL相关SQL语句的方法:
MariaDB [testdb]> help data definition

        数据库对象:
            DATABASE, TABLE, VIEW, FUNCTION, PRECEDURE, INDEX, ...

DML:数据;
    获取DML相关SQL语句的方法:
        MariaDB [testdb]> help data manipulation

        数据操纵:
            INSERT/REPLACE, DELETE, UPDATE, SELECT, ...

DDL:
数据库:
创建数据库:
CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name [DEFAULT] [CHARACTER SET [=] charset_name | [DEFAULT] COLLATE [=] collation_name]

    修改数据库的字符集或排序规则:
        ALTER {DATABASE | SCHEMA} [db_name] [DEFAULT] [CHARACTER SET [=] charset_name  | [DEFAULT] COLLATE [=] collation_name]

    删除数据库:
        DROP {DATABASE | SCHEMA} [IF EXISTS] db_name

    使用客户端命令创建数据库:
        ~]# mysqladmin create mydb
        ~]# mysql -e "create database mydb;"

    使用客户端命令删除数据库:
        ~]# mysqladmin drop mydb   //会对删除数据库的操作进行确认;
        ~]# mysql -e "drop database mydb;"

表:
    创建表:
        CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
            (create_definition,...)
            [table_options]
            [partition_options]

            //使用SQL语句全新的定义出一张新表,包括表的名称、字段数量、数据类型、存储引擎的选择等各种属性;

        Or:

        CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
            [(create_definition,...)]
            [table_options]
            [partition_options]
            select_statement

            //利用SELECT语句的查询结果来填充新表的内容,但是新表的表格式可能与基表不一致,很多的数据类型的修饰符可能会丢失;

        Or:

        CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
            { LIKE old_tbl_name | (LIKE old_tbl_name) }

            //直接复制基本的表格式到新表上,但新表中没有任何数据,即为空表;

    注意:
        1.对于MySQL或MariaDB的表来说,存储引擎是非常重要的概念,通常需要在创建表的时候来指定;如果没有明确指定,则使用默认的存储引擎;
        2.对于已经创建完成的空表,可以任意调整其存储引擎;
        3.对于非空表,不建议直接修改表的存储引擎;

        良心建议:在创建表之初或者存储数据之前,确定表的存储引擎;

    删除表:
        DROP [TEMPORARY] TABLE [IF EXISTS] tbl_name [, tbl_name] ... [RESTRICT | CASCADE]

        建议:使用修改表名称的方式使指定表不再被继续使用;

    修改表格式:
        ALTER [ONLINE | OFFLINE] [IGNORE] TABLE tbl_name [alter_specification [, alter_specification] ...]

        可以修改的内容:
            ADD:字段,索引,约束,键(主键,唯一键,外键)
            CHANGE:字段名称,字段定义格式和字段的位置;
            MODIFY:字段定义格式和字段的位置;
            DROP:字段,索引,约束,键;
            RENAME:修改表名称;

    查看表结构:
        DESC [db_name.]tbl_name;

    查看表的定义方式:
        SHOW CREATE TABLE tbl_name;

    查看表的状态和属性信息:
        SHOW TABLE STATUS [from | in db_name] like 'PATTERN' | where expr;

        示例:
            MariaDB [hellodb]> show table status where name='students'G

视图:VIEW,虚表;
    就是一个SELECT语句的执行结果;

    创建视图:
        CREATE VIEW view_name [(column_list)] AS SELECT clause;

        示例:
            MariaDB [hellodb]> create view student as select StuID,Name,Gender from students;

    删除视图:
        DROP VIEW [IF EXISTS] view_name [, view_name] ... [RESTRICT | CASCADE]

        示例:
            MariaDB [hellodb]> drop view student;

    注意:
        能否在视图中实现插入新的数据记录,取决于基表中没有被视图选择的字段是否要求不能为空,如果有此类约束,则结果是无法插入新数据;否则可以插入新数据,没有被视图选择的字段内容,默认都为"NULL";

索引:
    索引的类型:
        聚集索引、非聚集索引:
            聚集索引:索引和数据存放在一起,找到索引即找到数据;
            非聚集索引:索引和数据不存放在一起,索引通过索引指针指向数据所在位置;

        稠密索引、稀疏索引:是否索引了每一条数据记录;
            稠密索引:每条数据记录都有一条索引与之对应;
            稀疏索引:并不是每条数据记录都有一条索引与之对应,而是一条索引对应某个或某些数据块;

        主键索引、辅助索引:
            BTree:Balance Tree,B- Tree,BTree,B+Tree
                左前缀索引:

                注意:在使用BTree索引进行检索时,给出的PATTERN的最左侧字符不要出现通配符,否则,无法使用索引进行检索;只能全文遍历;

                Hash索引:

            R Tree:Spacial,空间索引;
            FULLTEXT:全文索引;

        覆盖索引:索引中的内容就是要检索的内容,通过检索索引内容即可立即找到数据,并直接返回检索结果;

    EXPLAIN:分析查询语句的执行路由;

    创建索引:
        1.在创建表时,通过指定主键或唯一键,可以自动创建索引;
        2.如果在创建表时,没有指定主键或唯一键,则可以在表成功创建之后添加索引;

        CREATE [ONLINE|OFFLINE] [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name [index_type] ON tbl_name (index_col_name,...) [index_option] ...

        示例:
            MariaDB [hellodb]> create index name_index on students(Name);

    查看索引:
        SHOW {INDEX | INDEXES | KEYS} {FROM | IN} tbl_name [{FROM | IN} db_name] [WHERE expr]

        示例:
            MariaDB [hellodb]> show index from studentsG

    删除索引:
        DROP [ONLINE|OFFLINE] INDEX index_name ON tbl_name

        示例:
            MariaDB [hellodb]> drop index name_index on students;

DML:操纵数据;
    INSERT/REPLACE、DELETE、UPDATE、SELECE

    INSERT:向表中插入新的数据记录;每次可以向表中插入一行或多行数据;
        INSERT [INTO] tbl_name [(col_name,...)] {VALUES | VALUE} ({expr | DEFAULT},...),(...),...

        示例:
            MariaDB [hellodb]> insert into students (Name,Age,Gender) values ('Rio Messi',31,'M');
            MariaDB [hellodb]> insert into students (Name,Age,Gender) values ('Guo Jing',40,'M'),('Huang Rong',27,'F');

        没有明确的规定字段名称,则意味着为一行中的各个字段添加数据内容:
            MariaDB [hellodb]> insert into students values (30,'Liu Bei',57,'M',1,2);

            注意:添加的数据内容,必须要严格的对应每个数据字段,需要保证数据类型的匹配;

    INSERT [INTO] tbl_name SET col_name={expr | DEFAULT}, ...
        示例:
            MariaDB [hellodb]> insert into students set Name='Tang Xuanzang',Age=35,Gender='M';

    INSERT [INTO] tbl_name [(col_name,...)] SELECT ...
        将后面SELECT语句的查询结果插入到选中的目标表中;注意下列问题:
            1.SELECT语句的查询结果中包含的字段数量,应该和目标表中的指定字段数量相同;
            2.SELECT语句的查询结果中包含的各字段的数据类型,必须要与目标表中各字段的数据类型保持一致;

        此种插入数据的方法,更多的用于表复制操作;
            此前曾经使用CREATE TABLE命令通过复制表格式的方式创建过一个空的新表,然后再将原表中的数据以方法复制到新表中;

    REPLACE命令与INSERT命令的功能几乎完全相同,除了一种特殊情况之外:
        当向表中插入数据时,如果主键位置或唯一键位置出现重复数据时,不会继续插入而是选择替换对应行中各字段的数据;

DELETE:
    Single-table syntax:
        DELETE FROM tbl_name [WHERE where_condition] [ORDER BY ...] [LIMIT row_count]

    Multiple-table syntax:
        DELETE tbl_name[.*] [, tbl_name[.*]] ... FROM table_references [WHERE where_condition]

        Or:

        DELETE FROM tbl_name[.*] [, tbl_name[.*]] ... USING table_references [WHERE where_condition]

    注意:默认情况下,MySQL或MariaDB都不会阻止不带有WHERE条件子句的删除操作,这将意味着,有可能会因为此操作导致清空整张表中的数据;

    限制条件:
        WHERE where_condition
        LIMIT row_count
        ORDER BY ... LIMIT row_count
        WHERE where_condition LIMIT row_count
        WHERE where_condition ORDER BY ... LIMIT row_count

    示例:
        MariaDB [hellodb]> delete from students limit 3;
            删除正常的查询结果中的前三行数据记录;

        MariaDB [hellodb]> delete from students where Age<20;
            删除Age字段中值小于20的所有数据记录;

        MariaDB [hellodb]> delete from students where Name like 'h%' limit 2;
            删除Name字段以"H|h"开头的所有数据记录中的前两条记录;

        MariaDB [hellodb]> delete from students order by age desc limit 3;
            删除根据Age字段进行降序排序的查询结果中的前三条数据记录;

UPDATE:
    Single-table syntax:
        UPDATE table_reference SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ... [WHERE where_condition] [ORDER BY ...] [LIMIT row_count]

    Multiple-table syntax:
        UPDATE table_references SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ... [WHERE where_condition]

    注意:默认情况下,MySQL或MariaDB都不会阻止不带有WHERE条件子句的修改操作,这将意味着,有可能会因为此操作导致整张表中的所有数据记录被同时修改;

    限制条件:
        WHERE where_condition
        LIMIT row_count
        ORDER BY ... LIMIT row_count
        WHERE where_condition LIMIT row_count
        WHERE where_condition ORDER BY ... LIMIT row_count

    示例:
        同DELETE的示例;

注意:在MySQL或MariaDB中,如果服务器变量sql_safe_updates=ON,则可以阻止不带有限制条件的UPDATE更新操作或DELETE删除操作;

    临时调整:
        MariaDB [hellodb]> set @@sql_safe_updates=ON;

    永久生效:/etc/my.cnf
        sql_safe_updates=ON

    MariaDB [hellodb]> update students set ClassID=1;
    ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column

SELECT
    Query Cache:MySQL/MariaDB的查询结果缓存;
        K/V对存储;
            Key:查询语句经过hash之后的hash值;
            Value:查询语句的执行结果;

    MySQL/MariaDB的查询执行路径:
        1.用户发送请求 --> 查询缓存(命中) --> 响应用户;
        2.用户发送请求 --> 查询缓存(未命中) --> 解析器 --> 预处理器 --> [查询优化器 -->] 查询执行引擎 --> 存储引擎 --> 查询执行引擎 --> [缓存查询结果 -->] 响应用户;

    SELECT
    [ALL | DISTINCT | DISTINCTROW ]
      [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
    select_expr [, select_expr ...]
    [FROM table_references
    [WHERE where_condition]
    [GROUP BY {col_name | expr | position}
      [ASC | DESC], ... [WITH ROLLUP]]
    [HAVING where_condition]
    [ORDER BY {col_name | expr | position}
      [ASC | DESC], ...]
    [LIMIT {[offset,] row_count | row_count OFFSET offset}]
    [PROCEDURE procedure_name(argument_list)]
    [INTO OUTFILE 'file_name'
        [CHARACTER SET charset_name]
        export_options
      | INTO DUMPFILE 'file_name'
      | INTO var_name [, var_name]]
    [FOR UPDATE | LOCK IN SHARE MODE]]

  DISTINCT:数据去重;即:重复出现的数据仅显示一次;

  SQL_CACHE:
    显式的指出必须将此次的查询语句的执行结果存放至查询缓存;

  SQL_NO_CACHE:
    显式的指出绝对不能将此次的查询语句的执行结果存放至查询缓存;

    query_cache_type服务器变量是MySQL的缓存开关,通常有三个取值:
        1.ON:启用缓存功能;
            默认缓存所有符合缓存条件的查询结果;除非使用SQL_NO_CACHE参数明确指出不缓存查询结果;
        2.OFF:关闭缓存功能;
            默认不缓存任何查询结果;仅能缓存使用SQL_CACHE参数明确的指出的查询结果;
        3.DEMAND:按需缓存;
            如果明确指出SQL_CACHE,即缓存查询结果,否则,默认隐式关闭查询缓存;

    query_cache_limit            | 1048576
        query_cache_min_res_unit     | 4096

    select_expr:
        *:表示表中的所有字段(列);
        col1,col2,...coln:普通的列名列表;通常用于执行投影运算;
        col_name1 as col_alias1,col_name2 as col_alias2, ...
            对于查询结果中的各字段名称使用别名进行重定义;

    table_references:
        [db_name.]tbl_name
        db_name.*
        [db_name.]tbl_name1,[db_name.]tbl_name2, ...
        [db_name.]tbl_name1 as tbl_alias1,[db_name.]tbl_name2 as tbl_alais2, ...

    单表查询:
        select select_expr1,select_expr2,... from tbl_name where expr group by col_name having expr order by col_name limit

        WHERE条件子句:
            通过指明特定的过滤条件或表达式来实现"选择"运算;过滤条件有下列几种:
                1.算术表达式:Age+10,
                    算术操作符:+, -, *, /, %;
                2.比较表达式:Age+10<20;
                    比较操作符:=, <=>, <>, !=, >, >=, <, <=;
                3.逻辑表达式:
                    逻辑操作符:AND, OR, NOT, XOR;
                4.其他表达式:
                    空值判断:IS NULL, IS NOT NULL;
                    连续区间判断:BETWEEN ... AND ... 相当于<=100  AND >=50;
                    列表从属关系判断:IN (LIST);
                    模糊值判断:
                        LIKE:可以支持通配符,%和_;如果想要使用索引实现加速检索,则最左侧字符不能使用通配符;
                        RLIKE或REGEXP:可以支持正则表达式元字符;只要在查询条件中包含正则表达式元字符,则一定无法使用索引进行检索;功能很强大,但检索性能可能变差;

        GROUP BY子句:
            根据指定的字段将查询结果进行分组归类,以方便进行聚合运算;
            常用的聚合运算函数:
                avg():取平均值运算;
                max():取最大值运算;
                min():取最小值运算;
                sum():做和运算;
                count():做次数统计;

            示例:
                统计每个班级里面的人数:
                    MariaDB [hellodb]> select ClassID,count(ClassID) as nos from students group by ClassID;

                统计每个班级里面所有人的平均年龄:
                    MariaDB [hellodb]> select ClassID,avg(Age) as nos from students where ClassID is not null group by ClassID;

                统计所有学生中男生和女生的平均年龄:
                    MariaDB [hellodb]> select Gender,avg(Age) as nos from students group by Gender;

        HAVING子句:对于经过分组归类并进行了聚合运算以后的结果进行条件过滤;
            其条件表达式的书写格式与WHERE子句相同;

            示例:
                统计人数超过3人的班级及其人数数据:
                    MariaDB [hellodb]> select ClassID,count(ClassID) as nos from students where ClassID is not null group by ClassID having nos>=3;

        ORDER BY子句:根据指定的字段将查询结果进行排序,可以使用升序或降序,默认是升序;
            升序:ASC
            降序:DESC

            示例:
                MariaDB [hellodb]> select ClassID,count(ClassID) as nos from students where ClassID is not null group by ClassID having nos>=3 order by nos desc;

        LIMIT子句:
            对于查询的结果进行限定行数的输出;
            LIMIT {[offset,] row_count | row_count OFFSET offset}

            1.LIMIT [offset,] row_count
                offset:偏移量,在输出结果中,从第一行开始(含)跳过的不显示的行数;
                row_count:要显示的行数;

                示例:显示查询结果中的第二行和第三行;
                    MariaDB [hellodb]> select ClassID,count(ClassID) as nos from students where ClassID is not null group by ClassID having nos>=3 order by nos desc limit 1,2;

            2.LIMIT row_count OFFSET offset

                示例:显示查询结果中的第二行和第三行;
                    MariaDB [hellodb]> select ClassID,count(ClassID) as nos from students where ClassID is not null group by ClassID having nos>=3 order by nos desc limit 2 offset 1;

    多表查询:
        建议:在生成环境中,能使用单表查询即可得到结果的操作,尽可能使用单表查询;因为多表查询会给服务器造成过大的负载压力;

        所谓多表查询,即指通过对多个表内容的查询,以获得具有一定关联关系的查询结果的查询方式;也称为连接操作,连接操作也就是将多张表关联在一起的方法;

        连接操作:
            交叉连接:
                也称为笛卡尔积连接;

                内连接:
                    等值连接:让表和表之间通过某特定字段的等值判断的方式建立的内连接;

                    非等值连接:让表和表之间通过某特定字段的不等值判断的方式建立的内连接;在极少的场合中才有应用;

                外连接:以某张为基准表,判断参考表与基准表之间的连接关系;
                    左外连接:
                        以左表为基准表,右表为参考表,显示出基准表中所有的行,并将参考表中与基准表中有关联关系的行合并输出,如果基准表中的行与参考表中无关,则输出NULL;

                        连接操作符:LEFT JOIN

                    右外连接:
                        以右表为基准表,左表为参考表,显示出基准表中所有的行,并将参考表中与基准表中有关联关系的行合并输出,如果基准表中的行与参考表中无关,则输出NULL;

                        连接操作符:RIGHT JOIN

            自然连接:
                通过MySQL的进程自行判断并完成的连接过程。通常MySQL会使用表中的名称相同的字段作为基本的连接条件;

                连接操作符:NATRUAL INNER

                自然外连接:
                    自然左外连接:
                        连接操作符:NATURAL LEFT JOIN

                    自然右外连接:
                        连接操作符:NATURAL RIGHT JOIN

            自连接:
                人为的将一张表中的两个字段之间建立的连接关系;

        示例:
            交叉内连接:
                每个学生所在的班级名称:
                    MariaDB [hellodb]> select Name,Class from students as s,classes as c where s.CLassID=c.ClassID;

                    MariaDB [hellodb]> select Name,Class from students,classes where students.CLassID=classes.ClassID;

            交叉左外连接:
                每个学生所在班级的名称,即使该学生不属于任何班级:
                    MariaDB [hellodb]> select Name,Class from students left join classes on students.CLassID=classes.ClassID;

            交叉右外连接:
                每个班级的学生姓名,即使该班级中没有任何学生;
                    MariaDB [hellodb]> select Class,Name from students right join classes on students.ClassID=classes.ClassID;
                                                            ||
                    MariaDB [hellodb]> select Class,Name from classes left join students on students.ClassID=classes.ClassID;

    子查询:嵌套查询;
        在SELECT查询语句中嵌套另一个SELECT查询语句;等同于从某个视图中获取查询结果;

        SELECT col1,col2,* FROM tbl_name WHERE col OPTS VALUE;

        示例:
            用于WHERE子句中的子查询:
                查询学生中年龄大于全班平均年龄的学生的姓名和年龄;
                    MariaDB [hellodb]> select Name,Age from students where Age>(select avg(Age) from students);

            用于IN子句中的子查询:
                查询学生的年龄和老师的年龄相同的学生的名字:
                    MariaDB [hellodb]> select Name from students where Age in (select Age from teachers);

                查询学生的年龄和老师的年龄相同的学生和老师的名字:
                    MariaDB [hellodb]> select t.Name as Teacher,s.Name as Student from students as s,teachers as t where s.Age=t.Age;

            用于FROM子句的子查询:
                查询有班级的学生对应的班级名称:
                    MariaDB [hellodb]> select s.Name,s.Class from (select StuID,students.Name,students.Age,Gender,Class from students,classes where students.ClassID=classes.ClassID) as s;

    联合查询:
        将多张表的内容通过多个SELECT语句查询得到的结果组合输出;

        注意:使用联合查询的前提条件:
            多张表需要有相同数据类型的字段;

            操作符:UNION

            示例:
                MariaDB [hellodb]> select StuID as ID,Name,Age,Gender from students union select TID as ID,Name,Age,Gender from teachers;

select查询:
    单表查询 --> 多表查询(交叉内连接) --> 多表查询(外连接) --> 子查询 --> 联合查询;

MySQL的存储引擎:
存储引擎也称为表类型,是一种表级别的概念,原则上来说,每张表都可以独立地使用某一个存储引擎;但出于稳定性考虑,在同一个数据库中的多张表最好选择同一种存储引擎;

对于MySQL或MariaDB来说,支持插件式存储引擎:
    默认情况下,如果使用RPM包安装的MySQL或MariaDB,插件文件所在的目录为:
        /usr/lib64/mysql/plugin

    安装一个插件:
        INSTALL PLUGIN plugin_name SONAME 'shared_library_name'

        plugin_name的相应内容,可以参考官方站点:
            http://dev.mysql.com/doc/refman/5.5/en/plugin-data-structures.html

        示例:
            MariaDB [mysql]> install plugin sphinx soname 'ha_sphinx.so';

        注意:使用此方法安装插件(存储引擎)之后,会立即自动激活;

    卸载一个插件:
        UNINSTALL PLUGIN plugin_name

        示例:
            MariaDB [mysql]> uninstall plugin sphinx;

    注意:每张表,只能使用一个存储引擎;如果在创建表时没有给出指定的存储引擎,MySQL会将新建表的存储引擎设置为默认的存储引擎;

    使用SHOW ENGINES命令查看时,support字段的值为DEFAULT的即为当前MySQL的默认存储引擎;当前版本的MariaDB中,默认存储引擎为"InnoDB";

    在创建表时,可以用的一个选项:
        CREATE TABLE tbl_name (...) ENGINE [=] engine_name;

    在表创建之后,插入数据之前,可以修改存储引擎的类型:
        ALTER TABLE tbl_name ENGINE [=] engine_name

        注意:不同的存储引擎对于数据的管理方式会不同,有时可能会有很大区别,因此,对于空表来说,可以任意修改其存储引擎;对于已经存放了数据的表来说,强烈不建议修改表的存储引擎;

当前MySQL系统上默认可以使用的存储引擎:
    MyISAM:
        最经典的MySQL的存储引擎;对于MyISAM而言,有一个缺陷——如果MySQL运行时因意外崩溃,再重启时需要对表进行修复,而MyISAM存储引擎无法保证表的安全修复;
    Aria:
        具有崩溃后安全修复表特性的增强版的MyISAM存储引擎;
    InnoDB:
    CSV:
        基于文本文件存储数据的存储引擎;跨数据库实现数据彼此交换时,比较有用;但CSV中存放的浮点类型的数值数据一定会损失数据精度;
    MRG_MYISAM:
        用于实现将多个MyISAM表在逻辑层上连接在一起,用户就像使用一张表一样去使用多张表;
    BLACKHOLE:
        黑洞存储引擎,在级联复制时比较有用;一般用于记录binlog做复制的中继;
    MEMORY:
        内存级的存储引擎;无法实现数据持久功能,多用于作为临时表(内存表)的存储引擎;MEMORY是唯一的支持用户显式定义hash索引的存储引擎,因此其查询速度是非常快的;
    PERFORMANCE_SCHEMA
        展示MySQL运行过程中的状态参数和统计数据;这些统计数据本身是MySQL内部的专有数据结构,但是有时用户需要查询这些信息,因此PERFORMANCE_SCHEMA就将此类数据虚化成一个MySQL认为可以使用的关系型接口(表);
    ARCHIVE:
        归档存储引擎,通常用来做数据仓库;这种类型的存储引擎一般仅支持select和insert语句,且本身不支持索引。适合于存放大量的独立的作为历史记录的数据。ARCHIVE存储引擎拥有高效的插入速度,查询速度相对较慢,用于日志记录和聚合函数分析较合适;
    FEDERATED:将不同MySQL服务器联合起来,逻辑上组成一个完整的数据库。非常适合于分布式应用;

MyISAM存储引擎:
    优点:
        支持全文索引(FULLTEXT INDEX),可以实现类似于搜索引擎的功能;实施数据的高效检索
        支持R TREE索引(空间函数的支持(GIS))
        支持数据的压缩存储;一旦数据被压缩,使得数据的占用空间更小,但是只能检索;
        支持复杂的行格式定义:
            ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT}

    缺点:
        不支持事务;
        锁粒度粗糙,仅支持表级锁;
        崩溃后无法保证表能够进行安全修复;(Aira)

    MyISAM存储引擎的适用场景:
        1.只读或读多写少的场景
        2.较小的表,以保证崩溃后修复的时间较短,数据丢失较少;

    MyISAM存储引擎管理数据表文件的方式:
        每个由MyISAM存储引擎管理的表,都包含三个文件,直接存储于数据库目录中;
            tbl_name.frm:format,表格式定义的内容;
            tbl_name.MYD:MyISAM Data,表中的数据内容;
            tbl_name.MYI:MyISAM Index,表中可用的索引;

    总结:
        性能:
            表级锁,并发访问性能相对较差,尤其是写锁,阻塞所有的读操作,串行访问;
            支持非聚集索引,全文索引及空间索引,检索数据时的速度和效率相对较高;
            表压缩,只能读,无法接收写操作请求;
            延迟的索引更新,比较合理的利用磁盘IO的性能;

        数据安全:
            支持手动或自动修复,但可能会导致数据丢失;
原文地址:https://www.cnblogs.com/aiaitie/p/9356245.html