目录

数据库(表)设计3范式:

第一范式(1NF):

第二范式(2NF)

第三范式(3NF)

数据操作语言:

插入数据(增):

load  data(载入数据)语法:

删除数据(删):

修改数据(改):

基本查询

基本语法形式

字段或表达式列表

all 和 distinct

from子句

where子句

is运算符:空值和布尔值的判断

between运算符:范围判断

in运算符:给定确定数据的范围判断

like运算符:对字符串进行模糊查找

group by 子句:分组

什么叫做分组?

having子句

可以用以下语句“恢复”(导入)数据:

order  by 子句

limit子句

对整个select语句的一些总结


数据库(表)设计3范式:

第一范式(1NF):

要求数据达到原子性,使数据不可再分;

看一个没有满足第一范式的例子:

                                                    PHP笔记之MySQL(3)

对其进行修改后,就符合第一范式了:

                                                   PHP笔记之MySQL(3)

第二范式(2NF)

使每一行数据具有唯一性,并消除数据之间的“部分依赖”,使一个表中的非主键字段,完全依赖于主键字段;

     经验上:常常是每个表都要设计主键,并通常多数情况下,使用一个自增长的int类型的字段当做主键

实际,有2个方面的要求:

1,每一行数据具有唯一性:只要给表设计主键,就可以保证唯一性。

2,消除数据之间的“部分依赖”;

 

什么叫做“依赖”?

    依赖,就是在一个表中,其中某个字段的值B可以由另一个字段的值A来“决定”,则此时我们就称为:

         字段B依赖于字段A,

         或:

         字段A决定字段B;

其意思是,如果根据字段A的某个值,一定可以找出一个确定的字段B的值,就是A决定B。

   对一个有主键的表,这种情况就成了:

       确定了主键字段的值,则其他字段肯定都确定了。

       也可以这样说:

         主键决定了其他字段;

         其他字段依赖于主键;

 

什么叫做部分依赖?

               如果某个字段,只依赖于“部分主键字段”,此时就称为“部分依赖”

                           ——发生此情况的前提一定是:主键字段有多个!!!

什么叫做完全依赖:

     就是某个字段,是依赖于“主键的所有字段”。

             ——推论:如果一个表的主键只有一个字段,则此时必然是完全依赖。

一个不良例子:

                     PHP笔记之MySQL(3)

改进之后:

                                                   PHP笔记之MySQL(3)

第三范式(3NF)

独立性,消除传递依赖:

使每个字段都独立地依赖于主键字段(独立性),而要消除其中部分非主键字段的内部依赖——这种内部依赖会构成“传递依赖”

不良做法:

  PHP笔记之MySQL(3)修正之后: PHP笔记之MySQL(3)

经验总结:

通常,在设计表的时候,基本只要遵循这样一个原则,就可以满足前述3范式要求:

          每一种数据,使用一个表来存储。

数据操作语言:

插入数据(增):

多种语法形式:

形式1:insert [into]  表名 [(字段名1,字段名2,....)] values (值表达式1,值表达式2,....), (.....), ....;

  1. 这是最常用的插入语句,可以一次性插入多行数据,用逗号隔开;
  2. 插入语句,要理解为每次插入数据都是以“行”为单位进行插入。
  3. 字段名通常不推荐省略,其后续的“值列表”应该跟字段名列表“一一对应”;
  4. 其中的值表达式,可以是一个“直接”,或“函数调用结果”,或变量值;其中,如果对应字段是字符或时间类型,则直接值应该使用单引号;

形式2:replace [into] 表名 [(字段名1,字段名2,....)] values (值表达式1,值表达式2,....), (.....), ....;

  1. 其跟insert into几乎一样:唯一区别是,如果插入的数据的主键或唯一键“有重复”,则此时就会变成“修改该行数据”;
  2. PHP笔记之MySQL(3)

形式3:insert [into] 表名 [(字段名1,字段名2,....)] select 字段名1,字段名2,.... from 其他表名;

  1. 将select语句查询的结果数据(可能多条),都插入到指定的表中。
  2. 其中,也需要注意字段的对应:select出来的字段列表,要跟前面指定的字段列表“一一对应”
  3. PHP笔记之MySQL(3)

形式4:insert [into] 表名 set 字段名1=值表达式1,字段名2=值表达式2,....;

load  data(载入数据)语法:

它适用于载入如下图所示“结构整齐的纯文本数据”:

              PHP笔记之MySQL(3)

当然,前提是,有一个这样的对应结构的现有的表:

           PHP笔记之MySQL(3)

载入语法形式:

               load  data  infile  “完整的数据文件的路径”  into  table  表名;

      PHP笔记之MySQL(3)

删除数据(删):

语法形式:

delete  from  表名  【where 条件】 【order by排序字段】 【limit 限定行数】;

说明:

1,删除数据仍然是以“行”为单位进行;

2,通常删除数据都需要带where条件,否则就会删除所有数据(这很不常见);

3,where条件的语法跟select中的语法一样;

4,order by 排序设定,用于指定这些数据的删除顺序;它通常跟limit配合使用才有意义;

5,limit限定用于设定删除多少行(按orderby设定的顺序);

6,实际应用中,通常很少用到orderby和limit,则删除的常规使用形式就成为:

delete  from  表名  where 条件;

                   PHP笔记之MySQL(3)

修改数据(改):

语法形式:

update  表名  set  字段1=值1,字段2=值2,......  【where 条件】 【order by排序字段】 【limit 限定行数】;

说明:

1,通常,update语句,也都需要where条件,否则:就会修改所有数据(这很少见);

2,where条件的语法跟select中的语法一样;

3,order by 用于设定修改的顺序,limit用于设定修改的行数,他们通常也是结合使用(虽然都很少用)

4,实际应用中,通常很少用到orderby和limit,则修改数据的常规使用形式就成为:

update 表名  set  字段1=值1,字段2=值2,......  where 条件

5,注意:其中的“数据值”,如果是字符串或时间类型的“直接值”,就应该用单引号;

举例:

update  tab1  set  name = ‘张三丰’,  age = 18,  birthday = ‘1900-3-4’  where id = 3;

update  tab1  set  name = get_name() ,  age = func1() ,  birthday = now()  where id = 3;

基本查询

基本语法形式

select  [all | distinct]  字段或表达式列表  [from子句]  [where子句]  [group by子句]   [having子句]   [order by子句]   [limit子句];

字段或表达式列表

1,字段,自然是来源于“表”,则其必然依赖于from子句;

2,表达式是类似这样一个内容:8,   8+3,   now(),   

 PHP笔记之MySQL(3) PHP笔记之MySQL(3)

其中:concat()函数是mysql中的系统函数,用于“连接”多个字符串;

3,每个“输出项”(字段或表达式结果),都可以给其设定一个“别名”(字段别名)形式为:

字段或表达式  as  别名;

                 PHP笔记之MySQL(3)

注意:实际上,表的字段并没有改变,而只是改变了“结果集”的字段名;

all 和 distinct

用于设定select出来的数据,是否消除“重复行”,可以不写,那就是默认值all:

all:表示不消除,即所有都出来,默认值;

distinct:表示会消除;

使用all(跟不使用结果是一样的):

 PHP笔记之MySQL(3)对比: PHP笔记之MySQL(3)

from子句

from子句表示select部分从中“取得”数据的数据源——其实就是表。

通常,其后面就是表名; 比如: from  tab1,

但,也可能是其他一些数据来源; from  tab1,tab2(连接表);

select输出(取出)部分,如果给定的是字段名,则其必然是来源于这里的“数据源”的字段;

where子句

说明:

1,where子句就是对from子句中的“数据源”中的数据进行筛选的条件设定,筛选的机制是“一行一行进行判断”,其作用,几乎就跟各种语言中if语句的作用一样。

2,则,可见,where子句依赖于from子句;

3,where子句中,通常都需要使用各种“运算符”;

           算术运算符:  +  -   *   /   %

            比较运算符:  >   >=   <    <=   =(等于)    < >(不等于)   ==(等于)  !=(不等于)

           逻辑运算符:  and   or    not  

  PHP笔记之MySQL(3)

4,对where子句的更进一步理解:

                                     PHP笔记之MySQL(3)

is运算符:空值和布尔值的判断

有4种情况的使用:

    XX  is  null:判断某个字段是“null”值——就是没有值;

    XX  is  not  null:判断某个字段不是“null”值

    XX  is  true:判断某个字段为“真”(true)

    XX  is  false:判断某个字段为“假”(false):0, 0.0,  ‘’,  null

所谓布尔值,其实是tinyint(1)这个类型的一个“别名”,本质上,只是判断一个数字是否为0;

             PHP笔记之MySQL(3)

between运算符:范围判断

用于判断某个字段的数据值是否在某个给定的范围——适用于数字类型;

语法:XX  between  值1  and  值2;

含义:XX字段的值在给定“值1”和“值2”之间,其实相当于:  XX >=值1  and  XX <= 值2;

PHP笔记之MySQL(3)对比:PHP笔记之MySQL(3)

in运算符:给定确定数据的范围判断

语法:XX  in  (值1,值2, 值3, .....);

含义:表示字段XX的值为所列出的这些值中的一个,就算是满足了条件;这些值,通常是零散无规律的。

 

PHP笔记之MySQL(3)

它罗列出的数据,如果有一定的规律,则其实可以使用逻辑运算符或between运算符来代替。

like运算符:对字符串进行模糊查找

语法:XX  like  ‘要查找的内容’

含义:实现对字符串的某种特征信息的模糊查找。它其实依赖于以下2个特殊的“符号”:

               % :它代表“任何个数的任何字符”;

               _ :(下杠),它代表“一个任何字符”;

PHP笔记之MySQL(3)PHP笔记之MySQL(3)

常见示例及含义:

     name  like  ‘%罗%’: 表示nam中“罗”这一个字的所有数据行;

     name  like  ‘罗%’: 表示nam中以“罗”开头的所有数据行;比如:罗兰,

     name  like  ‘%罗’: 表示nam中以“罗”结尾的所有数据行;比如:C罗,魂斗罗

     name  like  ‘罗_’: 表示nam中以“罗”开头并只有2个字符的所有数据行;比如:罗兰

     name  like  ‘_罗’: 表示nam中以“罗”结尾并只有2个字符的所有数据行;比如:C罗

一个新的问题:

   如果我要找某个字段中含“%”(或_)的行,怎么办?转义就ok:

      \% :表示%这个字符本身

     \_ :表示_这个字符本身

例:XX  like  ‘%\%%’; 表示XX中含有百分号(%)这个字符的所有行;

group by 子句:分组

形式:group  by  字段1 【desc|asc】, 字段2 【desc|asc】, .....

说明:

1,分组是对“前述”已经找出的数据(即where已经筛选过了)进行某种指定标准(依据)的分组。

2,同时,该分组结果,可以同时指定其“排序方式”:desc(倒序),asc(顺序);

3,通常,分组就一个字段(依据),2个以上很少。

什么叫做分组?

分组:就是将多行数据,以某种标准(就是指定的字段)来进行“分类”存放。

特别注意:分组之后的结果,一定要理解为:只有一个一个组了

则,结果是:在select语句中的“输出(取出)”部分,只应该出现“组的信息”:

select  组信息1, 组信息2, .....  from  数据源   group  by  字段;

原始数据:

PHP笔记之MySQL(3)分组之后(图示):PHP笔记之MySQL(3)

则我们对这些组(5组),就应该理解为5条数据结果。

应用中,分组之后,通常只有如下几种可用的“组信息”了(即可以出现在select中):

    1,分组依据本身的信息,其实就是该分组依据的字段名;

    2,每一组的“数量”信息:就是用count(*)获得;

    3,原来数据中的“数值类型字段的聚合信息”,包括如下几个:

         最大值:  max(字段名)

        最小值:  min(字段名)

        平均值:  avg(字段名)

        总和值:  sum(字段名)

       上述其实是4个系统内部函数;

PHP笔记之MySQL(3)

结果为:PHP笔记之MySQL(3) 

,表示,每一种品牌的商品数量。

继续举例:

PHP笔记之MySQL(3)

则这个结果的含义就非常明显:

某个品牌有多少件商品,及该品牌的最高价,最低价,平均价和总价,全都出来了。

having子句

一句话:having的作用跟where完全一样,但其只是对“分组的结果数据”进行筛选;

即:

    where对原始数据行进行筛选;

    having对分组之后的数据行进行筛选;

示例1:找出平均价大于5000的品牌信息:

PHP笔记之MySQL(3)

示例2:找出商品数超过2个的品牌信息:

PHP笔记之MySQL(3)

还有一种用法:

PHP笔记之MySQL(3)

可以用以下语句“恢复”(导入)数据:

mysql登录后:source  “备份数据文件的完整路径”

PHP笔记之MySQL(3)

order  by 子句

它用于将前面“取得”的数据以设定的标准(字段)来进行排序以输出结果。

形式:order  by  字段1  【asc|desc】, 字段2  【asc|desc】,......

说明:

1,对前面的结果数据以指定的一个或多个字段排序;

2,排序可以谁定正序(asc,默认值)或倒序(desc);

3,多个字段的排序,都是在前一个字段排序基础上,如果还有“相等值”,才继续以后续字段排序;

举例:

PHP笔记之MySQL(3)

例2:

PHP笔记之MySQL(3)

limit子句

含义:它用于将“前述取得的数据”,按指定的行取出来:从第几行开始取出多少行;

形式:limit  起始行号, 要取出的行数;

说明:

1,起始行号都是从0开始算起的;

2,起始行号跟数据中的任何一个字段(比如id)没有关系;

3,要取出的行数也是一个数字,自然应该是大于0的;

4,有一个简略形式:limit  行数;  表示直接从第0行开始取出指定的行数,它相当于limit  0, 行数;

举例1:

PHP笔记之MySQL(3) PHP笔记之MySQL(3)

PHP笔记之MySQL(3)

对整个select语句的一些总结

1,虽然在形式上,select的很多子句都是可以省略的,但他们的顺序(如果出现),就不能打乱的:必须仍然按照给出的顺序写出;

2,where子句依赖于from子句:即没有from,就不能有where;

3,having子句依赖于group by子句:即没有group by,就不能有having;

4,select中的“字段”也是依赖于from子句;

5,上述各子句的“内部执行过程”,基本上也都是按照该顺序进行的:

即从from的数据源中获得“所有数据”,然后使用where对这些数据进行“筛选”,之后再使用group by子句对筛选出来的数据进行“分组”,接下来才可以使用having对这些分组的数据进行筛选,然后才可以orderby 和limit。其大致图示如下:

                                           PHP笔记之MySQL(3)

 

相关文章:

  • 2021-12-30
  • 2021-11-17
  • 2021-06-13
  • 2022-02-16
  • 2022-12-23
  • 2021-08-03
  • 2021-05-18
猜你喜欢
  • 2022-12-23
  • 2022-01-06
  • 2021-06-17
  • 2021-07-09
  • 2022-01-03
  • 2021-04-05
  • 2021-09-22
相关资源
相似解决方案