一、数据库设计
数据库的设计
-
需求分析(数据是什么? 数据具有哪些属性? 数据与属性的特点是什么)
-
逻辑分析(通过ER图对数据库进行逻辑建模,不需要考虑我们所选用的数据库管理系统)
表关系
一对一
- 例: 用户 和 用户详情
- 一对一关系多用于表拆分,将一个实体中经常使用的字段放一张表,不经常使用的字段放另一张表,用于提升查询性能
-
实现方式
在任意一方加入外键,关联另一方主键,并且设置外键为唯一(UNIQUE)
-
sql语句:
create table tb_user_desc (
id int primary key auto_increment,
city varchar(20),
edu varchar(10),
income int,
status char(2),
des varchar(100)
);
create table tb_user (
id int primary key auto_increment,
photo varchar(100),
nickname varchar(50),
age int,
gender char(1),
desc_id int unique,
-- 添加外键
CONSTRAINT fk_user_desc FOREIGN KEY(desc_id) REFERENCES tb_user_desc(id)
);
一对多
-
如:部门 和 员工
-
一个部门对应多个员工,一个员工对应一个部门。如下图:
-
实现方式
在多的一方建立外键,指向一的一方的主键
-
sql语句
– 部门表
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)
);
多对多
-
如:商品 和 订单
-
一个商品对应多个订单,一个订单包含多个商品
-
实现方式
建立第三张中间表,中间表至少包含两个外键,分别关联两方主键
-
sql语句
二、多表查询
多表查询顾名思义就是从多张表中一次性的查询出我们想要的数据
内连接查询
-
相当于查询二表的交集数据
-
语法
-- 隐式内连接
SELECT 字段列表 FROM 表1,表2… WHERE 条件;
-- 显示内连接
SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 ON 条件;
- 隐式内连接
SELECT
*
FROM
emp,
dept
WHERE
emp.dep_id = dept.did;
- 显式内连接
select * from emp inner join dept on emp.dep_id = dept.did;
-- 上面语句中的inner可以省略,可以书写为如下语句
select * from emp join dept on emp.dep_id = dept.did;
外连接查询
-
分类
左外连接查询 :相当于查询A表所有数据和交集部分数据
右外连接查询 : 相当于查询B表所有数据和交集部分数据 -
语法
-- 左外连接
SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 ON 条件;
-- 右外连接
SELECT 字段列表 FROM 表1 RIGHT [OUTER] JOIN 表2 ON 条件;
左外连接:相当于查询A表所有数据和交集部分数据
右外连接:相当于查询B表所有数据和交集部分数据
子查询
- 概念
查询中嵌套查询,称嵌套查询为子查询。
语法:
查询工资高于猪八戒的员工信息
1、先查询猪八戒的的工资
select salary from emp where name = '猪八戒'
2、查询工资高于猪八戒的员工信息
select * from emp where salary > 3600;
3、子查询的写法:
select * from emp where salary > (select salary from emp where name = '猪八戒');
子查询根据查询结果不同,作用不同
- 子查询语句结果是单行单列,子查询语句作为条件值,使用 = != > < 等进行条件判断
- 子查询语句结果是多行单列,子查询语句作为条件值,使用 in 等关键字进行条件判断
- 子查询语句结果是多行多列,子查询语句作为虚拟表
三、事务
事务概念
数据库的事务(Transaction)是一种机制、一个操作序列,包含了一组数据库操作命令。
事务把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么同时成功,要么同时失败。
事务是一个不可分割的工作逻辑单元
- 开启事务
START TRANSACTION;
或者
BEGIN;
- 提交事务
commint
- 回滚事务
rollback
事务的特征
-
原子性(Atomicity): 事务是不可分割的最小操作单位,要么同时成功,要么同时失败
-
一致性(Consistency) :事务完成时,必须使所有的数据都保持一致状态
-
隔离性(Isolation) :多个事务之间,操作的可见性(看不到操作,只能看到结果)
-
持久性(Durability) :事务一旦提交或回滚,它对数据库中的数据的改变就是永久的
-
SELECT @@autocommit; 可以查询提交方式,查询到的结果是1 则表示自动提交,结果是0表示手动提交。
手动提交:
set @@autocommit = 0;
四、案例
环境准备
-- 部门表
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、查询所有员工信息。查询员工编号,员工姓名,工资,职务名称,职务描述
-- 隐式内连接
select e.id,e.ename,j.jname,j.description
FROM emp e,job j
where e.job_id=j.id;
- 2、查询员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置
select e.id,e.ename,j.jname,j.description,d.dname,d.loc
FROM emp e,job j,dept d
where e.job_id=j.id and e.dept_id=d.did;
- 3、查询员工姓名,工资,工资等级
select emp.ename,emp.salary,grade
from salarygrade,emp
where emp.salary> salarygrade.losalary and emp.salary< salarygrade.hisalary;
- 4、查询员工姓名,工资(emp),职务名称,职务描述(job),部门名称,部门位置(dept),工资等级(salarygrade)
select emp.ename,emp.salary,grade ,j.jname,j.description,d.dname,d.loc
from salarygrade,emp ,job j,dept d
where emp.salary> salarygrade.losalary and emp.salary< salarygrade.hisalary and emp.job_id=j.id and emp.dept_id=d.did;
- 5、查询出部门编号、部门名称、部门位置(dept)、部门人数
select dept.dname,dept.loc,count(dept.did) num
from dept LEFT JOIN emp
on emp.dept_id=dept.did
group by dept.did;