十八哥Mysql笔记之提高篇

★★★exists 子查询 :判断是否存在返回值TrueFalse把外层的查询结果,拿到内层,看内层的查询是否成立

 

如 : 获取 商品类型的表 中,有商品的栏目;

Select cat_id,good_name from category where exists (select * from goods where goods.cat_id=category.cat_id);

 

英国是岛国之一,有海底隧道

 

 

★★★Union : 连接查询 , 把两次或者以上的查询结果一起显示,要求两次或多次查询的结果列数一样,类型可以不一样

                     如 : select user_name,msg_content from feedback where id=1

                          Union select name, content from conmumicate where id=1

                           注意 : 此时 列名以第一个为准

练习:有两个表AB, 都有两列 分别为 id num,有部分的id 是相同的,要求把两个表显示出来,如果id相同则把 sum 相加

Select id,sum(num) from (select * from A union select * from B) as temp group by id;

                 注意 : (1)如果合并的两个表中,它们都有一行所有的数据都相同的话,合并后的表会将此视为重复只保留一条(去重复功能),如果想要不去重复则要 加 all                                     如:select * from A union all select * from B 

                        (2)如果unionorder by ,limit 并用则要添加括号,为了分辨整体还是不部分

                                      (3)在两个表合并时,如果子句使用order by 必须陪着limit 使用呢,否则无效

   ★★★Mysql中,集合相乘,就是笛卡尔积,就是两个集合的完全组合。 所以A*B得到的积, 有M*N个元素且不可能重复。

如 :A有9行,B有8行,两表相乘有72行 

   Select * from A,B;   注意 :用逗号进行分割表示乘,形成的过程是另一表从上到下进行匹配而成

 

 

 

★★左连接:以左表为准,去右表找匹配的数据,如果找不到就用null

            所以至少有N行(即是左表的行数)

注意 : 与列位置无关

     如 :现在要从goods,category表中取数据,且将两张表互联

         Select 

          Goods_id,goods.cat_id,goods_name,shop_price

          From

          Goods left join category

          On goods.cat_id = category.cat_id;

      注意 :(1)在添加自己要的列名时,如果两个表中有相同的列名就要添加表名前缀

            (2)因为goods表在左边所以是left 

            (3)第四,五部分表看做 连接 一张大表 , 所以后面where,having就像以前写

            (4)右连接 right 替换 left ; 内连接 inner 替换 left 

 

               ★左右连接的区别 : 

                       (1)以不同的表为准

                       (2)一般最好以左连接为好(),右连接可以转换为左连接

                              


               ★内连接 :查询左右表都有的数据,即舍弃null的那部分,所以内连接是左右连接的交集

                         注意 : 目前 mysql不支持外连接 outer join,但是可以用Union达到目的 ,就是把左右连接Union

练习 :

 

              Select goods_id,goods.cat_id,cat_name,brand_id,brand_name,goods_name

               from

               goods left join category

               on goods.cat_id = category.cat_id 

                left join brand

               on goods.brand_id = brand.brand_id;

           解释 :把四五部分看做一张表,再次进行左连接 

 

       Select  t1.teamname,matchresult,t2.teamname,matchtime

       From

        Match left join team as t1

        On match.hostteamid = t1.teamid

        Left join team as t2

On match.guestteamid = t2.teamid

Where matchtime between ‘2006-6-1’and’2006--1’;

解析 :为了区分team的不通所以用as添加了别名

 

★当多表时,同名如果不添加前缀,发生的错误

 

 

★★★视图 :把查询的结果形成一张虚拟表,并没有真实的数据存在,只是与表的一种查询产生的关系 。 

创建视图的语法 :Create view 视图名 as select 语句

删除视图的语法 :drop view 视图名

                    

               如 :create view goods2 as select id,goods_name,goods_price from goods where goods_price >1500;

          优点 :(1)简化视图,能把自己经常用的拿出来

                (2)能够起到约束的作用,可以选择想给别人看的列,把表的权限封锁,开放视图的权限

3)大数据分表时会用到,当表的行数超过了200万行时,就会变慢。因此可以把一张表分为多张表。分表常用取模法:比如200万行分为4张表,就直接求余 à id%4+1 = [1,2,3,4]

(4)还可以把多张表合成一张表

 create view new select from n1  union select from n2

 

5)视图的数据来自于表,如果表中的数据改变了则视图的数据也会改变;

     当视图的数据与表的数据一一对应时,此时可以进行修改。对于视图insert还应注意,视图必须包含表中没有默认值的列,否则视图不知道如何处理该列  

      ★★视图的algorithm  (以下是它的取值)

          (1merge :不写默认,当引用视图时,引用视图的语句与定义视图的语句合并。即是把查询视图的语句与创建视图的语句合并,分析之后形成select语句

 

                例如 :新生成一个表goods2,进行查询表goods2小于3000元的手机

                       create view goods2 as select id,goods_name,goods_price from goods where goods_price >1500;

                       select * from goods2 where shop_price 3000;

                   在执行第二句进行查询的时候,实际上执行的是where shop_price >1500 and shop_price 3000 ,第一句执行之后实际上是没有数据的只是空表

最终执行的是       select id,goods_name,goods_price from goods where goods_price >1500 and goods_price <3000

                        查询的对象是goods

         解析 :在查询的时候,实际上还是回到了goods表中进行查询

          (2temptable :当引用视图时,根据视图的创建语句建立一个临时表

 

               例如 :  create algorithm=temptable view goods2 as select id,goods_name,goods_price from goods where goods_price >1500;

                           select * from goods2 where shop_price 3000;

          最终执行的是2句话 : 先取出数据放到临时表然后去查临时表

                                 查询的对象是临时表

     (3Undefind :让系统帮你选

 

 

 ★★★字符集 : 如果某级没有设置字符集,则继承上一级的。一般设置表的即可 。一般出现乱码的问题是因为字符集不符合造成的,可以声明字符的编码进行解决

 

 

 

★★★触发器 :监控某种情况,并触发某种操作

               如 :商店拍下商品并减少库存 ; 

    ★触发器能够监视和触发的操作均为增删改 四要素

 

         触发的时间 :after/before :比如饭前洗手(before/饭后洗手(after

        ★★创建触发器的语法 

           Create trigger 触发器名字

            After/before  insert/update/delete  on  表名

             For each row

             Begin

               Sql语句

              End$

            在表XX触发XX操作之后/之前,每一行开始触发XX操作,然后结束

注意 :(1sql即是需要触发的语句,可以是多句,但是也必须是那三个语句范围

2)多个sql语句用分号隔开,并事先声明用$进行结束,语句为 delimiter $,此时分号只表隔开不是结束 , 修改回来则是  delimiter 

 

 

  ★续上,如何在触发器的sql语句中引用行的值 : 

 

  

1对于监视insert来说,新增的行 可以用new来表示,且行中增加的一列:

用  new.列名 来表示

实例 :两张表,一张是商品表goods;另一张是订单表orde,如下

 

 注意 :这里不能命名为order ,因为是关键字

 

当进行下单后,库存减少的触发器

进行设置触发器

 

 

 

当插入语句后,触发的情况。这里是的goodgid是和ordeid对应的,

 

 

2对于监视delete 来说 , 删去之后,则之前的是旧行 , 可以用old来进行表示

     且行中被删除的一列的值:用  old.列名 来表示

 

当删除下单后,库存增加的触发器

 

删除后的触发效果

 

 

3对于监视update来说, 更新之后 , 改之前的是old,改之后是new

        如 :同一样商品,下单之后,又修改了订单的数量 ,则

库存数=当前库存(未改的)+未改订单商品数量—修改订单后商品数量 

 

注意 :如果不是同一样商品的话则拆开计算那个语句

 

 

 

★删除触发器的语法 :drop trgger 触发器的名字; 

★查看触发器 :show trigger

★afterbefore的区别

 

 

before案例 :用于对订单的判断,如订单的数量超出范围,强制修改订单等等

   如 :如果订单超过5,就强制把订单数改为5

 

 

★★★存储引擎 :数据库存储同样的数据,有着不同的存储方式和管理方式,称为存储引擎 , 常用的有 

Myisam :批量插入速度快,不支持事务,锁表,支持全文索引

innoDB :批量插入相对较慢,支持事务,锁行,支持全文索引

 

  ★★事务:指一组操作,要么全部都成功操作,要么都不执行à原子性(不可分割)

在所有的操作完成之前,其他会话不够看见中间的改变à隔离性

当事务完成之后,其影响是会保留下来的,不能撤销à 持久性

数据的变化,在事务的前后保持不变 à一致性

 

比如 :转钱瞬间银行断电收不到钱,因为只完成了转钱扣钱的操作,转钱进的操作未完成

   ★事务一般选用InnoDB,所以建表的时候要进行声明

 

     ★事务的语法 :

1)开启事务:start  transaction

2)提交事务:commit  (在输入完要进行的事务语句之后,进行提交)

 

在没提交事务之前,对方都不会看见你的操作结果

有些语句会造成事务的隐式提交比如再来一个start transaction

3rollback :取消事务

事务的原理

 

 

★★★备份 :系统运行时,增量备份与整体备份

        比如 : 每周日整体备份一次,周一到周六备份当天


 ★★备份文件语法:

  (1)导出库下的多张表

mysqldump –u用户名 –p密码 库名 表2 > 地址/自定义备份文件名

 

注意 :如果把表名去掉就能够导出一个库下的所有表

mysqldump –u用户名 –p密码 库名 地址/自定义备份文件

 

2)以库为单位进行导出

mysqldump –u用户名 –p密码 –B 2> 地址/自定义备份文件

 

3)导出所有的库

mysqldump –u用户名 –p密码 –A> 地址/自定义备份文件

 

★★★数据库的恢复 :即是把备份文件里面的语句全部执行一次

  ★★登陆到命令行的状态下

1)恢复一个库

   Source 地址//库名

 

2)恢复一个表

   Use 库名

      Source 地址//表名

 

 

★★不登陆到命令行

 

注意 :如果直接使用cmd的话,显示‘mysql'不是内部或外部命令,也不是可运行的程序时,需要设置环境变量。我的电脑上右键-〉属性-〉高级-〉环境变量-〉新建:变量名:path 变量值:mysql.exe所在的目录。然后重启CMD窗口

 

 

★★★索引 :针对数据所建立的目录,加快搜索的速度

 例子 : select * from goods where id=100; à 实际上在查找的时候并不一定是从id=1查到id=100,它是会按照一定的优化算法寻找的

 ★★索引的算法 :

   (1)二叉树索引,把数按照大小不断分开在两边 log2N

      (2)哈希索引

 ★索引的优点 :加快查询速度

    索引的缺点 :降低了增删改的速度,增大表文件的大小(索引文件可能大过表文件)

  ★实例 :如果要导入很多的数据,索引占内容比较大的话,就要先去掉所引,再导入,然后再统一添加索引

    所以,索引的时候必须:(1)不过度索引 (2)索引条件列选择比较频繁的比如id而不是性别 (3)索引散列的值,比如不索引为男,女添加索引

★★文件第一个是表结构文件,第二个是表数据文件(最后的Date),第三个是表索引文件(最后的index)。所以索引文件比数据文件大。

 

 

 ★★索引的分类 : 

    (1)普通索引 : index 仅仅是加快查询的速度

    (2)唯一索引 :unique index 行上的值不能重复

    (3)主键索引 :primary key 不能重复,一张表只能有一个主键,但是可以有一个或者多个唯一索引

    (4)全文索引 :fulltext index

★查看一张表上的所有索引 : show index from 表名  

            垂直排列查看    Show index from 表名 /G

 

★给表中的列添加索引 : alter table 表名 add index/unique /fulltext自定索引名(列名)

           alter table 表名 add primary (列名)


  注 :自定索引名可以省略则默认和列名一样,主键索引直接省略它

 

            注 :全文索引是依靠相似度来匹配找出

Select * from 表名 where match(全文搜索的列名) agains (‘搜索的内容’)

全文索引是有停止词的,就是对于常见的词比如in it,是不会添加索引的

全文索引在mysql的默认情况下,对中文的意义是不大的,因为英文单词有空格拆分成单词,进而对单词进行索引,中文则没有

★删除非主键索引 :alter table 表名drop index 索引名 

删除主键索引 :alter table 表名 drop primar key

 

 

★★★存储过程 : procedure ,将一段代码封装起来,当要调用该存储过程来实现。在封装的语句体里面,可以用ifwhile等控制

  ★★查看现有的封装 :show procedure status

      删除封装 :drop procedure 名字

       调用封装 : call 名字();  实际调用封装的语句,即是beginend之间的语句


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值