MySQL表的约束和表的增删查改

Posted 两片空白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL表的约束和表的增删查改相关的知识,希望对你有一定的参考价值。

目录

一.表的约束

        1.1 空属性

         1.2 默认值

         1.3 列描述

         1.4 zerofill

        1.5 主键

         1.6 自增长

         1.7 唯一键

         1.8 外键

二.表的增删查改

        2.1 Create(创建)

        2.2 Retrieve(读取)

         2.2.1 全列查询

        2.2.2 指定列查询

         2.2.3 查询字段为自定义表达式

         2.2.4 为查询结果指定别名

         2.2.5 对查询结果去重

         2.2.6 where 条件

        2.2.7 排序

        2.2.8 筛选分页结果

        2.3 Update(更新)

        2.4 Delete(删除)

        2.4.1 删除数据

        2.4.2 截断表

                 2.5 插入查询结果

         2.6 聚合函数

         2.7 group by子句使用


一.表的约束

        mysql管理用户数据的软件,需要严格的保证数据的正确性和安全性。于是,MySQL对用户输入的数据增加了许多约束。比如:数据的类型,当数据超过类型的最大长度,会直接报错。但是,只有类型进行约束是很单一的。MySQL还增加了很多额外的约束,下面介绍。

        MySQL表的约束,倒逼着用户输入数据时,必须数据正确的数据。约束条件越严格,数据越精确越安全。

        1.1 空属性

  • 两个值:null(空,默认)和not null(不为空)
  • 作用:null约束表中字段可以设为空,not null约束表中字段不可设为空。

 案例:

 插入数据插入空时会失败:

         1.2 默认值

        默认值:当用户将一字段设定默认值,当用户插入数据时,不插入值,会使用默认值。

当对设置默认值的字段不插入值时,会使用默认值:

 注意:如果没有设定默认值,并且不能为空,插入时,必须插入值。

default和not null一般不需要同时约束一个字段,应为本身会有默认值。 

         1.3 列描述

        列描述:comment:用来描述当前字段的含义。

         1.4 zerofill

  • 作用:可以显示字段的长度。

         总结一下:zerofill是一种格式化输出,当长度小于设置长度,剩余长度填充0。虽然填充了0,实际值并没有发生改变。

        1.5 主键

  • 语法:用primary key修饰字段。
  • 作用:该字段里的数据不能有重复,不能为空,一张表中最多只有一个主键;主键修饰的字段一般是整数类型。

案例:

  • 创建表,其中字段用约束为主键

  •  插入数据

  •  当表创建好,但是忘记设置主键约束,可以再次追加主键约束条件。

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

  •  删除主键

alter   table   表名  drop  primary  key;//不需要加字段名称,因为一个表中只有一个主键。

  •  复合主键

        当一个表中想设置多个字段为主键,可以使用复合主键。

语法:在创建表示,增加primary key(主键字段列表)。

 一个表中只能有一个主键,为什么这里可以出现多个主键呢?

        这里的多个主键实际上也只是一个主键,需要所有主键字段组合才真正构成主键。意思就是,需要两个都一样才会构成冲突。但是,两个主键都不能设置为空。

         1.6 自增长

语法:创建表时,用auto_increment修饰字段。

功能:不给值时,系统会自动触发,会进行从当前字段中已经有的最大值加1操作。

通常和主键搭配使用,作为逻辑主键。

特点:

  • 任何字段要做自增长,前提本身时索引(key一栏有值)。
  • 自增长字段必须是整数。
  • 一张表最多只能有一个自增长。

案例:

  •  插入数据:

  •  修改自增初始值

一种方式:创建时修改初始值

 一种方式,在第一次插入时,设置自增字段的值。

  •  查询上一次自增值。

         1.7 唯一键

语法:在字段约束加上unique。

作用:唯一键修饰的字段不能有重复数据。

        表中往往有很多字段需要唯一性,数据不能重复。但是一张表中只有一个主键,唯一键解决了有多个字段需要唯一性的约束问题。

        唯一键和主键功能相似,它们的区别在于:

  • 唯一键可以有多个。
  • 唯一键可以一个或者多个为空。
  • 唯一键不需要全部唯一键和已经插入值一样才冲突。
  • 主键主要是用在与业务无关的字段,避免因为业务改变主键也需要改变
  • 唯一键主要是用在与业务相关的字段。 

         1.8 外键

        一种情况,现实生活中,一种场景下,可能需要记录的数据会很多。如果将其记录在一张表中,会导致一张表的数据量很大,并且用户看起来麻烦。我们可以将数据拆除成多个表,使用一个字段,使表与表之间产生联系。

        使一张表和另外一张表产生联系的字段为外键。含有外键的表叫从表,不含有外键的表叫主表。

        外键的约束是,为了保证两个表信息一致。如果删除某个表的信息时,可能另外一个表中还保存着删除字段的信息,导致信息不一致,这时会报错。必须键要删除的信息全部删除。

        删除信息时,需要先删除从表中需要删除的数据,再来删除主表中的数据。

语法:foreign  key (字段名) references  主表列;

作用:使两张表产生联系。

        外键用来定义主表和从表之间的关系,外键约束主要定义在从表上,主表必须是有主键约束或者unique约束。当定义外键后,要求外键列数据必须在主表的主键列存在或者为空。

  •  正常插入数据

  •  如果插入不在主表的id数据中:会导致两个表数据不一致。

  •  但是可以插入空值

  •  删除主表某一字段

        先删除从表中字段含有的信息,才能删除主表的字段。

 如何理解外键约束:

        上面的例子,如果我们不建立外键约束。我们也可以正常创建这两个表,但是两个表的联系需要我们用户来注意。

比如:删除一个班级,需要将班级里的所有学生信息都要删除。如果用户疏忽,导致忘记删除或者将学生信息插入到了一个不在班级表中的班级,这样就会出现问题。需要用户自己注意这样成本是很高的。

于是将这种联系的审核交给了MySQL。当我们错误插入,或者未将数据删除干净时,MySQL会提醒我们,约束我们必须做出正确的操作。

二.表的增删查改

        CRUD:Create(创建),Retrieve(读取),Update(更新),Delete(删除)。

        2.1 Create(创建)

        在表种插入字段。

语法:insert   into   表名   (字段)   values   (字段具体值) 

案例:

创建一张表:

  •  单行数据,全部插入

  •  多行数据,指定列插入

注意:前面的字段和后面的数据必须顺序一致。 

  • 插入,否则更新

由于主键或者唯一键对应的值已经存在,导致插入失败。

 如果插入失败,可以选择进行更新,如果插入成功直接插入。

语法:insert   into   表名   (字段)   values   (字段具体值)  on duplicate  key  update  (具体更新字段)

 通过MySQL函数获取受影响的数据行数。

  •  替换

主键或者唯一键没有冲突,直接插入。

主键或者唯一键冲突,则删除后插入

语法: replace into  表名 (字段)  values (字段对应具体数据)

         2.2 Retrieve(读取)

语法:

SELECT   [DISTINCT]    * | column [, column] ...   [FROM table_name]    [WHERE ...] [ORDER BY column [ASC | DESC], ...]      LIMIT ...

案例:

创建一个表,并且插入数据:

         2.2.1 全列查询

  • 一般不建议使用全列查询
    • 查询的列越多,MySQL是网络服务,意味着传输的数据量越大。
    • 可能会影响到索引的使用。

        2.2.2 指定列查询

执行列的顺序不需要按照创建表的顺序输入。

         2.2.3 查询字段为自定义表达式

  • 表达式不包含表中的字段

  •  表达式中包含一个字段

  •  表达式包含多个字段

 注意:自定义表达式并没有修改表,只是修改显示的值。

         2.2.4 为查询结果指定别名

语法:select   字段名  as(可省略)  别名   from  表名;

         2.2.5 对查询结果去重

         2.2.6 where 条件

比较运算符: 

逻辑运算符:

 案例:

//英语不及格的同学及英语成绩 (<60)
select name,english from exam_result where english < 60;

//语文成绩在 [80, 90] 分的同学及语文成绩
//用逻辑and
select name, chinese from exam_result where chinese>=80 and chinese<=90;
//用between...and...
select name, chinese from exam_result where chinese between 80 and 90;

//数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩
//用or连接
select name, math from exam_result where math=58 or  math=59 or math=98 or math=99;
//用in
select name, math from exam_result where math in (58,59,98,99);

// 姓孙的同学
select name from exam_result where name like '孙%';

//查询孙某同学
select name from exam_result where name like '孙_';

//语文成绩好于英语成绩的同学
select name, chinese, english from exam_result where chinese > english;
// 总分在 200 分以下的同学
select name, chinese+english+math '总分' from exam_result where chinese+english+math < 200;

注意别名不能出现在where中:

//语文成绩 > 80 并且不姓孙的同学
select name, chinese from exam_result where chinese > 80 and name not like '孙%';

// 孙某同学,否则要求总成绩 > 200 并且 语文成绩 < 数学成绩 并且 英语成绩 > 80
select name, chinese+english+math '总分', chinese, math, english from exam_result where name like '孙_' or 
(chinese+english+math > 200 and chinese<math and english>80);
  • null 查询
//查询qq为null
select * from students where qq is null;

//查询qq不为空
select * from students where qq is not null;
  • null和null比较

'='不起作用,比出来都是空。

 '<=>'起作用

        2.2.7 排序

语法:select... from 表名   [WHERE ...]  order  by   字段   [ASC|DESC], [...];

ASC:升序。从小到大

DESC:降序。从大到小

注意:没有order  by的子句查询,返回的顺序都是未定义的。

注意:字段数据为空,比任何值都小。

//同学及数学成绩,按数学成绩升序显示
select name, math from exam_result order by math;//默认升序
select name, math from exam_result order by math asc;
//查询同学各门成绩,依次按 数学降序,英语升序,语文升序的方式显示
select name, math, chinese, english from exam_result order by math desc, english, chinese;

// 查询同学及总分,由高到低
select name, chinese+english+math from exam_result order by chinese+english+math desc;
//可以使用别名
select name, chinese+english+math '总分' from exam_result order by 总分 desc;

//查询姓孙的同学或者姓曹的同学数学成绩,结果按数学成绩由高到低显示
//可以使用where的结果来进行排序
select name, math from exam_result where name like '曹%' or name like '孙%' order by math desc;

        2.2.8 筛选分页结果

语法:

从0,开始筛选n条结果

select ... from  表名  [where ...]  [order by ...]  limit  n

从s位置开始,筛选出n条结果

select ... from  表名  [where ...]  [order by ...]  limit  s ,n

从s位置开始,筛选出n条结果,比第二种更加明确

select ... from  表名  [where ...]  [order by ...]  limit  n  offset  s

        建议:对位置表进行查询时,最好加一条limit 1,避免表中数据过大,查询全表数据导致数据库卡死。

案例:

按id进行分页,每页3条记录,分别显示第1,2,3页。

         2.3 Update(更新)

语法:update  表名  set  字段=更新数据  [where ...]  [order by...] [limit ...]

对查询的结果进行更新。

  • 修改单个数据

  •  修改多个数据
将曹孟德同学的数学成绩变更为 60 分,语文成绩变更为 70

 将总成绩倒数前三的 3 位同学的数学成绩加上 30

 将所有同学的语文成绩更新为原来的 2

        2.4 Delete(删除)

语法:delete   from   表名   [where...]  [order  by...]  [limit...]

        2.4.1 删除数据

删除孙悟空的考试成绩

 删除整张表的数据

 删除整张表,只是删除了表中的数据,表结构依然存在。

查看表结构中,auto_increment项更新为n。

         2.4.2 截断表

语法:truncate  [table]   表名;

作用:删除表的数据。

注意:这个操作慎用。

  • 只能对整个表进行操作,不能像delete对部分数据操作。
  • 会重置表结构的auto_increment选项。
  • 实际上截断,MySQL不会对数据操作,所以会比delete快。但是truncate在删除数据时,并不经过真正的事务,所以无法回滚。

回滚:将删除的数据恢复的操作。

实际上,当我们通过MySQL对数据进行操作时,MySQL的日志中会记录与你相反的操作,防止误操作,可以进行数据恢复。

比如:你使用delete删除一条数据,在MySQL日志记录为insert插入一条数据。

而truncate不会在日志中有记录。所以无法回滚。

                 2.5 插入查询结果

语法:insert   into   表名    字段   select  ...

案例:将一张表中的数据去重插入到另外一张数据中。

 修改表名:

         2.6 聚合函数

函数说明

count([distinct]  表名)

返回查询到数据的数量
sum([distinct]  表名)返回查询到数据的总和,不是数字没有意义
avg([distinct]  表名)返回查询到数据的平均数,不是数字没有意义
max([distinct]  表名)返回查询到数据的最大值,不是数字没有意义
min([distinct]  表名)返回查询到数据的最小值,不是数字没有意义

 案例:

对于表:

 测试count:

  • 使用'*'做统计,为记录数据的个数

 注意空不会记录进结果

  • 统计数据成绩分数的个数,去重和未去重。

  •  统计数学总分

  • 总分平均分

  •  统计英语最高分

  •  返回 > 70 分以上的数学最低分

         2.7 group by子句使用

        在select使用group by进行分组查询。

        在公司中有很多部门,select只能事项全部部门的查询,加上group by可以实现不同部门之间的查询。

语法:select  ... from 表名  group by 分组字段;

案例:

  • 准备工作,创建一个雇员信息表(来自oracle 9i的经典测试表)
    • EMP员工表
    • DEPT部门表
    • SALGRADE工资等级表
  • 显示每一个部门的平均工资和最高工资

如果不加group by计算的就是所有的,就看不出部门之间的区别。

  •  显示每个部门的每种岗位的平均工资和最低工资

  •  显示平均工资低于2000的部门和它的平均工资

显示部门和平均工资,条件平均工资低于2000

        havinggroup by配合使用,对group by结果进行过滤 

以上是关于MySQL表的约束和表的增删查改的主要内容,如果未能解决你的问题,请参考以下文章

MySQL表的增删查改

MySQL表的增删查改

MySQl表的增删查改(CRUD)

一文搞懂MySQL数据库基础与MySQL表的增删查改(初阶)

MySQL 表的增删查改

MySQL表的增删查改(CRUD)