1.16 约束.数据库设计.多表查询

news/2025/2/5 14:06:51/文章来源:https://www.cnblogs.com/hzy-rj/p/18675706

1.约束

  • 非空约束: 关键字是 NOT NULL
    保证列中所有的数据不能有null值。
  • 唯一约束:关键字是 UNIQUE
    保证列中所有数据各不相同。
  • 主键约束: 关键字是 PRIMARY KEY
    非空且唯一。
  • 默认约束: 关键字是 DEFAULT
    未指定值则采用默认值。
  • 外键约束: 关键字是 FOREIGN KEY
    练习
    根据需求,为表添加合适的约束
点击查看代码
-- 员工表
CREATE TABLE emp (
id INT, -- 员工id,主键且自增长
ename VARCHAR(50), -- 员工姓名,非空且唯一
joindate DATE, -- 入职日期,非空
salary DOUBLE(7,2), -- 工资,非空
bonus DOUBLE(7,2) -- 奖金,如果没有将近默认为0
);

按照约束的关键字及需求对表进行修改,得到结果

点击查看代码
-- 员工表
CREATE TABLE emp (
id INT PRIMARY KEY auto_increment, -- 员工id,主键且自增长
ename VARCHAR(50) NOT NULL UNIQUE, -- 员工姓名,非空并且唯一
joindate DATE NOT NULL , -- 入职日期,非空
salary DOUBLE(7,2) NOT NULL , -- 工资,非空
bonus DOUBLE(7,2) DEFAULT 0 -- 奖金,如果没有奖金默认为0
);


外键约束
外键让两个表之间建立链接
练习

点击查看代码
-- 部门表
CREATE TABLE dept(
id int primary key auto_increment,
dep_name varchar(20),
addr varchar(20)
);
-- 员工表
CREATE TABLE emp(
id int primary key auto_increment,
name varchar(20),
age int,
dep_id int,
-- 添加外键 dep_id,关联 dept 表的id主键
CONSTRAINT fk_emp_dept FOREIGN KEY(dep_id) REFERENCES dept(id)
);

-- 建完表后添加外键约束 ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称);

2.数据库设计
1. 一对多
在多的一方建立外键,指向一的一方的主键

点击查看代码
-- 部门表
CREATE TABLE tb_dept(
id int primary key auto_increment,
dep_name varchar(20),
addr varchar(20)
);
-- 员工表
CREATE TABLE tb_emp(
id int primary key auto_increment,
name varchar(20),
age int,
dep_id int,
-- 添加外键 dep_id,关联 dept 表的id主键
CONSTRAINT fk_emp_dept FOREIGN KEY(dep_id) REFERENCES tb_dept(id)
);
**2. 多对多** 建立第三张中间表,中间表至少包含两个外键,分别关联两方主键
点击查看代码
-- 订单表
CREATE TABLE tb_order(
id int primary key auto_increment,
payment double(10,2),
payment_type TINYINT,
status TINYINT
);
-- 商品表
CREATE TABLE tb_goods(
id int primary key auto_increment,
title varchar(100),
price double(10,2)
);
-- 订单商品中间表
CREATE TABLE tb_order_goods(
id int primary key auto_increment,
order_id int,
goods_id int,
count int
);
-- 建完表后,添加外键
alter table tb_order_goods add CONSTRAINT fk_order_id FOREIGN key(order_id) REFERENCES
tb_order(id);
alter table tb_order_goods add CONSTRAINT fk_goods_id FOREIGN key(goods_id) REFERENCES
tb_goods(id);

3.多表查询

点击查看代码
# 创建部门表
CREATE TABLE dept(
did INT PRIMARY KEY AUTO_INCREMENT,
dname VARCHAR(20)
);
# 创建员工表
CREATE TABLE emp (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(10),
gender CHAR(1), -- 性别
salary DOUBLE, -- 工资
join_date DATE, -- 入职日期
dep_id INT,
FOREIGN KEY (dep_id) REFERENCES dept(did) -- 外键,关联部门表(部门表的主键)
);
-- 添加部门数据
INSERT INTO dept (dNAME) VALUES ('研发部'),('市场部'),('财务部'),('销售部');
-- 添加员工数据
INSERT INTO emp(NAME,gender,salary,join_date,dep_id) VALUES
('孙悟空','男',7200,'2013-02-24',1),
('猪八戒','男',3600,'2010-12-02',2),
('唐僧','男',9000,'2008-08-08',2),
('白骨精','女',5000,'2015-10-07',3),
('蜘蛛精','女',4500,'2011-03-14',1),
('小白龙','男',2500,'2011-02-14',null);
select * from emp , dept where emp.dep_id = dept.did;
  • 内连接
    查找两表交集
    -- 隐式内连接 SELECT 字段列表 FROM 表1,表2… WHERE 条件;
    -- 显示内连接 SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 ON 条件;

  • 外连接
    -- 左外连接 SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 ON 条件;
    -- 右外连接 SELECT 字段列表 FROM 表1 RIGHT [OUTER] JOIN 表2 ON 条件;

  • 子查询
    查询中嵌套查询
    例: 查询工资高于猪八戒的员工信息。
    第一步:先查询出来 猪八戒的工资
    select salary from emp where name = '猪八戒'
    第二步:查询工资高于猪八戒的员工信息
    select * from emp where salary > 3600;
    select * from emp where salary > (select salary from emp where name = '猪八戒');

  • 子查询语句结果是单行单列,子查询语句作为条件值,使用 = != > < 等进行条件判断

  • 子查询语句结果是多行单列,子查询语句作为条件值,使用 in 等关键字进行条件判断

  • 子查询语句结果是多行多列,子查询语句作为虚拟表
    案例

  • 环境准备:

点击查看代码
-- 部门表
CREATE TABLE dept (
did INT PRIMARY KEY PRIMARY KEY, -- 部门id
dname VARCHAR(50), -- 部门名称
loc VARCHAR(50) -- 部门所在地
);
-- 职务表,职务名称,职务描述
CREATE TABLE job (
id INT PRIMARY KEY,
jname VARCHAR(20),
description VARCHAR(50)
);
-- 员工表
CREATE TABLE emp (
id INT PRIMARY KEY, -- 员工id
ename VARCHAR(50), -- 员工姓名
job_id INT, -- 职务id
mgr INT , -- 上级领导
joindate DATE, -- 入职日期
salary DECIMAL(7,2), -- 工资
bonus DECIMAL(7,2), -- 奖金
dept_id INT, -- 所在部门编号
CONSTRAINT emp_jobid_ref_job_id_fk FOREIGN KEY (job_id) REFERENCES job (id),
CONSTRAINT emp_deptid_ref_dept_id_fk FOREIGN KEY (dept_id) REFERENCES dept (id)
);
-- 工资等级表
CREATE TABLE salarygrade (
grade INT PRIMARY KEY, -- 级别
losalary INT, -- 最低工资
hisalary INT -- 最高工资
);
-- 添加4个部门
INSERT INTO dept(did,dname,loc) VALUES
(10,'教研部','北京'),
(20,'学工部','上海'),
(30,'销售部','广州'),
(40,'财务部','深圳');
-- 添加4个职务
INSERT INTO job (id, jname, description) VALUES
(1, '董事长', '管理整个公司,接单'),
(2, '经理', '管理部门员工'),
(3, '销售员', '向客人推销产品'),
(4, '文员', '使用办公软件');
-- 添加员工
INSERT INTO emp(id,ename,job_id,mgr,joindate,salary,bonus,dept_id) VALUES
(1001,'孙悟空',4,1004,'2000-12-17','8000.00',NULL,20),
(1002,'卢俊义',3,1006,'2001-02-20','16000.00','3000.00',30),
(1003,'林冲',3,1006,'2001-02-22','12500.00','5000.00',30),
(1004,'唐僧',2,1009,'2001-04-02','29750.00',NULL,20),
(1005,'李逵',4,1006,'2001-09-28','12500.00','14000.00',30),
(1006,'宋江',2,1009,'2001-05-01','28500.00',NULL,30),
(1007,'刘备',2,1009,'2001-09-01','24500.00',NULL,10),
(1008,'猪八戒',4,1004,'2007-04-19','30000.00',NULL,20),
(1009,'罗贯中',1,NULL,'2001-11-17','50000.00',NULL,10),
(1010,'吴用',3,1006,'2001-09-08','15000.00','0.00',30),
(1011,'沙僧',4,1004,'2007-05-23','11000.00',NULL,20),
(1012,'李逵',4,1006,'2001-12-03','9500.00',NULL,30),
(1013,'小白龙',4,1004,'2001-12-03','30000.00',NULL,20),
(1014,'关羽',4,1007,'2002-01-23','13000.00',NULL,10);
-- 添加5个工资等级
INSERT INTO salarygrade(grade,losalary,hisalary) VALUES
(1,7000,12000),
(2,12010,14000),
(3,14010,20000),
(4,20010,30000),
(5,30010,99990);
1. 查询所有员工信息。查询员工编号,员工姓名,工资,职务名称,职务描述
点击查看代码
/*
分析:
1. 员工编号,员工姓名,工资 信息在emp 员工表中
2. 职务名称,职务描述 信息在 job 职务表中
3. job 职务表 和 emp 员工表 是 一对多的关系 emp.job_id = job.id
*/
-- 方式一 :隐式内连接
SELECT emp.id,emp.ename,emp.salary,job.jname,job.descriptionFROM emp,job WHERE emp.job_id = job.id;
-- 方式二 :显式内连接
SELECT emp.id,emp.ename,emp.salary,job.jname,job.description FROM emp INNER JOIN job ON emp.job_id = job.id;
2. 查询员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置
点击查看代码
/*
分析:
1. 员工编号,员工姓名,工资 信息在emp 员工表中
2. 职务名称,职务描述 信息在 job 职务表中
3. job 职务表 和 emp 员工表 是 一对多的关系 emp.job_id = job.id
4. 部门名称,部门位置 来自于 部门表 dept
5. dept 和 emp 一对多关系 dept.id = emp.dept_id
*/
-- 方式一 :隐式内连接
SELECT emp.id,emp.ename,emp.salary,job.jname,job.description,dept.dname,dept.loc FROM emp,job,dept WHERE emp.job_id = job.id and dept.id =emp.dept_id
;
-- 方式二 :显式内连接
SELECT emp.id,emp.ename,emp.salary,job.jname,job.description,dept.dname,dept.loc FROM emp 
INNER JOIN job ON emp.job_id = job.id
INNER JOIN dept ON dept.id = emp.dept_id
3. 查询员工姓名,工资,工资等级
点击查看代码
/*
分析:
1. 员工姓名,工资 信息在emp 员工表中
2. 工资等级 信息在 salarygrade 工资等级表中
3. emp.salary >= salarygrade.losalary and emp.salary <= salarygrade.hisalary
*/
SELECT emp.ename,emp.salary,t2.* FROM emp,salarygrade t2 WHERE emp.salary >= t2.losalary AND emp.salary <= t2.hisalary
4. 查询员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级
点击查看代码
/*
分析:
1. 员工编号,员工姓名,工资 信息在emp 员工表中
2. 职务名称,职务描述 信息在 job 职务表中
3. job 职务表 和 emp 员工表 是 一对多的关系 emp.job_id = job.id
4. 部门名称,部门位置 来自于 部门表 dept
5. dept 和 emp 一对多关系 dept.id = emp.dept_id
6. 工资等级 信息在 salarygrade 工资等级表中
7. emp.salary >= salarygrade.losalary and emp.salary <= salarygrade.hisalary
*/
SELECT
emp.id
emp.ename,
emp.salary,
job.jname,
job.description,
dept.dname,
dept.loc,
t2.grade
FROM
emp
INNER JOIN job ON emp.job_id = job.id
INNER JOIN dept ON dept.id = emp.dept_id
INNER JOIN salarygrade t2 ON emp.salary BETWEEN t2.losalary and t2.hisalary;
5. 查询出部门编号、部门名称、部门位置、部门人数
点击查看代码
/*
分析:
1. 部门编号、部门名称、部门位置 来自于部门 dept 表
2. 部门人数: 在emp表中 按照dept_id 进行分组,然后count(*)统计数量
3. 使用子查询,让部门表和分组后的表进行内连接
*/
-- 根据部门id分组查询每一个部门id和员工数
select dept_id, count(*) from emp group by dept_id;
SELECT
dept.id,
dept.dname,
dept.loc,
t1.count
FROM
dept,
(
SELECT
dept_id,
count(*) count
FROM
emp
GROUP BY
dept_id
) t1
WHERE
dept.id = t1.dept_id

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/870282.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【内网穿透】概念、原理与实现方法

一、内网穿透简介 内网穿透是一种网络技术,它允许外部网络(如互联网)上的设备访问位于内部网络(例如公司或家庭局域网LAN)中没有直接公网IP地址的设备。这对于远程办公、云服务接入以及物联网设备管理等场景至关重要。 二、工作原理 内网穿透主要依赖于NAT(网络地址转换)…

数字电路课程笔记

1、数制与码制 补零 二进制和十六进制之间的转换: 整数部分:对于整数部分,您需要将二进制数从右往左,每四位一组。如果剩余的位数不足四位,就需要在左边补零,直到每组都有四位。小数部分:对于小数部分,您需要将二进制数从左往右,每四位一组。如果剩余的位数不足四位,…

unity里生成的.csproj和.sln :assembly definition

有一段时间一直没明白为啥有的时候第三方的package里的代码没法引用我们项目的,最近有点心得,记录下: 在创建unity项目的时候默认是创建一个解决方案就是以.sln为结尾的。默认开发时都在同一个解决项目里,所以不会出现相互引用不到的问题。当我们引用到第三方的package时就…

【前端框架】2025 React 状态管理终极指南!

全文约 10800 字,预计阅读需要 30分钟。 React 作为当下最受欢迎的前端框架,在构建复杂且交互丰富的应用时,状态管理无疑是至关重要的一环。从简单的本地状态,到能让多个组件协同工作的全局状态,再到涉及服务器通信、导航切换、表单操作以及持久化存储等不同场景下的状态管…

【搜索】多源BFS专题

跳马(多源BFS变种,每个起点有步数限制)补充几个测试样例 输入 3 2 . . 2 . . .输出 0输入 3 5 4 7 . 4 8 4 7 4 4 . 7 . . . .输出 17输入 3 4 . . . . . 2 . . . . . .输出 0输入 3 4 . . . . . 2 2 . . . . .输出 -1本题很坑爹的地方在于,输入的字符串还用空格分开,所以…

代码随想录算法训练营第四天 | 24. 两两交换链表中的节点、19. 删除链表的倒数第N个节点、160.链表相交、142.环形链表II

9-24.两两交换链表中的节点 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。示例 1:输入:head = [1,2,3,4] 输出:[2,1,4,3] 示例 2: 输入:head = [] 输出:[] 示例 3: 输入:he…

2025 省选模拟 6

2025 省选模拟 6 A.圣诞树 DP,计数题 考虑题目题目的两个限制相邻两层彩球颜色集合不同同层相邻两个彩球颜色不同发现求出每一行恰好 \(j\) 个颜色后第二个限制很简单就解决了。 设 \(f_{i,j}\) 表示长度为 \(i\) 时恰好有 \(j\) 个颜色的方案数(对于一行考虑) 设 \(g_{i,j}…

第一次

第一次 1. 神秘符文的重复序列 逻辑思维#include<bits/stdc++.h> using namespace std; int main(){int n,k;cin>>n>>k;//长度为n,重复k遍!string s;cin>>s;long long int ans=0;long long int cnt=0;while(k--) {//重复k遍for(int i=0;i<n;i++)…

在kubernates中安装安卓模拟器

1.检测环境 root@xx:~# apt install cpu-checker root@xx:~# kvm-ok INFO: /dev/kvm exists KVM acceleration can be used root@xx:~# ll /dev/kvm crw-rw---- 1 root kvm 10, 232 Jan 15 16:38 /dev/kvm确认/dev/kvm设备存在即可。如果是ESXi虚拟机服务器,则需要在虚拟机配置…

告别虚拟机!WSL2安装配置教程!!!

作者:SkyXZ CSDN:SkyXZ~-CSDN博客 博客园:SkyXZ - 博客园 由于Linux的系统的稳定以及在环境管理方面的优越性,同时Linux对于ROS系统的独占,很多时候我们都乐意在Linux系统下开发我们机器人的算法,但是由于Windows和Linux系统的存在内核方面的天壤之别,在我们手边…

windows安装Mosquitto(MQTT服务)

安装说明: https://www.cnblogs.com/xiaosongboke/p/18604458, https://blog.csdn.net/qq_44477552/article/details/143883087设置账号和密码.\mosquitto_passwd.exe -c .\pwfile.example admin注意:CMD以管理员方式运行。 修改配置文件mosquitto.confallow_anonymous fals…

ABC 337 G(主席树)

最近刚学完主席树,找了道题巩固一下,还是非常有收获的。 题目链接:problem 若只让求\(f(1)\),则还是比较简单的——用权值树状数组维护\(dfs\)路径上的数,每次查一下在 递归路径中\(>\)当前结点值 的结点数量,累加起来即为\(f(1)\)。 可是题目要求将\(f(1)到f(n)\)全部…