一、基础概念
二、DDL,DML语句
三、MySQL基础架构
四、索引
五、视图VIEW
六、DML语句执行过程
七、MySQL查询操作
八、多表查询
九、子查询:查询语句中嵌套查询语句

一、基础概念
数据库:表、索引(平衡树索引[排列之后],B-Tree索引)、视图(虚表)
    索引会加速读取速度,但是会影响写入操作
    SQL:stucture Query Language
        DDL,DML
    编程接口:
        存储过程:没有返回值的函数
        存储函数:有返回结果的代码片段
        触发器:代码片段,SQL语句
        事件调度器:类似于crontab,完成某些任务
        过程式编程:选择、循环
存储过程和存储函数请参考:https://www.cnblogs.com/zhanglei93/p/6437867.html
      
1.阿里去IOE:emc,oracle,IBM emc存储,oracle数据库,IBM小型机            
    三层模型://数据模型
        物理层 //存储设备或FS上的形态,一张表一个文件,多张表一个文件等
        逻辑层:DBA看到的表,索引,视图等
        视图层:最终用户看到的,例如让终端用户授权只能看到一张表中几个字段
数据库解决方案:
    Oracle,Sybase,Infomix,PostgreSQL,SQLite //以前三分天下,
        Infomix属于IBM,IBM有:DB2
        MySQL, 07年被sun收购,10亿,后来被Oracle收购
        Mairadb :
MySQL-->5.1-->5.5-->5.6-->5.7
Mairadb-->
    插件式存储引擎://show engines查看存储引擎
    单进程多线程:
        连接线程:维护client连接
        守护线程:
2.msyql配置文件
集中式的配置文件,能够为mysql的各应用程序提供配置信息
    [mysqld]
    [mysqld_safe] //线程安全
    [mysqld_multi] //多实例,多实例共享
    //三个只启动一个
    [server] //服务端程序使用的配置
    [mysql] //专用于client端
    [msqldump] //备份
    [client] //客户端
    
    parameter = value
    //有的支持"_",有的支持"-" ,大部分两种风格都支持,建议统一
    skip-name-resolve 或者skip-name-resolve = on
    skip_name_resolve //都可以使用
3.配置文件查找路径    
    /etc/my.cnf-->/etc/mysql/my.cnf-->$安装路径/my.cnf--> --default-extra-file=/path/to/somedir/my.cnf[指定其他的配置文件]--->~/.my.cnf
    每个位置都会查找,最后决定哪个生效 //越往后,后面的最终生效
    
    元数据数据库:mysql    
        user,host等
        mysql-->mysqld
mysql-->mysqld
    mysql客户端程序:
        mysql:交互式CLI工具
        mysqldump:导入导出工具,基于mysql协议向mysql发起查询请求,并将查到的数据转换成insert等写操作语句,保存文本文件中。
        msyqladmin:基于msyql协议管理mysqld
        mysqlimport:数据导入工具;
    非客户端类的管理程序:
        myisamchk //检查修复myisam表
        myisampack //表打包工具
        
    获取默认配置信息:
        mysql --print-defaults
            --no-auto-rehash //关闭自动补全功能,tab间补全
            但是rehash会在加载所有的msyqld组件,表,库等,hash到内存,导致client接入速度变慢
        mysqld --print-defaults
4.客户端类应用程序的可用选项:
    -u user
    -h host
    -p password
    -P Port
    --protocol={tcp|socket|pipe...}
    -S socket文件//本机通信
    -D,database
    -C compress,传输过程压缩
    -e "SQL" //执行sql语句

5.mysql的使用模式:
    交互式模式:
        可运行命令:
            客户端命令:
                \h,help,?
            服务器端命令
                SQL语句, 语句结束符
    脚本模式:
        # mysql -uUSERNAME -pPASS -hHOST < /path/a.sql
        mysql> source /path/a.sql
    
6.服务器端(msyqld):工作特性有多种定义方式
    命令行选项:--ARGU --ARGU ...
    配置文件参数:my.cnf 指定
        mysqld --verbose --help //获取可用参数列表        
        mysqld_safe --verbose --help
        MariaDB [(none)]> show variables\G; //查看参数
        mysqladmin extended-status
    获取运行中的msyql进程使用各参数及其值:
        mysql > show global variables;
        mysql> show session variables; //仅仅对当前会话生效
        
    注意:有些参数支持运行时修改,会立即生效;    有些参数只能通过修改配置文件,并重启服务生效
        有些参数作用域是全局的,不可改变;有些参数可以为每个用户提供单独配置;
            例如data_dir 是不允许修改的,
                
        全局配置:每个新登录的用户都会集成
            DBA1修改后,新登录的用户,也是集成全局配置,而不是修改后的配置
    修改变量的值:
        msyql> help set
        
        全局:
            mysql> set global system_var_name=VALUE;
            mysql> set @@global.system_var_name=value;
        会话:
            mysql> set [session] system_var_name=value;
            mysql> set @@[session.]system_var_name=value;
        
    状态变量: //是不能修改的
        用于保存msyql运行中的统计数据的变量;
            mysql> show global status ;
            mysql> show [session] status;
            
            
7.SQL:ANSI //SQL标准
    SQL-86,SQL-89,SQL-92,SQL-99,SQL-03
                    
8.SQL模式:
    enum('a','1') //inert ('b') //仍然能够成功,但是b为空
    tinyint 字段中插入大于256的,仍按不会错误,自动截取,保留前五个
    
    也可以当用户插入非法数据时,不让用户操作成功,需要sqlmode定义
    
SQL MODE:定义mysqld对约束的响应行为。
    set global sql_mode='string' //不会立即生效,后面新建立的才会生效
    set @@global.sql_mode='mode'  //仅仅对后期的新会话有效,已经建立的无效
    
    需要有权限的用户才能修改。修改会话级别的sql_mode 立即生效
    set session sql_mode='mode'
    set session @@session.sql_mode='mode'
    
    MariaDB [mine]> show global variables like 'sql_mode';
    MariaDB [mine]> show global variables like 'sql_%'; //%任意长度任意字符
    
常用mode:traditional,strict_trans_tables,strict_all_tables //模式
    传统模型:不允许对非法值进行插入操作
    严格事务模型:对所有支持事务类型的表,做严格约束
    严格所有:
    还有sqlserver 的mode,oracle的mode等还有很多
默认global和session的sql_mode一样
    

MariaDB [mine]> create table t1 (id int unsigned auto_increment primarykey not null,name char(5) not null)
MariaDB [mine]> insert into t1 (name) values('tom'),('blamdfkjidf');
Query OK, 2 rows 
affected, 1 warning (0.02 sec)
Records: 2  Duplicates: 0  Warnings: 1
MariaDB [mine]> show warnings;
+---------+------+-------------------------------------------+
| Level   | Code | Message                                   |
+---------+------+-------------------------------------------+
| Warning | 1265 | Data truncated for column 'name' at row 2 |
+---------+------+-------------------------------------------+
//插入数据太长了,自动修剪
MariaDB [mine]> set sql_mode='traditional';
//仅仅对当前会话有效
MariaDB [mine]> insert into t1 (name) values('tom'),('blamdfkjidf');
ERROR 1406 (22001): Data too long for column 'name' at row 2

注意:无论是global还是sesion修改,重启mysql都会失效
    除非:定义在配置文件中,或者启动mysql时传递参数给mysql
二、DDL,DML语句
    DDL:数据定义语言create,alter,drop,
DB组件:数据库、表、索引、视图、用户、存储过程、存储函数、触发器、事件调度器...
    help create //即可看到
alter和create操作的对象类似
    MariaDB [mine]> show create database mine;
    //还原创建库语句,优化后的结果
        
1.DML:数据操作语言:
    insert,delete,update,select    
    数据库:
        create,alter,drop //没有回收站,删除需要谨慎
            {database|schema}
            {if exists}
            {if not exists}
表:二维关系
    设计表:遵循规范
    
    定义:字段,索引
        字段:字段名,字段数据了类型,修饰符,
        约束:索引:应该创建在经常用作查询的字段上;,默认Btree索引
            索引:实现级别在存储引擎。
            索引的分类:
                稠密索引,稀疏索引 //稀疏:隔行或隔字段索引
                B+索引,hash索引,R树索引,全文索引
                聚集索引,非聚集索引//    数据和主键索引是否存储在一起,按照索引次序进行存储
                        //索引可以单独存储在一个文件上
                单键索引和组合索引//索引在一个或者多个字段上,
    创建表:create table
        1.直接创建;
        2.通过查找现存的表创建;新表中会被直接插入查询而来的数据
        3.通过复制现存的表的表结构;不复制数据
        create table
        create table tbl_name like old_name
        create table tbl_name select_statement
    修改表:
        alter
        
        show global variables like '%default%engine%' //查看默认存储引擎
        default_storage_engine InnoDB //默认InnoDB引擎
注意:Storage Engine 是指表类型,也即在表创建时指明其使用的存储引擎;
    同一库中表要使用同一种存储引擎类型;
        
查看表状态信息:
    查看表结构:describe tbl_name
查看表状态信息:
    show tables from db_name like
    
    MariaDB [mine]> help show tables;
    SHOW [FULL] TABLES [{FROM | IN} db_name] [LIKE 'pattern' | WHERE expr]
    show table status line 't1' //查看t1表的状态信息

MariaDB [mine]> show table status like 't1'\G;
    row 为行;column为列
    =================================
     Row_format: Compact
           Rows: 4    //共有4行
 Avg_row_length: 4096  /平均行大小
    Data_length: 16384    //表中数据的大小
Max_data_length: 0        //表数据的最大容量,该值和存储引擎相关,0没有上限
   Index_length: 0        //索引大小,没有创建索引
      Data_free: 10485760    //目前已经分配的空间,但是没有使用的
 Auto_increment: 7
    Create_time: 2017-04-13 13:56:59 //创建时间
    Update_time: NULL    //最近一次的修改时间
     Check_time: NULL        //最近一次使用check table命令检查的时间,myisam表使用
      Collation: latin1_swedish_ci //排序规则
       Checksum: NULL        //表的校验和
 Create_options:             //

        
    
修改表:alter table
删除表:drop table
        
三、MySQL基础架构        
1.单进程多线程:

MySQL入门(二)_第1张图片
用户连接:连接线程
SQL interface://DML,DDL,存储过程,视图,事件等
    //检查词法语法错误,等
Parser:分析器,分析对象访问权限等。查询对象属性//查询翻译,转换成能够在本地执行的操作
Optimizer:优化器,最佳paths,静态数据等,//根据内置的索引,以及动态生成的数据,选择最近执行方法[语句]
    //选择最佳
MySQL的数据文件类型
    数据文件、索引文件
    重做日志,撤销日志,二进制日志,错误日志,查询日志,慢查询日志,(中继日志)
管理工具:
    备份,恢复,安全,集群,管理,配置,迁移,元数据工具(myisamchk)
    
2.MySQL的认证:
    1.用户登录该数据库的权限
    2.用户对请求的目标数据的权限

MySQL入门(二)_第2张图片

//缓存查询的结果,进行hash计算,key-value对比,hash是区分大小写的//因此建议使用统一风格,大写或者小写
//首次需要,连接管理器和线程管理器,通过用户模块验证身份
//之后的操作,client直接通过已经建立的链接通过调用用户模块进行操作。
//执行过程:由存储引擎负责执行            
简化版架构
--------------------------------------

MySQL入门(二)_第3张图片

四、索引

索引管理
    索引:按照特定数据结构所存储的数据
    索引:只是告诉我们有这样一个数据记录,具体的值还需要去查询
        //索引可以理解为一个指针
例如查询:没有索引的话,需要扫描表中所有的内容,文件过大的话,会导致效率低下
    //有了索引的话,只需要查询索引中的一个区域,因为已经按照一定的规则组织起来了(可认为是排序)
    //内存中需要装载的数据量也少了        

聚集索引:数据和索引是放在一起的 //每个表只能有一个聚集索引,因为数据行本身只能按一个顺序存储。
    //优点:直到索引,数据就直接找到了,不用再次扫描数据块
    //缺点:删除一条数据记录,所有的其他索引都有可能需要重新编排
    主键不一定是聚集索引。
非聚集索引:数据和索引是分离的,各自独立//索引只是一个指针,指向了原始数据的位置
    //索引可能是一个单独文件,索引中的数据指向了原始数据对应的数据块
索引还需要组织成多级形式:表现为平衡树索引
    多级中第一级:稀疏格式
    最下级:多为聚集索引
索引的好处://4级别索引,只需要5次io,没有索引的话,可能需要n次io,因为每个数据的加载,就是一次io    
索引的问题:插入新数据,删除数据,更新数据//都有可能触发所有索引改变
    
表中的数据量较小时,可以不使用索引
表中的数据量较大时,索引的效果还是比较明显的
    
索引类型:
    聚集索引、非聚集索引//数据是否与索引存储在一起
    主键索引、辅助索引//聚集索引多为主键索引
    稠密索引、稀疏索引//是否索引了表中的每一个数据项
    B+ Tree,HASH,R Tree,Full text //B:balance,hash:key-value不能排序,因为排序对hash值进行排序没有意义
    简单索引、组合索引//索引创建在了两个字段上
    
    左前缀索引: //每一行的前几个字符,进行索引
        问题:select like '%abc%' //索引可能在这里匹配不到,只能找原始数据
    覆盖索引:索引中直接有所需要的数据。不用去查找原始数据。
    
管理索引的途径:
    创建表时指定;
    创建索引:创建表时指定。
    创建或删除索引:修改表的命令 alter table ... add index ..
    help create table;
        create tables tbl_name     
    help crate index;
        
    help alter table
        alter table ... add index
        altere table ... drop index
        
    
    删除索引:
        drop index index_name on table_name
        alter table ... drop index ...
    查看索引:
        show index from|in table_name
        
        
    注意:索引是没有必要修改的1
        千万不要对在线系统,进行删除或者重建索引,更新索引。因为损失代价很大。
        
        对一个1kw行的表,构建索引,大概需要几十分钟。
        索引一旦重建,所有的请求,都要修改,可能瞬间卡死。

博客推荐:https://www.cnblogs.com/tgycoder/p/5410057.html

[root@localhost ~]# mysql -uroot -ptengxun < hellodb.sql
MariaDB [hellodb]> explain select * from students where StuID=3\G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: students      
         type: const //查询类型为一对一,查询一行,只加载一行
possible_keys: PRIMARY //可能查询的键,主键
          key: PRIMARY //实际用到的键,主键也是一种索引
      key_len: 4
          ref: const
         rows: 1
        Extra: 
//explain:只是分析查询过程,而不真正进行查询
//StuID为主键,但是Age是没有索引的
MariaDB [hellodb]> explain select * from students where Age=53\G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE //简单查询,只在一张表中
        table: students 
         type: ALL //全表扫描
possible_keys: NULL 
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 25 //查询了25行
        Extra: Using where
        
//创建索引
MariaDB [hellodb]> alter table students add index(age);
MariaDB [hellodb]> show indexes from students;
    
MariaDB [hellodb]> explain select * from students where Age=53\G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE    
        table: students
         type: ref    //
possible_keys: Age
          key: Age 
      key_len: 1 //取出了1行
          ref: const 
         rows: 1    //只有一行
        Extra: 
MariaDB [hellodb]> create index name on students(name);
MariaDB [hellodb]> show indexes from students;
MariaDB [hellodb]> desc students;
MariaDB [hellodb]> explain select * from students where Name like "X%"\G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: students
         type: range
possible_keys: name
          key: name
      key_len: 152
          ref: NULL
         rows: 6  //过滤掉6行
        Extra: Using index condition
MariaDB [hellodb]> explain select * from students where Name like "%X%"\G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: students
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 25
        Extra: Using where

//此时索引,将没用,因此:查询语句很重要
五、视图VIEW
    虚表;存储的select语句
    CREATE
        VIEW view_name [(column_list)]
        AS select_statement
        [WITH [CASCADED | LOCAL] CHECK OPTIO    

    是一个基本组件:

MariaDB [hellodb]> create view test as select  StuID,Name,Age from students;
MariaDB [hellodb]> show tables;
    //可以看到该虚表
MariaDB [hellodb]> show table status like 'test'\G;
    //一堆NULL
MariaDB [hellodb]> explain select * from test where age=22\G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: students //真实的表
         type: ref
possible_keys: Age    
          key: Age
      key_len: 1
          ref: const
         rows: 2
        Extra:

    基表插入内容,视图会修改吗?
        也会随着修改。
    视图能否插入数据?
        视图只有部分字段,基表中有其他字段的约束,而该字段没有在视图中,则不能插入。
        结论:能否修改成功数据,取决于基表中的约束限制
六、DML语句执行过程
    增,删,查,该
    insert,delete,update,select
    insert:支持一次插叙一行,或多行数据
1.insert
    insert tbl_name (col1,col2,,) values (valu1,..),(val2,...)..     
        键冲突,则失败
    replace语句和insert语句类似:
        键冲突,则替换
    insert into students (Name,Age,Gender) values ('Jinjiaodawnag',100,'M')
    insert into students set Name='yinjiaokey',Age=98,Gender='M';
    insert into students as select 语句//字段要保持一致
2.delete
    delete from students //删除整个表
    delete from students where .. //一定要加上where子句
    
    注意:一定要有限制条件,否则将清空表中的所有数据
        update也要加上限制条件
    限制条件:
        where ... limit //limit可以没有
        order ... limit         
3.update
    update tbl_name set col1=VALUE col2=VALUE ... where 条件/Order by条件/limit条件
    注意:
    限制条件:
        where ... limit //limit可以没有
        order ... limit     
4.select 语句        
//进程是没有权限直接访问磁盘的,只能交由内核,让内核加载数据到内存中,进程在内存中进行修改
七、MySQL查询操作
查询的执行路径:    
MySQL入门(二)_第4张图片
    查询缓存:query cache  
    分析器-->预处理-->查询优化器-->查询执行计划-->查询执行引擎
    查询执行计划:排队执行
    查询结果,符合缓存条件,则进行缓存
    
组件:
    查询缓存,解析器,预处理器,优化器,查询与执行引擎,存储引擎
    假如有多台mysql 服务器,每个服务器都有自己的缓存
MySQL入门(二)_第5张图片
    为了提高命中率,将同一个请求,发送同一个后端server
        一致性hash;基于查询粘性。但是在一定程度上,损害了负载均衡效果
    或者使用第三方的公共缓存
        app server先去查找缓存,没有记录则查询mysql
    MySQL自己的缓存大小是有大小的。
        假如使用mySQL主从,需要读写分离。写入发给master
        
MariaDB [hellodb]> select now(); //显示当前系统时间
    这种查询进行缓存是没有用的。
    一般只有在查询结果是确定时,进行缓存才有用
    select database(); //当前使用的库
    
select语句:
    select ... from ... order by ...
    select ... form ... group by ... having ...
    select ... from ... where ...
    select ... from ... where ... group by ... limit ...
    select ... from ... having ...
    
    
    FROM-->WHER-->GROPU by-->HAVING-->ORDER BY-->SELECT colums-->LIMIT-->end
    
    分组后聚合
    HAVING:聚合
    select colume:挑选出需要的字段,投影
    
    单表查询:

SELECT
    [ALL | DISTINCT | DISTINCTROW ]
      [HIGH_PRIORITY]
      [STRAIGHT_JOIN]
      [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
      [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]]

(1)解释
    DISTINCT:去除重复的内容
MariaDB [hellodb]> select distinct Gender from students;
    //只有M和F
    SQL_CACHE / SQL_NO_CACHE :明确指定查询 [存储/不存储] 结果于缓存之中
MariaDB [hellodb]> show global variables like "query%";
MySQL入门(二)_第6张图片

//查询缓存类型,为ON则启动缓存查询结果,为OFF为关闭缓存功能

    query_cache_type值为"ON"时,查询缓存功能打开
        select的结果符合缓存条件才缓存,否则,不予缓存。
        显式指定SQL_NO_CACHE,不予缓存。    
    query_cache_type的值为DEMAIN时,查询缓存功能按需进行
        显示执行sql_cache语句才会缓存,但是也要满足缓存条件。其它均不予缓存
    
    注意:我们应该关注其命中率
        命中/(没有命中+命中)
MariaDB [hellodb]> show global status like "Qcache%";
MySQL入门(二)_第7张图片
字段显示可以使用别名:
    select Name as StuName  from students     
    WHERE:子句:指明过滤条件,实现选择
        过滤条件:布尔型表达式,返回值要么为真,要么为假
    select Name,Age from students where age+30>50    
操作符:
    1.算数操作符:
        + - * / %
    2.比较操作符:    
        =     !=/<>不等于
        >=,>,....
        <=>//NULL safe 等于
    select Name,Age from students where age != 22;
        
    BETWEEN min_num AND MAX_num
    IN 列表范围内
    select Name,Age,From students WHERE Age In (18,100);
    IS NULL;判断是否为空
    IS not NULL :非空取值
    like :模糊比较,通配符或者表达式
        %:任意长度的任意字符
        _:任意单个字符
        
    rlike:使用正则表达式 regular
    REGEXP:同rlike,有可能所以将无法使用,尽量不要使用
    
    3.逻辑操作符:
        not
        and
        or
        xor:异或,二者不同则为真,相同则为假
        
    GROUP子句:根据指定的条件把查询结果进行“分组”以用于做“聚合”运算;
        avg(),max(),count(),sum()
    MariaDB [hellodb]> select avg(Age),Gender from students group by Gender;
    MariaDB [hellodb]> select avg(Age) as AAge,Gender from students group by Gender HAVING AAge>20;
        //对group之后的结果进行,过滤
    MariaDB [hellodb]> select count(StuID) as NOS,ClassID from students group by ClassID;
        //查看每个班,有多少人。
    MariaDB [hellodb]> select count(StuID) as NOS,ClassID from students group by ClassID having NOS>2;    
        //超过2个人的班级
    ORDER by:根据指定字段对查询结果进行排序
        升序:ASC 默认
        将序:DESC
    LIMIT [[offset],rowcount] ,对查询的结果进行输出行数限制
        select * from students limit 10,10; //偏移10个,取出后10个
    for  update 请求施加写锁,排他锁
    LOCK in share mode 施加共享锁,共享锁,读锁
        //对查询结果请求施加锁
                   
练习:导入hellodb.sql生成数据库
    (1) 在students表中,查询年龄大于25岁,且为男性的同学的名字和年龄;
    (2) 以ClassID为分组依据,显示每组的平均年龄;
    (3) 显示第2题中平均年龄大于30的分组及平均年龄;
    (4) 显示以L开头的名字的同学的信息;
    (5) 显示TeacherID非空的同学的相关信息;
    (6) 以年龄排序后,显示年龄最大的前10位同学的信息;
    (7) 查询年龄大于等于20岁,小于等于25岁的同学的信息;用三种方法;        
    
select Name,Age from students where Gender='M' and Age>25;
select avg(Age) from students group by ClassID;
select avg(Age) as Age  from students group by ClassID having AAge>30;    
select * from students where Name like 'L%';
select * from students where TeacherID is not NULL;
select * from students order by Age limit 10;    

select * from students where Age>=20 and Age<=25;
select * from students where  Age in (20,21,22,23,24,25);
八、多表查询
内连接:
    等值连接:让表之间的字段以“等值”建立链接关系
    不等值链接
    自然链接
外链接:
    左外链接:以左为准,
        from tb1 left join tb2 on tb1.col=tb2.col //
    右外链接:以右侧为准
        from tb1 right join tb2 on tb1.col=tb2.col //

等值连接:两个表中具有相同意义的字段,以相等方式进行链接
    相等的则构建新行,否则,丢弃
select * from students,teachers where students.TeacherID=teachers.TID;
select s.Name as StuName,t.Name as TeaName from students as s,teachers as t where s.TeacherID=t.TID;
select s.Name,c.Class from students as s,classes as c where c.ClassID=s.ClassID;
select s.name,c.class from students as s LEFT JOIN classes as c ON s.ClassID=c.ClassID;
    //左外链接,以左为准
select s.name,c.class from students as s RIGHT JOIN classes as c ON s.ClassID=c.ClassID;
    //右外链接,以左为准
select s.Name,t.Name from students as s,students as t where s.StuID=t.ClassID;
    //自己的字段和自己的另外一个字段,等值链接
多表查询:代价比较大,
九、子查询:查询语句中嵌套查询语句
    基于某语句的查询结果再次记性查询
    建议不要使用子查询,因为性能不好
    
    1.用在where子句中的子查询
        (1)用于比较表达式的子查询;子查询仅能返回单个值
        select * from students where Age>(select avg(Age) from students);
        //查询年龄大于平均年龄的同学
        (2)用于in中的子查询;子查询语句返回一个或多个值从而构成列表
        select * from students where Age in (select Age from teachers);
        //查询同学和老师年龄相同的行
        (3)exists;存在性判断
    2.用于From子句的查询
        select tb_alias.col1,... FROM (select clause) AS tb_alias where Clause;
        select s.AAge,s.ClassID from  (select avg(Age) as AAge,ClassID from students where ClassID is not NULL group by ClassID) AS s where s.AAge>30;
        
联合查询:
    两个查询结果合并为一个,对应字段要一致   
    select Name,Age From teachers union select Name,Age from students;
    
设置缓存大小:
set @@global.query_cache_size=1000000; 这里是设置1M左右,900多K。
再次查看下 select @@global.query_cache_size;    
    
row:行
colume:列    

交叉连接,笛卡尔乘积//最低效的
    select * from students,teachers;
    //student的行数 *  teachers的行数 = 最终显示行数