• mysql常用技能分享


    一,MySQL查询的五种子句:

    1,where(条件查询),常用的运算符:

    ①比较运算符

    > , < , = , != , >= , <= , in( ) , between val1 and val2

    ②逻辑运算符

    逻辑非:not / ! , 逻辑或:or / || , 逻辑与:and / &&

    ③模糊查询“like”

    通配符:% 任意字符,例如:where name like ‘苹果%’

    _ 匹配单个字符,例如:where name like ‘苹果__’

    2,group by(分组),一般情况下和统计函数(聚合函数)一起使用

    mysql五种统计函数:

    ①max:求最大值 例如查询每个分类下面最高价格的商品:

    select cat_id max(price) from goods group_by cat_id

    ②min:求最小值

    ③sum:求总和,例如:select sum(goods_number) from goods

    ④avg:求平均值,例如:求每个分类的商品平均价格

    select cat_id avg(price) from goods group_by cat_id

    ⑤count:求商品条数,例如:select count(*) from goods

    可以把每个字段名当成变量来理解,它可以进行运算:

    例:查询本店每个商品价格比市场价低多少;select goods_id,goods_name,goods_price-market_price from goods;

    可以用as给字段名起别名,group by前面如果没有使用聚合函数,默认就取每个分组的第一行数据

    3,having与where的异同

    having与where类似,可以筛选数据,where后的表达式怎么写,having后的表达式就怎么写

    where针对表中的列发挥作用,查询数据

    having针对查询结果中的列发挥作用,筛选数据

    #查询本店商品价格比市场价低多少钱,输出低200元以上的商品

    select goods_id,good_name,market_price - shop_price as s from goods having s>200 ;

    #如果用where的话则是:

    select goods_id,goods_name from goods where market_price - shop_price > 200;

    #同时使用where与having

    select cat_id,goods_name,market_price - shop_price as s from goods where cat_id = 3 having s > 200;

    4,order by

    (1) order by price  //默认升序排列

    (2)order by price desc //降序排列

    (3)order by price asc //升序排列,与默认一样

    (4)order by rand() //随机排列,效率不高

    #按栏目号升序排列,每个栏目下的商品价格降序排列:

     select * from goods where cat_id !=2 order by cat_id,price desc;

    5,limit:limit [offset,] N

    offset 偏移量,可选,不写则相当于limit 0,N。N取出条目

    #取价格4-6高的商品

    select good_id,goods_name,goods_price from goods order by good_price desc limit 3,3;

    二,mysql子查询

    1,where型子查询

    (把内层查询结果当作外层查询的比较条件)

    #不用order by 来查询最新的商品

    select goods_id,goods_name from goods where goods_id = (select max(goods_id) from goods);

    #取出每个栏目下最新的产品(goods_id唯一)

    select cat_id,goods_id,goods_name from goods where goods_id in(select max(goods_id) from goods group by cat_id);

    2,from型子查询(把内层的查询结果供外层再次查询)

    #用子查询查出挂科两门及以上的同学的平均成绩

    思路:#先查出哪些同学挂科两门以上

    select name,count(*) as gk from stu where score < 60 having gk >=2;

    #以上查询结果当做一个表放入下面的查询中去

    select name from (select name,count(*) as gk from stu having gk >=2) as t;

    #找出这些同学了,那么再计算他们的平均分

    select name,avg(score) from stu where name in (select name from (select name,count(*) as gk from stu having gk >=2) as t) group by name;

    3,exists型子查询(把外层查询结果拿到内层,看内层的查询是否成立)

    #查询哪些栏目下有商品,栏目表category,商品表goods

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

    如果商品表中的商品的栏目id等于某个栏目的id那么证明该栏目下面存在商品,所以这些栏目在条件下成立。会被查询出来。

    三,union的用法

    UNION用于把来自许多SELECT语句的结果组合到一个结果集合中

    四,内连接,左连接,右连接,全连接

    表T1:                     表T2:
    
    id name passwd        id jifen dengji
    
    1  jack   jpw             1   20    3
    
    2  tom   tpw      3   50    4

    1,内连接

    如果想把用户信息、积分、等级都列出来,那么一般会这样写:
    
    普通:select * from T1, T2 where T1.id = T2.id
    
    内连:select * from T1 inner join T2 on T1.id = T2.id
    
    后者的效率比前面的效率高多了,建议使用内连

    2,左连接

    显示左表T1中的所有行,并把右表T2中符合条件加到左表T1中;
    
    右表T2中不符合条件,就不用加入结果表中,并且NULL表示。
    
    SQL语句:select * from T1 left join T2 on T1.id = T2.id
    
    运行结果 :
    
    T1.id name  passwd  T2.id  jifen   dengji   
    
    1     jack    jpw      1     20    3   
    
    2       tom    tpw      NULL   NULL   NULL   

    3,右连接

    显示右表T2中的所有行,并把左表T1中符合条件加到右表T2中;
    
    左表T1中不符合条件,就不用加入结果表中,并且NULL表示。
    
    SQL语句:select * from T1 right join T2 on T1.id = T2.id
    
    运行结果:
    
    T1.id   name   passwd   T2.id   jifen   dengji   
    
    1        jack      jpw         1        20      3   
    
    NULL   NULL   NULL        3        50      4

    4,全连接

    显示左表T1、右表T2两边中的所有行,即把左联结果表 + 右联结果表组合在一起,然后过滤掉重复的。SQL语句:
    
    select * from T1 full join T2 on T1.id = T2.id
    
    运行结果   
    
    T1.id   name   passwd   T2.id   jifen   dengji   
    
    1         jack      jpw        1         20    3   
    
    2         tom      tpw     NULL   NULL   NULL   
    
    NULL   NULL   NULL        3      50      4 

    四,MySQL的索引

    1,什么是索引

    一个索引是存储的表中一个特定列的值数据结构(最常见的是B-Tree)。索引是在表的列上创建。所以,要记住的关键点是索引包含一个表中列的值,并且这些值存储在一个数据结构中。说到底索引就是对数据列的值进行结构化排序的一个东西。记住这一点:索引是一种数据结构

    B-Tree 是最常用的用于索引的数据结构。因为它们是时间复杂度低, 查找、删除、插入操作都可以可以在对数时间内完成。另外一个重要原因存储在B-Tree中的数据是有序的。数据库管理系统(RDBMS)通常决定索引应该用哪些数据结构。但是,在某些情况下,你在创建索引时可以指定索引要使用的数据结构。

    2,索引是怎么提升性能的?

    因为索引基本上是用来存储列值的数据结构,这使查找这些列值更加快速。如果索引使用最常用的数据结构-B-Tree-那么其中的数据是有序的。有序的列值可以极大的提升性能。下面解释原因。

    假设我们在 Employee_Name这一列上创建一个B-Tree索引。这意味着当我们用之前的SQL查找姓名是‘Jesus’的雇员时,不需要再扫描全表。而是用索引查找去查找名字为‘Jesus’的雇员,因为索引已经按照按字母顺序排序。索引已经排序意味着查询一个名字会快很多,因为首字母为‘J’的员工都是排列在一起的。另外重要的一点是,索引同时存储了表中相应行的指针以获取其他列的数据。

    3,数据库索引里究竟存的是什么?

    你现在已经知道数据库索引是创建在表的某列上的,并且存储了这一列的所有值。但是,需要理解的重点是数据库索引并不存储这个表中其他列(字段)的值。举例来说,如果我们在Employee_Name列创建索引,那么列Employee_Age和Employee_Address上的值并不会存储在这个索引当中。

    索引存储了指向表中某一行的指针

    如果我们在索引里找到某一条记录作为索引的列的值,如何才能找到这一条记录的其它值呢?这是很简单 - 数据库索引同时存储了指向表中的相应行的指针。指针是指一块内存区域, 该内存区域记录的是对硬盘上记录的相应行的数据的引用。因此,索引中除了存储列的值,还存储着一个指向所在行数据的索引。也就是说,索引中的Employee_Name这列的某个值(或者节点)可以描述为 (“Jesus”, 0x82829), 0x82829 就是包含 “Jesus”那行数据在硬盘上的地址。如果没有这个引用,你就只能访问到一个单独的值(“Jesus”),而这样没有意义 

    4,哈希表索引是怎么工作的?

    哈希表是另外一种你可能看到用作索引的数据结构-这些索引通常被称为哈希索引。使用哈希索引的原因是,在寻找值时哈希表效率极高。所以,如果使用哈希索引,对于比较字符串是否相等的查询能够极快的检索出的值。例如之前我们讨论过的这个查询(SELECT * FROM Employee WHERE Employee_Name = ‘Jesus’) 就可以受益于创建在Employee_Name 列上的哈希索引。哈系索引的工作方式是将列的值作为索引的键值(key),和键值相对应实际的值(value)是指向该表中相应行的指针。因为哈希表基本上可以看作是关联数组,一个典型的数据项就像“Jesus => 0x28939″,而0x28939是对内存中表中包含Jesus这一行的引用。在哈系索引的中查询一个像“Jesus”这样的值,并得到对应行的在内存中的引用,明显要比扫描全表获得值为“Jesus”的行的方式快很多。

    5,哈希索引的缺点

    哈希表是无顺序的数据结构,对于很多类型的查询语句哈希索引都无能为力。举例来说,假如你想要找出所有小于40岁的员工。你怎么使用哈希索引进行查询?因为哈希表只适合查询键值对-也就是说查询相等的查询(例:like “WHERE name = ‘Jesus’)。哈希表的键值映射也暗示其键的存储是无序的。这就是为什么哈希索引通常不是数据库索引的默认数据结构-因为在作为索引的数据结构时,它没有B-Tree那么灵活

    6,聚簇索引:

    实际存储的顺序结构与数据存储的物理结构是一致的,所以通常来说物理顺序结构只有一种,那么一个表的聚簇索引也只能有一个,通常默认都是主键,设置了主键,系统默认就为你加上了聚簇索引,当然有人说我不想拿主键作为聚簇索引,我需要用其他字段作为索引,当然这也是可以的,这就需要你在设置主键之前自己手动的先添加上唯一的聚簇索引,然后再设置主键,这样就木有问题啦。总而言之,聚簇索引是顺序结构与数据存储物理结构一致的一种索引,并且一个表的聚簇索引只能有唯一的一条。

    7,非聚簇索引:

    非聚簇索引记录的物理顺序与逻辑顺序没有必然的联系,与数据的存储物理结构没有关系;一个表对应的非聚簇索引可以有多条,根据不同列的约束可以建立不同要求的非聚簇索引。

    8,主键索引和唯一索引的区别

    主键创建后一定包含一个唯一性索引,唯一性索引不一定就是主键。

    唯一性索引列允许空值,而主键列不允许为空值。

    主键列在创建时,已经默认为空值 + 唯一索引了。

    主键可以被其他表引用为外键,而唯一索引不能。

    一个表最多只能创建一个主键,但可以创建多个唯一索引。

    主键更适合那些不容易更改的唯一标识,如自动递增列、身份证号等。

    总结索引使用原则:

    1:不要索引数据量不大的表,对于小表来讲,表扫描的成本并不高。

    2:不要设置过多的索引,在没有聚集索引的表中,最大可以设置249个非聚集索引,过多的索引首先会带来更大的磁盘空间,而且在数据发生修改时,对索引的维护是特别消耗性能的。

    3:合理应用复合索引,有某些情况下可以考虑创建包含所有输出列的覆盖索引。

    4:对经常使用范围查询的字段,可能考虑聚集索引。

    5:避免对不常用的列,逻辑性列,大字段列创建索引。

    MySQL只对以下操作符才使用索引:<,<=,=,>,>=,between,in,以及某些时候的like(不以通配符%或_开头的情形)

    来源[http://www.cnblogs.com/rollenholt/archive/2012/05/15/2502551.html],[http://blog.csdn.net/weiliangliang111/article/details/51333169]

    感谢以上博友分享!

  • 相关阅读:
    奇虎董事长周鸿祎:谁说没钱不能创业
    分析.NET基础库源码,学习Stream类及相关类
    Why need two IF in singleton pattern in the multiple threads scenario
    It's bad design that leveraging singleton design pattern in db connection
    Asp.net mvc 3 JSONResult return array
    System.Web.HttpContext.Current vs. ControllerContext.HttpContext (almost the same)
    Nhibernate HQL example paging and avoid sql injection
    Asp.net mvc 3 JSON complext object mapping
    Nhibernate configuration in app.config with log4net enabled 0 of 4
    Setup and run a simple nhibernate example
  • 原文地址:https://www.cnblogs.com/phpper/p/6614029.html
Copyright © 2020-2023  润新知