Mysql外键与查询关键字
今日内容概要
- 1 > 自增特性
- 2 > 约束条件之外键
- 2.1 > 外键简介
- 2.2 > 外键关系
- 2.2.1 > 一对多
- 2.2.2 > 多对多
- 2.2.3 > 一对一关系
- 3 > 查询关键字
- 3.1 > 查询关键字之select与from
- 3.2 > 查询关键字之where筛选
- 3.3 > 查询关键字之group by分组
- 3.4 > 聚合函数
- 3.5 > 间接获取分组以外其他字段的数据
1 > 自增特性
自增的作用已经了解但是自增他有他自己的一些特性,在实操过程中当我们将id值设为自增属性之后,当我们删除某个数据后,再次插入数据会发现自增的值就会出现断层了。演示如下:
create table t1(-> id int primary key auto_increment,-> name varchar(32)-> );
正常插入数据时没有问题自增没有出现断层,数字连续。
insert into t1(name) values('jason'),('bob'),('kevin');
当我们删除id=4,id= 7 后插入oscar他的id值不会回退。如下:
delete from t1 where id=4;
delete from t1 where id=7;
insert into t1(name) value('oscar');
select * from t1;
+----+-------+
| id | name |
+----+-------+
| 1 | jason |
| 2 | bob |
| 3 | kevin |
| 5 | rr |
| 6 | rr |
| 8 | oscar |
+----+-------+
6 rows in set (0.00 sec)
如何解决呢? 就是我们必须要在删除数据后再重置主键值,自增属性才会继续连续自增。
mysql> truncate t1;
Query OK, 0 rows affected (1.85 sec)mysql> select * from t1;
Empty set (0.00 sec)mysql> insert into t1(name) values('jason'),('kevin'),('tony');
Query OK, 3 rows affected (0.05 sec)
Records: 3 Duplicates: 0 Warnings: 0mysql> insert into t1(name) values('oscar');
Query OK, 1 row affected (0.05 sec)mysql> select * from t1;
+----+-------+
| id | name |
+----+-------+
| 1 | jason |
| 2 | kevin |
| 3 | tony |
| 4 | oscar |
+----+-------+
4 rows in set (0.00 sec)
2 > 约束条件之外键
2.1 > 外键简介
外键前戏:
创建一张员工表(有以下几个字段)id name age dep_name dep_desc就这样创建一个表有不少的缺陷:1.表的重点不清晰既可以说是员工表也可以说是部门表2.表中的某些字段对应的数据一直在重复浪费了存储空间3.表的拓展性极差 牵一发而动全身耦合度太高 不利于维护解决方法将表一分为二员工表 部门表id name age id dep_name dep_desc# 拆完之后确实解决了上述三个缺陷,但是也有了一个致命缺点# 员工与部门表之间没有了绑定关系解决方法 在员工表中添加一个部门编号字段与部门表中的主键字段相对应'''该字段就是外键字段是用来记录表与表之间的数据关系'''
2.2 > 外键关系
四种外键关系:
1.一对多2.多对多3.一对一4.没有关系
对于关系的判断就需要记住一个口诀:换位思考
2.2.1 > 一对多
关系梳理如下:
1.以员工表与部门表为例先站在员工表的角度问:一个员工能否对应多个部门答:不可以再站在部门表的角度问:一个部门能否对应多个员工答:可以结论:换位思考之后得出的答案是一个可以一个不可以所以关系是"一对多" 部门是'一'员工是'多'''关系表达只能用一对多 不能用多对一'''一对多关系 外键字段建在"多"的一方(员工表)
创建外键SQL语句如下:
'''如果表中有外键字段 那么建议先编写普通字段 最后再考虑外键字段'''create table emp(id int primary key auto_increment comment '编号',name varchar(32) comment '姓名',age int comment '年龄',dep_id int comment '部门编号',foreign key(dep_id) references dep(id));create table dep(id int primary key auto_increment comment '编号',dep_name varchar(32) comment '部门名称',dep_desc varchar(32) comment '部门描述');
'''但是按这个顺序你这么些 你会发现员工表创建不出来,就是因为有这 foreign key的约束条件存在
'''
foreign key的约束条件具体如下:
1.创建表的时候 应该先创建被关联表(没有外键字段的表)2.插入数据的时候 应该先插入被关联表(没有外键字段的表)外键字段填入的值只能是被关联表中已经存在的值3.修改、删除被关联表数据都会出现障碍需要使用到级联更新来解决这个障碍
级联更新级联删除的具体作用,就是当我们创建完成员工表和部门表之后向对部门表(被关联表)做修改的时候员工表(关联表)中的关联数据也会做出变动的操做,具体代码如下:
'''再关联表中去添加级联跟新级联删除代码on update cascade # 级联更新on delete cascade # 级联删除'''create table emp1(id int primary key auto_increment comment '编号',name varchar(32) comment '姓名',age int comment '年龄',dep_id int comment '部门编号',foreign key(dep_id) references dep1(id) on update cascade # 级联更新on delete cascade # 级联删除);create table dep1(id int primary key auto_increment comment '编号',dep_name varchar(32) comment '部门名称',dep_desc varchar(32) comment '部门描述');"""在实际工作中外键也可能不会使用 因为外键会消耗额外的资源并且会增加表的复杂度 表很多的情况下 我们也可以通过SQL语句的形式建立逻辑意义上的表关系"""
2.2.2 > 多对多
关系梳理如下:
以图书与作者表为例1.先站在图书表的角度问:一本书籍能否对应多名作者答:可以2.再站在作者表的角度问:一名作者能否对应多本书籍答:可以结论:换位思考之后两边都可以 那么就是"多对多"关系
创建关联表代码过程如下:
"""针对多对多关系 需要单独开设第三张表专门存储关系"""# 先依此创建书表和作者表(两张表里不写两张表的关系)create table book(id int primary key auto_increment,title varchar(32),price float(10,2));create table author(id int primary key auto_increment,name varchar(32),gender enum('male','female','others'));# 再创建第三张表专门存储关系的表create table book_author(id int primary key auto_increment,author_id int,book_id int,# 将字段author_id 与作者表的id关联foreign key(author_id) references author(id) on update cascade # 级联更新on delete cascade, # 级联删除# 将字段book_id 与书表的id关联foreign key(book_id) references book(id) on update cascade # 级联更新on delete cascade # 级联删除);
2.2.3 > 一对一关系
关系梳理如下:
针对qq用户表 其实里面的数据可以分成两类热数据:经常需要使用的数据eg:qq号码 座右铭 个人简介 爱好冷数据:不怎么经常需要使用的数据eg:邮箱 电话 学校 ...为了节省资源并降低数据库压力 会将表一分为二用户表存使用频率较高的数据字段用户详情表存使用频率较低的数据字段1.先站在用户表的角度问:一个用户数据能否对应多个用户详情数据答:不可以2.再站在用户详情表的角度问:一个用户详情数据能否对应多个用户数据答:不可以结论:换位思考之后两边都不可以 那么关系可能有两种
创建关联表代码过程如下:
create table User(id int primary key auto_increment,name varchar(32),gender enum('male','female','others'),user_detail_id int unique, foreign key(user_detail_id) references UserDetail(id) on update cascade # 级联更新on delete cascade, # 级联删除
);
create table UserDetail(id int primary key auto_increment,phone bigint,age int
);
3 > 查询关键字
数据准备。
create table emp(id int primary key auto_increment,name varchar(20) not null,sex enum('male','female') not null default 'male', #大部分是男的age int(3) unsigned not null default 28,hire_date date not null,post varchar(50),post_comment varchar(100),salary double(15,2),office int, #一个部门一个屋子depart_id int
);
插入记录。
#三个部门:教学,销售,运营
insert into emp(name,sex,age,hire_date,post,salary,office,depart_id) values
('jason','male',18,'20170301','张江第一帅形象代言',7300.33,401,1), #以下是教学部
('tom','male',78,'20150302','teacher',1000000.31,401,1),
('kevin','male',81,'20130305','teacher',8300,401,1),
('tony','male',73,'20140701','teacher',3500,401,1),
('owen','male',28,'20121101','teacher',2100,401,1),
('jack','female',18,'20110211','teacher',9000,401,1),
('jenny','male',18,'19000301','teacher',30000,401,1),
('sank','male',48,'20101111','teacher',10000,401,1),
('哈哈','female',48,'20150311','sale',3000.13,402,2),#以下是销售部门
('呵呵','female',38,'20101101','sale',2000.35,402,2),
('西西','female',18,'20110312','sale',1000.37,402,2),
('乐乐','female',18,'20160513','sale',3000.29,402,2),
('拉拉','female',28,'20170127','sale',4000.33,402,2),
('僧龙','male',28,'20160311','operation',10000.13,403,3), #以下是运营部门
('程咬金','male',18,'19970312','operation',20000,403,3),
('程咬银','female',18,'20130311','operation',19000,403,3),
('程咬铜','male',18,'20150411','operation',18000,403,3),
('程咬铁','female',18,'20140512','operation',17000,403,3);
3.1 > 查询关键字之select与from
select用于指定查询的字段from用于指定查询的表select id,name from mysql.user;'''查询关键字其实有先后执行顺序 但是无需过多在意!!!'''
3.2 > 查询关键字之where筛选
1. 查询id大于等于3 小于等于6的数据
select * from emp where id>=3 and id<=6;select * from emp where id between 3 and 6;
2. 查询薪资是20000或者18000或者17000的数据
select * from emp where salary=20000 or salary=18000 or salary=17000;select * from emp where salary in (20000,18000,17000);
3. 查询id小于3或者大于6的数据
select * from emp where id not between 3 and 6;
4. 查询薪资不在20000,18000,17000的数据
select * from emp where salary not in (20000, 18000, 17000);
5. 查询岗位描述为空的数据
select * from emp where post_comment = null; # 报错'''针对null只能用is 而不能用符号'''select * from emp where post_comment is null;
6. 查询员工姓名中包含字母o的员工姓名和薪资
'''当查找信息不准确时 我们统一称为‘模糊查询’使用关键字like: 开启模糊查询关键字关键符号%:匹配任意个数的任意字符_:匹配单个个数的任意字符'''select name,salary from emp where name like '%o%';
7. 查询员工姓名是由四个字符组成的数据
select * from emp where name like '____';select * from emp where char_length(name)=4;
3.3 > 查询关键字之group by分组
什么是分组?
按照指定的条件将单个单个的个体组织成一个个整体例如:按照性别分组 按照部门分组 按照年龄分组 按照国家分组...
为何需要分组?
分组的好处在于可以快速统计出某些数据eg:最大薪资 平均年龄 最小年龄 总人数 ...
如何分组?
'''按照部门分组 '''select * from emp group by post; # 5.7及以上版本会直接报错 '''mysql5.7及以上版本默认自带sql_mode=only_full_group_by该模式要求分组之后默认只可以直接获取分组的依据不能直接获取其他字段原因是分组的目的就是按照分组的条件来管理诸多数据 最小单位应该是分组的依据而不是单个单个的数据如果是MySQL5.6及以下版本 需要自己手动添加可以直接在配置文件里面直接改方便不然需要将之前写的所有配置再写一遍set global sql_mode = only_full_group_by......'''# 所以真确的写法是下面这种select post from emp group by post;
3.4 > 聚合函数
聚合函数是专门用于分组之后的数据统计。
max 统计最大值min 统计最小值sum 统计求和count 统计计数avg 统计平均值ps:是否需要分组 我们可以在题目或者需求中发现
1 > 统计每个部门的最高薪资
select post,max(salary) from emp group by post;
2 > 统计每个部门的平均薪资
select post,avg(salary) from emp group by post;
3 > 统计每个部门的员工人数
select post,count(id) from emp group by post
4 > 统计每个部门的月工资开销
select post,sum(salary) from emp group by post;
5 > 统计每个部门最小的年龄数
select post,min(age) from emp group by post;
3.5 > 间接获取分组以外其他字段的数据
1 > 统计每个部门下所有员工的姓名
select post,group_concat(name) from emp group by post;
2 > 统计每个部门下所有员工的姓名和年龄
select post,group_concat(name, age) from emp group by post;
3 > 给字段起别名
select post,group_concat(name) as '姓名' from group by post;'''也可以不写as关键字 但是语义不明确 建议还是加上select post,id '序列',name '姓名' from emp; '''
Mysql外键与查询关键字相关推荐
- mysql外键约束查询语句_MySQL数据库 : 查询语句,连接查询及外键约束
查询指定字段 select 字段1,字段2 from 表名; 消除重复行(重复指的是结果集中的所有完全重复行) select distinct 字段1,字段2.. ...
- mysql外键关联查询_MySQL外键约束和多表联查
一.创建外键 #测试数据表 # 教师表,主表 CREATE TABLE teacher( id INT PRIMARY KEY AUTO_INCREMENT, name varchar(20), ag ...
- MySQL外键关联(一对多)MySQL连接查询
MySQL外键关联(一对多) 外键说明 什么是外键? 1)表A中有字段(如身份证号)做了主键,表B中也有这个字段(身份证号),这里的身份证号一定来自表A同样字段里的内容,但再B表中身份证号对应id可以 ...
- mysql 外键查询_mysql 外键查询(mysql数据库多表联查)
mysql 外键查询(mysql数据库多表联查) 2020-07-24 11:51:00 共10个回答 查看方式主要是通过第三方工具或者是sql语句,主要有以下三种方式1:使用Navicateform ...
- MySQL外键约束On Delete、On Update各取值的含义
主键.外键和索引的区别? 主键 外键 索引 定义: 唯一标识一条记录,不能有重复的,不允许为空 表的外键是另一表的主键, 外键可以有重复的, 可以是空值 主索引(由关键字PRIMARY定义的索引) ...
- MySql外键学习总结
mysql添加外键 为已经添加好的数据表添加外键: 语法:alter table 表名 add constraint FK_ID foreign key(你的外键字段名) REFERENCES 外表表 ...
- mysql外键_MySQL外键约束(FOREIGN KEY)
MySQL 外键约束(FOREIGN KEY)是表的一个特殊字段,经常与主键约束一起使用.对于两个具有关联关系的表而言,相关联字段中主键所在的表就是主表(父表),外键所在的表就是从表(子表). 外键用 ...
- mysql外键约束怎么写_mysql外键约束怎么写
mysql外键约束的写法:[[CONSTRAINT ] FOREIGN KEY 字段名 REFERENCES 主键列1].外键约束是表的一个特殊字段,经常与主键约束一起使用. 在 CREATE TAB ...
- mysql 命令行 外键_MySQL命令行MySql外键设置详解
第一招.mysql服务的启动和停止 net stop mysql net start mysql 第二招.登陆mysql 语法如下: mysql -u用户名 -p用户密码 键入命令mysql -uro ...
最新文章
- java hello world
- 浅析Java虚拟机结构与机制
- 树型控件TreeView的几种用法
- ASP.NET中App_Code,App_Data等文件夹的作用
- (转)【javascript基础】原型与原型链
- spring里头各种获取ApplicationContext的方法
- ccna综合实验实训总结_实验室设备搬迁工作顺利展开
- Bzoj4568: [Scoi2016]幸运数字
- Visual Studio 2005 Tip:编辑项目文件
- c# MEF框架(三 导出类的方法和属性)
- js日期控件_11个开源的Github开源日期选择器组件,供你选择
- selenium和junit 的使用
- sql server序列_SQL Server中的序列对象
- IJCAI最佳论文公布 华人斩获最佳学生论文奖!
- 全网首发:研究WORD布局,会意之笑
- 【Vue插件】一款很好用的vue日历插件——vue-sweet-calendar
- STC12C5A60S2-定时器+数码管
- Android Studio MAC M1 安装模拟器
- 两道例题详解贝叶斯定理
- 不看好叮咚买菜的N个理
热门文章
- 用ChatGPT创造的虚拟老婆,被真女友强制「安乐死」
- 用html5 canvas画猪头,使用HTML5 Canvas实现画图效果
- 华为手机什么时候用上鸿蒙系统,华为手机要用鸿蒙系统吗?华为手机什么时候用鸿蒙系统?...
- Vue:单页面应用动态设置title
- Packer 自动化镜像 Windows 安装过程
- uniapp 云打包后IOS白屏,真机调试也是白屏,没有报错!解决办法
- 解决argument list too long错误
- 天刀服务器的位置2018,江湖前沿 2018天刀版本爆料分析
- python字符串长度补齐_Python补齐字符串长度的实例
- 巴厘岛民宿软件测试,住在这家民宿,感觉自己是在巴厘岛