MySQL学习二、数据管理与DQL查询数据

三、MySQL数据管理

3.1 外键

创建表时添加外键约束

CREATE TABLE `student` (
  `id` int(20) NOT NULL AUTO_INCREMENT COMMENT '学号',
  `name` varchar(30) NOT NULL DEFAULT '匿名' COMMENT '姓名',
  `password` varchar(20) NOT NULL DEFAULT '123456' COMMENT '密码',
  `sex` varchar(2) NOT NULL DEFAULT '女' COMMENT '性别',
  `birthday` datetime DEFAULT NULL COMMENT '出生日期',
  `gradeid` int(10) NOT NULL COMMENT '学生的年级',
  `address` varchar(100) DEFAULT NULL COMMENT '家庭住址',
  `email` varchar(20) DEFAULT NULL COMMENT '邮箱',
  PRIMARY KEY (`id`),
  FOREIGN KEY (`gradeid`) REFERENCES `grade`(`gradeid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

CREATE TABLE `grade` (
  `gradeid` int(10) NOT NULL AUTO_INCREMENT COMMENT '年级id',
  `gradename` varchar(50) NOT NULL COMMENT '年级名称',
  PRIMARY KEY (`gradeid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

物理外键不建议使用!(避免数据库过多造成困扰)

最佳实践:
  • 数据库就是单纯的表,只用来存数据,只有行(数据)和列(字段)
  • 我们想使用多张表的数据,想使用外键(程序去实现)

3.2 DML语言(数据操作语言)

数据库的意义:

数据存储,数据管理

  • Insert
  • update
  • delete

3.3 添加

insert

-- 插入语句(添加)

-- insert into 表名([字段1,字段2,字段3]) values ('值1'),('值2'),('值3');
insert into `grade` (`gradename`) values ('大四');

-- 由于主键自增,我们可以省略 (如果不写表的字段,他就会--匹配)

-- 一般写插入语句,要将数据与字段一一对应
-- 插入多个字段
insert into `grade` (`gradename`) values ('大三'),('大二'),('大一');

语法: insert into 表名 ([字段名1,字段名2,字段名3]) values ('值1'),('值2'),('值3');

注意事项:

  1. 字段和字段之间使用英文逗号隔开
  2. 字段可以省略,但是后面的值必须一一对应
  3. 可以同时插入多条数据,values后面的值,需要使用,隔开

3.4 修改

update

-- 修改语句
update `grade` set `gradename` = '大一' where gradeid = 1;

-- 不指定条件的情况下,会改动所有
update `grade` set `gradename` = '初始';

-- 修改多个条件
update `grade` set `gradename` = '大四', `gradep` = 12 where gradeid = 1;

语法: update 表名 set colnum_name = value.[colnum_name = value] where [条件]

条件:where 子句 运算符 id 等于某个值,大于某个值,在某个区间内修改....

操作符会返回 布尔值

操作符 含义 范围 结果
= 等于 5 = 6 false
<> 或 != 不等于 5 <> 6 true
>
<
<=
>=
BETWEEN ... and ... 在某个范围 [2,5]
AND && 5 > 1 and 1 > 2 false
OR ||
-- 通过多个定位条件定位数据
update `grade` set `name` = '长江7号' where `name` = '磊' and sex = '男'

注意:

  • colnum_name 是数据库的列,尽量带上``
  • 条件,筛选的条件,如果没有指定,则会修改所有的列
  • value,是一个具体的值
update `student` set `brithday` = CURRENT_TIME `name` = '长江7号' AND sex = '男'

3.5 删除

delete 命令

语法:delete from 表名 [where 条件]

-- 删除数据
delete from `grade`;

-- 删除指定数据
delete from `grade` where gradeid = 1;

TRUNCATE 命令

作用:完全清空一个数据库表,表的结构和索引约束不会变!

-- 清空 student 表
truncate `student` 

delete 和 TRUNCATE 区别

  • 相同点:都能删除数据,都不会删除表结构

  • 不同:
    • TRUNCATE 重新设置 自增列 计数器会归零
    • TRUNCATE 不会影响事务
-- 测试delete 和 TRUNCATE区别

create table `test` (
    `id` int(4) not null auto_increment,
    `coll` varchar(20) not null,
    primary key (`id`)
)ENGINE = InnoDB Default charset = utf8;

insert into `test` (`coll`) values ('1'),('2'),('3');

delete from test;       -- 不会影响自增
insert into `test` (`coll`) values ('1'),('2'),('3');

TRUNCATE table `test`;  -- 自增归零
insert into `test` (`coll`) values ('1'),('2'),('3');

DELETE删除问题:重启数据库现象

  • InnoDB 自增列会从1开始 (存在内存当中,断电即失)
  • MyISAM 继续从上一个自增量开始(存在文件中,不会丢失)

四、DQL查询数据

4.1 DQL

(Data Query Language:数据查询语言)

  • 所有的查询操作都用他 Select
  • 简单的查询,复杂的查询他都能做~
  • 数据库中最核心的语言
  • 使用频率最高

4.2 查询所有字段

-- 查询所有
select * from student;

-- 查询指定字段
select `name`,`sex` from student;

-- 别名,给结果起一个名字 AS 可以给字段起别名
select `name` as 姓名, `sex` from student;

-- 函数 Concat (a,b)
select concat('姓名: ', name) from student;

列名字可以起别名 AS

去重 disinct

作用:去除SELECT查询出来的结果中重复的数据,只显示一条

select distinct `gradeid` from student;

数据库的列

-- 查询系统的版本(函数)
select VERSION();

-- 用来计算(表达式)
select 100 * 3 - 1 as how;

-- 查询自增的步长(变量)
select @@auto_increment_increment;

-- 学生的密码 +1 查看
select `name`,`password`+1 as `密码+1后`from student;

数据库中的表达式:文本值,列,Null,函数,计算表达式,系统变量....

select 表达式 from 表

4.3 where条件子句

作用:检索数据中 符合条件 的值

逻辑运算符

搜索的条件由一个或者多个表达式组成!结果 布尔值

运算符 语法 描述
and && a and b a && b 逻辑与,两个都为真,结果为真
or || a or b a || b 逻辑或,其中一个为真,则结果为真
Not ! not a ! a 逻辑非,真为假,假为真!
-- ============================ where =================================
select `name`, `password` from student;

-- 查询学生密码在10000以上的学生
select `name`, `password` from student where password > 10000;

-- and && 查询学生密码在1000以上,10000以下的学生
select `name`, `password` from student where password > 1000 && password < 10000;

-- 模糊查询(区间) between and
select `name`, `password` from student where password between 1000 and 10000;

-- 除了1234密码的学生  ! not
select `name`, `password` from student where password != 1234;
select `name`, `password` from student where not password = 1234;

模糊查询:比较运算符

运算符 语法 描述
IS NULL a is null 如果操作符为NULL,结果为真
IS NOT NULL a is not null 如果操作符不为NULL,结果为真
BETWEEN a between b and c 若a在b和c之间,则结果为真
LIKE a like b SQL匹配,如果a匹配b,则结果为真
IN a in (a1,a2,a3...) 假设a在a1,或者a2...
-- =============================== 模糊查询 ====================================
-- 查询姓张的同学
-- like结合   %(代表0到任意个字符)    _(一个字符)
select `id`,`name` from student where name like '张%';

-- 查询姓张,后面只有一个字的
select `id`,`name` from student where name like '张_';

-- 查询名字中有烁的同学
select `id`,`name` from student where name like '%烁%';

-- ====================== in(具体的一个或者多个值) ===========================
-- 查询 1,2,3号学生
select `id`,`name` from student where id in (1,2,3);

-- 查询地址在呼和浩特的学生
select `id`,`name` from student where address in ('呼和浩特');

-- 查询地址为空的学生
-- ====================== null  not null ========================
select `id`,`name` from student where address = '';

-- 查询有出生日期的同学
select `id`,`name` from student where birthday is not null;

-- 查询没有出生日期的学生
select `id`,`name` from student where birthday is null;

4.4 联表查询

JOIN 对比

-- ======================== 联表查询 ==========================
-- 查询,同学的学号,姓名,年级
select * from student;
select * from grade;

/*
    1.分析需求,分析查询的字段来自哪些表,(连接查询)
    2.确定使用哪种连接查询?   7种
    确定交叉点(这两个表中哪个数据是相同的)
    判断的条件:学生表中 gradeid = 成绩表 gradeid
*/

select id,name,s.gradeid,gradename
from student as s
inner join grade as g
where s.gradeid = g.gradeid;

-- right join
select `id`,`name`,s.gradeid,`gradename`
from student s
right join grade g
on s.gradeid = g.gradeid;

-- left join
select `id`,`name`,s.gradeid,`gradename`
from student s
left join grade g
on s.gradeid = g.gradeid;
操作 描述
Innre join 如果表中至少有一个匹配,就返回行
left join 即使右表中没有匹配,也会从左表中返回所有的值
right join 即使左表中没有匹配,也会从右表中返回所有的值
-- join (连接的表) on (判断条件)            连接查询
-- where                                   等值查询

自连接

自己的表和自己的表连接,核心:一张表拆为两张一样的表即可

父类

categoryid categoryName
2 信息技术
3 软件开发
5 美术设计

子类

pid categoryid categoryName
3 4 数据库
2 8 办公信息
3 6 web开发
5 7 美术设计

操作:查询父类对应的子类关系

父类 子类
信息技术 办公信息
软件开发 数据库
软件开发 web开发
美术设计 ps技术
-- ============================= 自连接 ==================================

create table category (
    categoryid int(10) unsigned not null auto_increment comment '主题id',
    pid int(10) not null comment '父id',
    categoryName varchar(50) not null comment '主题名字',
    primary key (`categoryid`)
) engine = InnoDB auto_increment = 9 default charset = utf8;

insert into category values
                            (2,1,'c语言'),(3,1,'JavaSE'),(4,3,'JavaEE'),
                            (5,1,'web开发'),(6,3,'操作系统'),(7,5,'数据结构'),
                            (8,2,'离散数学');

-- 查询父子信息:把一张表看成两个一模一样的表
select a.categoryName as '父栏目', b.categoryName as '子栏目'
from `category` as a,
     `category` as b
where a.categoryid = b.pid;

SELECT语法

SELECT [ALL | DISTINCT]
{* | table.* | [table.field1[as alias1][,table.field2[as alias2]][,....]]}
FROM table_name [as table_alias]
    [left | right | inner join table_name2]     -- 联合查询
    [WHERE ...]     -- 指定结果需要满足的条件
    [GROUP BY ...]      -- 指定结果按照哪几个字段来分组
    [HAVING]        -- 过滤分组的记录必须满足的次要条件
    [ORDER BY ...]      -- 指定查询记录按一个或多个条件查询
    [LIMIT {[offset,]row_count | row_countOFFSET offset}];
    -- 指定查询的记录从哪条至哪条

4.5 分页和排序

排序

-- ========================= 分页 排序 ===============================
-- 排序 : 升序 ASC  ,  降序 DESC
-- ORDER BY 通过哪个字段排序,怎么排
-- 根据密码排序
select `id`,`name`,`password`,s.`gradeid` from student s left join grade g on s.gradeid = g.gradeid
where not id = 1 order by password asc;

select `id`,`name`,`password`,s.`gradeid` from student s left join grade g on s.gradeid = g.gradeid
where not id = 1 order by password desc;

分页

-- 分页 语法:limit 起始值 页面的大小
-- 缓解数据库压力 (瀑布流)
-- 每页只显示5条数据
select `id`,`name`,`password`,s.`gradeid` from student s left join grade g on s.gradeid = g.gradeid
where not id = 1 order by password desc limit 0,3;

-- [pageSize:页面大小]
-- [(n - 1) + pageSize:起始值]
-- [n:当前页]
-- [数据总数/页面大小 = 总页数]

4.6 子查询

本质:在where语句中嵌套一个子查询语句

-- ===================== where ======================
-- 1.查询学号,姓名,密码,年级号,年级 根据降序排列

-- 方式一、连接查询
select `id`,`name`,`password`,s.`gradeid`,`gradename` from student s left join grade g on s.gradeid = g.gradeid
order by password desc;

-- 方式二、子查询 查询gradeid 小于2
select `name`,`password` from student s
    inner join grade g on s.gradeid = g.gradeid where g.gradeid < 2;

-- 在上述基础上增加 学生名字中有王的
select `name`,`password` from student s
    inner join grade g on s.gradeid = g.gradeid where g.gradeid < 2 and name like '%王%';

-- 子查询
select `name`,`password`
from student s where name like '%王%' and gradeid = (
    select `gradeid` from grade where gradeid < 2 and s.gradeid = grade.gradeid
);

猜你喜欢

转载自www.cnblogs.com/yfyyy/p/12431938.html