MySQL基础第三课

回顾

   

字段类型(列类型): 数值型, 时间日期型和字符串类型php

   

数值型: 整型和小数型(浮点型和定点型)算法

时间日期型: datetime, date,time,timestamp, yearsql

字符串类型: 定长, 变长, 文件字符串(text和blob), 枚举和集合数据库

Mysql记录长度: 65535个字节, varchar达不到理论长度, NULL占用一个字节, text文本不占用记录长度(可是自己占据十个字节)服务器

   

字段属性: 空属性, 列描述, 默认值ide

 

 

字段属性

主键, 惟一键和自增加.函数

   

主键

主键: primary key,主要的键. 一张表只能有一个字段可使用对应的键, 用来惟一的约束该字段里面的数据, 不能重复: 这种称之为主键.测试

一张表只能有最多一个主键.优化

   

增长主键

SQL操做中有多种方式能够给表增长主键: 大致分为三种.spa

   

方案1: 在建立表的时候,直接在字段以后,跟primary key关键字(主键自己不容许为空)

-- 增长主键
create table my_prim1(
name varchar(20) not null comment '姓名',
number char(10) primary key comment '学号: itcast + 0000, 不能重复'
)charset utf8;
View Code

 

优势: 很是直接; 缺点: 只能使用一个字段做为主键

   

方案2: 在建立表的时候, 在全部的字段以后, 使用primary key(主键字段列表)来建立主键(若是有多个字段做为主键,能够是复合主键)

-- 复合主键
create table my_pri2(
number char(10) comment '学号: itcast + 0000',
course char(10) comment '课程代码: 3901 + 0000',
score tinyint unsigned default 60 comment '成绩',
-- 增长主键限制: 学号和课程号应该是对应的,具备惟一性
primary key(number,course)
)charset utf8;
View Code

 

方案3: 当表已经建立好以后, 额外追加主键: 能够经过修改表字段属性, 也能够直接追加。

alter table 表名 add primary key(字段列表);

   

前提: 表中字段对应的数据自己是独立的(不重复)

   

主键约束

主键对应的字段中的数据不容许重复: 一旦重复,数据操做失败(增和改)

   

更新主键 & 删除主键

没有办法更新主键: 主键必须先删除,才能增长.

   

Alter table 表名 drop primary key;

   

主键分类

在实际建立表的过程当中, 不多使用真实业务数据做为主键字段(业务主键,如学号,课程号); 大部分的时候是使用逻辑性的字段(字段没有业务含义,值是什么都没有关系), 将这种字段主键称之为逻辑主键.

   

Create table my_student(

Id int primary key auto_increment comment '逻辑主键: 自增加',    -- 逻辑主键

Number char(10) not null comment '学号',

Name varchar(10) not null

)

   

 

自增加

自增加: 当对应的字段,不给值,或者说给默认值,或者给NULL的时候, 会自动的被系统触发, 系统会从当前字段中已有的最大值再进行+1操做,获得一个新的不一样的字段.

   

自增加一般是跟主键搭配.

   

新增自增加

自增加特色: auto_increment

  1. 任何一个字段要作自增加必须前提是自己是一个索引(key一栏有值)

  2.自增加字段必须是数字(整型)

  3.一张表最多只能有一个自增加

 

 

自增加使用

当自增加被给定的值为NULL或者默认值的时候会触发自动增加.

自增加若是对应的字段输入了值,那么自增加失效: 可是下一次仍是可以正确的自增加(从最大值+1)

如何肯定下一次是什么自增加呢? 能够经过查看表建立语句看到.

以下图:AUTO_INCREMENT=8 即表示该自增加的下一个值为8

修改自增加

自增加若是是涉及到字段改变: 必须先删除自增加,后增长(一张表只能有一个自增加)

修改当前自增加已经存在的值: 修改只能比当前已有的自增加的最大值大,不能小(小不生效)

Alter table 表名 auto_increment = 值;

向上修改能够

思考: 为何自增加是从1开始?为何每次都是自增1呢?

全部系统的变量(如字符集,校对集)都是由系统内部的变量进行控制的.

查看自增加对应的变量: show variables like 'auto_increment%';

能够修改变量实现不一样的效果: 修改是对整个数据修改,而不是单张表: (修改是会话级)

会话级:表示只对当前本次有效,关闭了数据库链接以后,就失效了

Set auto_increment_increment = 5; -- 一次自增5

测试效果: 自动使用自增加

删除自增加

自增加是字段的一个属性: 能够经过modify来进行修改(保证字段没有auto_increment便可)

Alter table 表名 modify 字段 类型;

惟一键

一张表每每有不少字段须要具备惟一性,数据不能重复: 可是一张表中只能有一个主键: 惟一键(unique key)就能够解决表中有多个字段须要惟一性约束的问题.

惟一键的本质与主键差很少: 惟一键默认的容许自动为空,并且能够多个为空(空字段不参与惟一性比较)

增长惟一键

基本与主键差很少: 三种方案

方案1: 在建立表的时候,字段以后直接跟unique/ unique key

方案2: 在全部的字段以后增长unique key(字段列表); -- 复合惟一键

方案3: 在建立表以后增长惟一键

惟一键约束

惟一键与主键本质相同: 惟一的区别就是惟一键默认容许为空,并且是多个为空.

若是惟一键也不容许为空: 与主键的约束做用是一致的.

更新惟一键 & 删除惟一键

更新惟一键: 先删除后新增(惟一键能够有多个: 能够不删除).

删除惟一键

Alter table 表名 drop unique key; -- 错误: 惟一键有多个

Alter table 表名 drop index 索引名字; -- 惟一键默认的使用字段名做为索引名字

索引

几乎全部的索引都是创建在字段之上.

索引: 系统根据某种算法, 将已有的数据(将来可能新增的数据),单独创建一个文件: 文件可以实现快速的匹配数据, 而且可以快速的找到对应表中的记录.

索引的意义

 

  1. 提高查询数据的效率
  2. 约束数据的有效性(惟一性等)

    增长索引的前提条件: 索引自己会产生索引文件(有时候有可能比数据文件还大) ,会很是耗费磁盘空间.

    若是某个字段须要做为查询的条件常用, 那么可使用索引(必定会想办法增长);

    若是某个字段须要进行数据的有效性约束, 也可能使用索引(主键,惟一键)

    Mysql中提供了多种索引

  3. 主键索引: primary key
  4. 惟一索引: unique key
  5. 全文索引: fulltext index
  6. 普通索引: index

    全文索引: 针对文章内部的关键字进行索引

    全文索引最大的问题: 在于如何肯定关键字

    英文很容易: 英文单词与单词之间有空格

    中文很难: 没有空格, 并且中文能够各类随意组合(分词: sphinx)

    关系

    将实体与实体的关系, 反应到最终数据库表的设计上来: 将关系分红三种: 一对一, 一对多(多对一)和多对多.

    全部的关系都是指的表与表之间的关系.

    一对一

    一对一: 一张表的一条记录必定只能与另一张表的一条记录进行对应; 反之亦然.

    学生表: 姓名,性别,年龄,身高,体重,婚姻情况, 籍贯, 家庭住址,紧急联系人

Id(P) 

姓名 

性别

年龄 

体重 

身高 

婚姻 

籍贯 

住址 

联系人 

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

   

表设计成以上这种形式: 符合要求. 其中姓名,性别,年龄,身高,体重属于经常使用数据; 可是婚姻,籍贯,住址和联系人属于不经常使用数据. 若是每次查询都是查询全部数据,不经常使用的数据就会影响效率, 实际又不用.

   

解决方案: 将经常使用的和不经常使用的信息分离存储,分红两张表

经常使用信息表

Id(P) 

姓名 

性别 

年龄 

体重 

身高 

  

  

  

  

  

  

  

  

  

  

  

   

不经常使用信息表: 保证不经常使用信息与经常使用信息必定可以对应上: 找一个具备惟一性(肯定记录)的字段来共同链接两张表

Id(P) 

婚姻 

籍贯 

住址 

联系人 

  

  

  

  

  

  

  

  

   

一个经常使用表中的一条记录: 永远只能在一张不经常使用表中匹配一条记录;反过来,一个不经常使用表中的一条记录在经常使用表中也只能匹配一条记录: 一对一的关系

   

一对多

一对多: 一张表中有一条记录能够对应另一张表中的多条记录; 可是返回过, 另一张表的一条记录只能对应第一张表的一条记录. 这种关系就是一对多或者多对一.

   

母亲与孩子的关系: 母亲,孩子两个实体

妈妈表

ID(P) 

名字 

年龄 

性别 

  

  

  

  

  

  

  

  

   

孩子表

ID(P) 

名字 

年龄 

性别 

  

  

  

  

  

  

  

  

   

以上关系: 一个妈妈能够在孩子表中找到多条记录(也有多是一条); 可是一个孩子只能找到一个妈妈: 是一种典型的一对多的关系.

   

可是以上设计: 解决了实体的设计表问题, 可是没有解决关系问题: 孩子找不出妈,妈也找不到孩子.

   

解决方案: 在某一张表中增长一个字段,可以找到另一张表的中记录: 应该在孩子表中增长一个字段指向妈妈表: 由于孩子表的记录只能匹配到一条妈妈表的记录.

   

妈妈表

ID(P) 

名字 

年龄

性别 

  

  

  

  

  

  

  

  

   

孩子表

ID(P) 

名字 

年龄 

性别 

妈妈ID

  

  

  

  

妈妈表主键 

  

  

  

  

  

   

   

多对多

多对多: 一张表中(A)的一条记录可以对应另一张表(B)中的多条记录; 同时B表中的一条记录也能对应A表中的多条记录: 多对多的关系

   

老师教学: 老师和学生

老师表

T_ID(P) 

姓名 

性别 

男 

女 

   

学生表

S_ID(P) 

姓名 

性别 

张三 

男 

小芳 

女 

   

以上设计方案: 实现了实体的设计, 可是没有维护实体的关系.

一个老师教过多个学生; 一个学生也被多个老师教过.

   

解决方案: 在学生表中增长老师字段: 无论在哪张表中增长字段, 都会出现一个问题: 该字段要保存多个数据, 并且是与其余表有关系的字段, 不符合表设计规范: 增长一张新表: 专门维护两张表之间的关系

老师表

T_ID(P) 

姓名 

性别 

男 

女 

   

学生表

S_ID(P) 

姓名 

性别 

张三 

男 

小芳 

女 

   

中间关系表: 老师与学生的关系

ID 

T_ID(老师)

S_ID(学生)

4

  

  

   

增长中间表以后: 中间表与老师表造成了一对多的关系: 并且中间表是多表,维护了可以惟一找到一表的关系; 一样的,学生表与中间表也是一个一对多的关系: 一对多的关系能够匹配到关联表之间的数据.

   

学生找老师: 找出学生id -> 中间表寻找匹配记录(多条) -> 老师表匹配(一条)

老师找学生: 找出老师id -> 中间表寻找匹配记录(多条) -> 学生表匹配(一条)

   

   

范式

范式: Normal Format, 是一种离散数学中的知识, 是为了解决一种数据的存储与优化的问题: 保存数据的存储以后, 凡是可以经过关系寻找出来的数据,坚定再也不重复存储: 终极目标是为了减小数据的冗余.

   

范式: 是一种分层结构的规范, 分为六层: 每一次层都比上一层更加严格: 若要知足下一层范式,前提是知足上一层范式.

   

六层范式: 1NF,2NF,3NF...6NF, 1NF是最底层,要求最低;6NF最高层,最严格.

   

Mysql属于关系型数据库: 有空间浪费: 也是致力于节省存储空间: 与范式全部解决的问题不谋而合: 在设计数据库的时候, 会利用到范式来指导设计.

可是数据库不单是要解决空间问题,要保证效率问题: 范式只为解决空间问题, 因此数据库的设计又不可能彻底按照范式的要求实现: 通常状况下,只有前三种范式须要知足.

   

范式在数据库的设计当中是有指导意义: 可是不是强制规范.

   

1NF

第一范式: 在设计表存储数据的时候, 若是表中设计的字段存储的数据,在取出来使用以前还须要额外的处理(拆分),那么说表的设计不知足第一范式: 第一范式要求字段的数据具备原子性: 不可再分.

   

讲师代课表

讲师

性别

班级

教室

代课时间

代课时间(开始,结束)

朱元璋

Male

php0226

D302

30天

2014-02-27,2014-05-05

朱元璋

Male

php0320

B206

30天

2014-03-21,2014-05-30

李世民

Male

php0320

B206

15天

2014-06-01,2014-06-20

   

上表设计不存在问题: 可是若是需求是将数据查出来以后,要求显示一个老师从何时开始上课,到何时节课: 须要将代课时间进行拆分: 不符合1NF, 数据不具备原子性, 能够再拆分.

   

解决方案: 将代课时间拆分红两个字段就解决问题.

   

2NF

第二范式: 在数据表设计的过程当中,若是有复合主键(多字段主键), 且表中有字段并非由整个主键来肯定, 而是依赖主键中的某个字段(主键的部分): 存在字段依赖主键的部分的问题, 称之为部分依赖: 第二范式就是要解决表设计不容许出现部分依赖.

   

讲师带课表

   

以上表中: 由于讲师没有办法做为独立主键, 须要结合班级才能做为主键(复合主键: 一个老师在一个班永远只带一个阶段的课): 代课时间,开始和结束字段都与当前的代课主键(讲师和班级): 可是性别并不依赖班级, 教室不依赖讲师: 性别只依赖讲师, 教室只依赖班级: 出现了性别和教室依赖主键中的一部分: 部分依赖.不符合第二范式.

   

解决方案1: 能够将性别与讲师单独成表, 班级与教室也单独成表.

解决方案2: 取消复合主键, 使用逻辑主键

   

ID = 讲师 + 班级(业务逻辑约束: 复合惟一键)

   

   

3NF

要知足第三范式,必须知足第二范式.

   

第三范式: 理论上讲,应该一张表中的全部字段都应该直接依赖主键(逻辑主键: 表明的是业务主键), 若是表设计中存在一个字段, 并不直接依赖主键,而是经过某个非主键字段依赖,最终实现依赖主键: 把这种不是直接依赖主键,而是依赖非主键字段的依赖关系称之为传递依赖. 第三范式就是要解决传递依赖的问题.

   

讲师带课表

   

以上设计方案中: 性别依赖讲师存在, 讲师依赖主键; 教室依赖班级,班级依赖主键: 性别和教室都存在传递依赖.

   

解决方案: 将存在传递依赖的字段,以及依赖的字段自己单独取出,造成一个单独的表, 而后在须要对应的信息的时候, 使用对应的实体表的主键加进来.

讲师代课表

讲师表                                    班级表

   

讲师表: ID = 讲师                        班级表中: ID = 班级

   

逆规范化

   

有时候, 在设计表的时候,若是一张表中有几个字段是须要从另外的表中去获取信息. 理论上讲, 的确能够获取到想要的数据, 可是就是效率低一点. 会刻意的在某些表中,不去保存另外表的主键(逻辑主键), 而是直接保存想要的数据信息: 这样一来,在查询数据的时候, 一张表能够直接提供数据, 而不须要多表查询(效率低), 可是会致使数据冗余增长.

   

如讲师代课信息表

   

逆规范化: 磁盘利用率与效率的对抗

   

   

数据高级操做

数据操做: 增删改查

   

新增数据

基本语法

Insert into 表名 [(字段列表)] values (值列表);

   

在数据插入的时候, 假设主键对应的值已经存在: 插入必定会失败!(由于主键值的惟一性)

   

主键冲突

当主键存在冲突的时候(Duplicate key),能够选择性的进行处理: 更新和替换

   

主键冲突: 更新操做

Insert into 表名[(字段列表:包含主键)] values(值列表) on duplicate key update 字段 = 新值;

   

主键冲突: 替换

Replace into 表名 [(字段列表:包含主键)] values(值列表);

   

蠕虫复制

蠕虫复制: 从已有的数据中去获取数据,而后将数据又进行新增操做: 数据成倍的增长.

   

表建立高级操做: 从已有表建立新表(复制表结构)

Create table 表名 like 数据库.表名;

   

蠕虫复制: 先查出数据, 而后将查出的数据新增一遍

Insert into 表名[(字段列表)] select 字段列表/* from 数据表名;

   

蠕虫复制的意义

  1. 从已有表拷贝数据到新表中(也能够从本身的表中复制数据到本身表中,也就是自我复制,可是复制的时候不要复制主键,由于这会引发主键冲突)
  2. 能够迅速的让表中的数据膨胀到必定的数量级: 测试表的压力以及效率

       

       

     

    更新数据

     

    基本语法

    Update 表名 set 字段 = 值 [where条件];

       

    高级新增语法

    Update 表名 set 字段 = 值 [where条件] [limit 更新数量];

       

     

    删除数据

     

    与更新相似: 能够经过limit来限制数量

    Delete from 表名 [where条件] [limit 数量];

       

    删除: 若是表中存在主键自增加,那么当删除以后, 自增加不会还原

       

    思路: 数据的删除是不会改变表结构, 只能删除表后重建表

    Truncate 表名;    -- 先删除改变,后新增改变

       

     

    查询数据

     

    基本语法

    Select 字段列表/* from 表名 [where条件];

       

    完整语法

    Select [select选项] 字段列表[字段别名]/* from 数据源 [where条件子句] [group by子句] [having子句] [order by子句] [limit 子句];

       

     

    Select选项

     

    Select选项: select对查出来的结果的处理方式

    All: 默认的,保留全部的结果

    Distinct: 去重, 查出来的结果,将重复给去除(全部字段都相同)

       

     

    字段别名

     

    字段别名: 当数据进行查询出来的时候, 有时候名字并必定就知足需求(多表查询的时候, 会有同名字段). 须要对字段名进行重命名: 别名

       

    语法

    字段名 [as] 别名;

       

       

     

    数据源

     

    数据源: 数据的来源, 关系型数据库的来源都是数据表: 本质上只要保证数据相似二维表,最终均可以做为数据源.

       

    数据源分为多种: 单表数据源, 多表数据源, 查询语句

       

    单表数据源: select * from 表名;

       

    多表数据源: select* from 表名1,表名2...;

    从一张表中取出一条记录,去另一张表中匹配全部记录,并且所有保留:(记录数和字段数),将这种结果成为: 笛卡尔积(交叉链接): 笛卡尔积没什么卵用, 因此应该尽可能避免.

       

    子查询: 数据的来源是一条查询语句(查询语句的结果是二维表)

    Select * from (select 语句) as 表名;

       

       

     

    Where子句

     

    Where子句: 用来判断数据,筛选数据.

    Where子句返回结果: 0或者1, 0表明false,1表明true.

       

    判断条件:

    比较运算符: >, <, >=, <= ,!= ,<>, =, like, between and, in/not in

    逻辑运算符: &&(and), ||(or), !(not)

       

    Where原理: where是惟一一个直接从磁盘获取数据的时候就开始判断的条件: 从磁盘取出一条记录, 开始进行where判断: 判断的结果若是成立保存到内存;若是失败直接放弃.

       

       

    条件查询1: 要求找出学生id为1或者3或者5的学生

       

    条件查询2: 查出区间落在180,190身高之间的学生:

       

    Between自己是闭区间; between左边的值必须小于或者等于右边的值

       

     

    Group by子句

     

    Group by:分组的意思, 根据某个字段进行分组(相同的放一组,不一样的分到不一样的组)

       

    基本语法: group by 字段名;

       

    分组的意思: 是为了统计数据(按组统计: 按分组字段进行数据统计)

    SQL提供了一系列统计函数

    Count(): 统计分组后的记录数: 每一组有多少记录

    Max():    统计每组中最大的值

    Min(): 统计最小值

    Avg(): 统计平均值

    Sum(): 统计和

       

    Count函数: 里面可使用两种参数: *表明统计记录,字段名表明统计对应的字段(NULL不统计)

       

       

    分组会自动排序: 根据分组字段:默认升序

    Group by 字段 [asc|desc];    -- 对分组的结果合并以后的整个结果进行排序

       

    多字段分组: 先根据一个字段进行分组,而后对分组后的结果再次按照其余字段进行分组

       

    有一个函数: 能够对分组的结果中的某个字段进行字符串链接(保留该组全部的某个字段): group_concat(字段);

       

    回溯统计: with rollup: 任何一个分组后都会有一个小组, 最后都须要向上级分组进行汇报统计: 根据当前分组的字段. 这就是回溯统计: 回溯统计的时候会将分组字段置空.

       

    多字段回溯: 考虑第一层分组会有此回溯: 第二次分组要看第一次分组的组数, 组数是多少,回溯就是多少,而后加上第一层回溯便可.

       

     

    Having子句

     

    Having子句: 与where子句同样: 进行条件判断的.

       

    Where是针对磁盘数据进行判断: 进入到内存以后,会进行分组操做: 分组结果就须要having来处理.

       

    Having能作where能作的几乎全部事情, 可是where却不能作having能作的不少事情.

       

  3. 分组统计的结果或者说统计函数都只有having可以使用.

  4. Having可以使用字段别名: where不能: where是从磁盘取数据,而名字只多是字段名: 别名是在字段进入到内存后才会产生.

       

     

    Order by子句

     

    Order by: 排序, 根据某个字段进行升序或者降序排序, 依赖校对集.

       

    使用基本语法

    Order by 字段名 [asc|desc]; -- asc是升序(默认的),desc是降序

       

    排序能够进行多字段排序: 先根据某个字段进行排序, 而后排序好的内部,再按照某个数据进行再次排序:

       

       

     

    Limit子句

     

    Limit子句是一种限制结果的语句: 限制数量.

       

    Limit有两种使用方式

       

    方案1: 只用来限制长度(数据量): limit 数据量;

       

    方案2: 限制起始位置,限制数量: limit 起始位置,长度;

       

    Limit方案2主要用来实现数据的分页: 为用户节省时间,提交服务器的响应效率, 减小资源的浪费.

    对于用户来说: 能够点击的分页按钮: 1,2,3,4

    对于服务器来说: 根据用户选择的页码来获取不一样的数据: limit offset,length;

       

    Length: 每页显示的数据量: 基本不变

    Offset: offset = (页码 - 1) * 每页显示量

 

对应sql脚本代码:

-- 增长主键

 

create table my_pri1(

name varchar(20) not null comment '姓名',

number char(10) primary key comment '学号: itcast + 0000, 不能重复'

)charset utf8;

 

-- 复合主键

create table my_pri2(

number char(10) comment '学号: itcast + 0000',

course char(10) comment '课程代码: 3901 + 0000',

score tinyint unsigned default 60 comment '成绩',

-- 增长主键限制: 学号和课程号应该是个对应的,具备惟一性

primary key(number,course)

)charset utf8;

 

-- 追加主键

create table my_pri3(

course char(10) not null comment '课程编号: 3901 + 0000',

name varchar(10) not null comment '课程名字'

);

 

alter table my_pri3 modify course char(10) primary key comment '课程编号: 3901 + 0000';

alter table my_pri3 add primary key(course);

 

-- 向pri1表插入数据

insert into my_pri1 values('古学星','itcast0001'),('蔡仁湾','itcast0002');

insert into my_pri2 values('itcast0001','39010001',90),('itcast0001','39010002',85),('itcast0002','39010001',92);

 

-- 主键冲突(重复)

insert into my_pri1 values('刘辉','itcast0002'); -- 不能够: 主键冲突

insert into my_pri2 values('itcast0001','39010001',100); -- 不能够:冲突

 

-- 删除主键

alter table my_pri3 drop primary key;

 

-- 自增加

create table my_auto(

id int primary key auto_increment comment '自动增加',

name varchar(10) not null

)charset utf8;

 

-- 触发自增加

insert into my_auto(name) values('邓立军');

insert into my_auto values(null,'龚森');

insert into my_auto values(default,'张滔');

 

-- 指定数据

insert into my_auto values(6,'何思华');

insert into my_auto values(null,'陈少炼');

 

 

-- 修改表选项的值

alter table my_auto auto_increment = 4; -- 向下修改(小)

alter table my_auto auto_increment = 10; -- 向上修改

 

-- 查看自增加变量

show variables like 'auto_increment%';

 

-- 修改自增加步长

set auto_increment_increment = 5;

 

-- 插入记录: 使用自增加

insert into my_auto values(null,'刘阳');

insert into my_auto values(null,'邓贤师');

 

-- 删除自增加

alter table my_auto modify id int primary key; -- 错误: 主键理论是单独存在

alter table my_auto modify id int; -- 有主键的时候,千万不要再加主键

 

-- 惟一键

create table my_unique1(

number char(10) unique comment '学号: 惟一,容许为空',

name varchar(20) not null

)charset utf8;

 

create table my_unique2(

number char(10) not null comment '学号',

name varchar(20) not null,

-- 增长惟一键

unique key(number)

)charset utf8;

 

create table my_unique3(

id int primary key auto_increment,

number char(10) not null,

name varchar(20) not null)charset utf8;

 

-- 追加惟一键

alter table my_unique3 add unique key(number);

 

-- 插入数据

insert into my_unique1 values(null,'曾光'),('itcast0001','晁松'),(null,'李帅');

insert into my_unique1 values('itcast0001','周江');

 

-- 删除惟一键

alter table my_unique3 drop index number;

 

-- 插入数据

insert into my_class values('PHP0810','B203');

insert into my_class values('PHP0810','B205');

insert into my_class values('PHP0710','B203');

 

-- 主键冲突: 更新

insert into my_class values('PHP0810','B205')

-- 冲突处理

on duplicate key update

-- 更新教室

room = 'B205';

 

-- 主键冲突:替换

replace into my_class values('PHP0710','A203');

replace into my_class values('PHP0910','B207');

 

-- 复制建立表

create table my_copy like my_gbk;

 

-- 蠕虫复制

insert into my_copy select * from my_collate_bin;

insert into my_copy select * from my_copy;

 

 

-- 更新部分a变成c

update my_copy set name = 'c' where name = 'a' limit 3;

 

 

-- 删除数据:限制记录数为10

delete from my_copy where name = 'b' limit 10;

 

-- 清空表: 重置自增加

truncate my_student;

 

-- select选项

select * from my_copy;

select all * from my_copy;

 

-- 去重

select distinct * from my_copy;

 

 

insert into my_student values(null,'itcast0001','张三',''),

(null,'itcast0002','李四',''),

(null,'itcast0003','王五',''),

(null,'itcast0004','赵六',''),

(null,'itcast0005','小明','');

 

-- 字段别名

select

id,

number as 学号,

name as 姓名,

sex 性别 from my_student;

 

-- 多表数据源

select * from my_student,my_class;

 

 

-- 子查询

select * from (select * from my_student) as s;

 

-- 增长age和height字段

alter table my_student add age tinyint unsigned;

alter table my_student add height tinyint unsigned;

 

-- 增长值: rand取得一个0到1之间的随机数, floor向下取整

update my_student set age=floor(rand() * 20 + 20),height = floor(rand()*20 + 170);

 

-- 找学生id为1,3,5的学生

select * from my_student where id = 1 || id = 3 || id = 5; -- 逻辑判断

select * from my_student where id in(1,3,5); -- 落在集合中

 

-- 找身高在180到190之间的学生

select * from my_student where height >= 180 and height <= 190;

select * from my_student where height between 180 and 190;

 

select * from my_student where height between 190 and 180;

 

-- 根据性别分组

select * from my_student group by sex;

 

-- 分组统计: 身高高矮,年龄平均和总年龄

select sex,count(*),max(height),min(height),avg(age),sum(age) from my_student group by sex;

select sex,count(*),count(age),max(height),min(height),avg(age),sum(age) from my_student group by sex;

select sex,count(*),count(age),max(height),min(height),avg(age),sum(age) from my_student group by sex desc;

 

-- 多字段分组: 先班级,后男女

select c_id,sex,count(*),group_concat(name) from my_student group by c_id,sex; -- 多字段排序

 

 

-- 统计

select c_id,count(*) from my_student group by c_id;

 

-- 回溯统计

select c_id,count(*) from my_student group by c_id with rollup;

 

-- 多字段分组回溯统计

select c_id,sex,count(*),group_concat(name) from my_student group by c_id,sex; -- 多字段排序

select c_id,sex,count(*),group_concat(name) from my_student group by c_id,sex with rollup;

 

 

-- 求出全部班级人数大于等于2的学生人数

select c_id,count(*) from my_student group by c_id having count(*) >= 2;

select c_id,count(*) from my_student where count(*) >= 2 group by c_id ;

 

select c_id,count(*) as total from my_student group by c_id having total >= 2;

select c_id,count(*) as total from my_student where total >= 2 group by c_id ;

 

-- 排序

select * from my_student group by c_id;

select * from my_student order by c_id;

 

-- 多字段排序: 先班级排序,后性别排序

select * from my_student order by c_id, sex desc;

 

-- 查询学生: 前两个

select * from my_student limit 2;

 

-- 查询学生: 前两个

select * from my_student limit 0,2; -- 记录数是从0开始编号

select * from my_student limit 2,2;

select * from my_student limit 4,2;
View Code
相关文章
相关标签/搜索