数据库高级

约束

约束是作用于表中列上的规则,用于限制加入表的数据
约束的存在保证了数据库中数据的正确性,有效性和完整性

单表约束

描述

关键字

非空约束

保证列中所有数据不能有null值

not null

唯一约束

保证列中所有数据各不相同

unique

主键约束

主键是一行数据的唯一标识,要求非空且唯一,一张表只能有一个主键。

primary key

检查约束

保证列中数据的值满足某一条件

check(MySql不支持检查约束)

默认约束

保存数据时,未指定值则采用默认值

default

create database if not exists db2;

use db2;

DROP TABLE IF EXISTS emp;

-- 员工表
CREATE TABLE if not exists 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
);
SELECT * from emp;

CREATE TABLE if not exists emp (
   id INT 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
   primary key (id) -- 设置主键
);
SELECT * from emp;

INSERT INTO emp(id,ename,joindate,salary,bonus) values(1,'张三','1999-11-11',8800,5000);
SELECT * from emp;

-- 演示主键约束:非空且唯一(Duplicate entry '1' for key 'PRIMARY')
INSERT INTO emp(id,ename,joindate,salary,bonus) values(1,'张三','1999-11-11',8800,5000);
SELECT * from emp;

-- 演示非空约束(Column 'ename' cannot be null)
INSERT INTO emp(id,ename,joindate,salary,bonus) values(2,null,'1999-11-11',8800,5000);
SELECT * from emp;

-- 演示唯一约束(Duplicate entry '张三' for key 'ename')
INSERT INTO emp(id,ename,joindate,salary,bonus) values(2,'张三','1999-11-11',8800,5000);
SELECT * from emp;

-- 演示默认约束(默认值为0)
INSERT INTO emp(id,ename,joindate,salary) values(4,'赵六','1999-11-11',8800);
SELECT * from emp;

-- 演示自动增长:auto_increment:当列是数字类型并且 唯一约束()
/*自动增长规则:计数器原理,count每次+1作为id,但是在添加数据时,还会看最后一条数据的id值,将最后一条数据的id+1
  和计数器比较,谁的值大就用谁。
  */
INSERT INTO emp(ename,joindate,salary,bonus) values('王七','1999-11-11',8800,0);
SELECT * from emp;

多表约束

描述

关键字

外键约束

外键用来让两个表的数据之间建立连接,保证数据的一致性和完整性

foreign key

use db2;
/*
    外键约束:
        * 外键用来让两个表的数据之间建立链接,保证数据的一致性和完整性

    -- 创建表时添加外键约束
    CREATE TABLE 表名(
         列名 数据类型,
         …
         [CONSTRAINT] [外键名称] FOREIGN KEY(外键列名) REFERENCES 主表(主表列名) 
    ); 

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

    -- 删除约束
    ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;
    
    
*/
-- 删除表
DROP TABLE IF EXISTS emp;
DROP TABLE IF EXISTS dept;


-- 部门表
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,
    constraint fk_emp_dept_1 foreign key (dep_id) references dept(id)
);
-- 添加 2 个部门
insert into dept(dep_name,addr) values
('研发部','广州'),('销售部', '深圳');

-- 添加员工,dep_id 表示员工所在的部门
INSERT INTO emp (NAME, age, dep_id) VALUES 
('张三', 20, 1),
('李四', 20, 1),
('王五', 20, 1),
('赵六', 20, 2),
('孙七', 22, 2),
('周八', 18, 2);
-- ------------------
select * from emp;
-- 演示外键约束(Cannot delete or update a parent row:
-- a foreign key constraint fails (`db2`.`emp`, CONSTRAINT `fk_emp_dept_1` FOREIGN KEY (`dep_id`) REFERENCES `dept` (`id`)))
delete from dept where id=2;

-- 删除外键
alter table emp drop foreign key fk_emp_dept_1;

-- 建完表后,添加外键
alter table emp add constraint fk_emp_dept_1 foreign key (dep_id) references dept(id);



数据库设计

数据库设计的步骤:

  1. 需求分析(数据是什么? 数据具有哪些属性? 数据与属性的特点是什么)

  1. 逻辑分析(通过ER图对数据库进行逻辑建模,不需要考虑我们所选用的数据库管理系统)

  1. 物理设计(根据数据库自身的特点把逻辑设计转换为物理设计)

  1. 维护设计(1.对新的需求进行建表;2.表优化)

多表设计

一对多(多对一):外键设计在多的一方,指向一的一方的主键

多对多:建立第三张中间表,中间表至少包含两个外键,分别关联两方的主键。
/*
    多对多:
        * 如:订单 和 商品
        * 一个商品对应多个订单,一个订单包含多个商品

    实现方式:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键
*/
-- 删除表
DROP TABLE IF EXISTS tb_order_goods;
DROP TABLE IF EXISTS tb_order;
DROP TABLE IF EXISTS tb_goods;

use db2;
-- 订单表
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_tb_goods_1 foreign key (goods_id) references tb_goods(id);
alter table tb_order_goods add constraint fk_tb_order_2 foreign key (order_id) references tb_order(id);


一对一:在任意一方加入外键,关联另一方主键,并设置外键为唯一(unique)
/*
    一对一:
        如:用户 和 用户详情
        一对一关系多用于表拆分,将一个实体中经常使用的字段放一张表,不经常使用的字段放另一张表,用于提升查询性能

    实现方式:在任意一方加入外键,关联另一方主键,并且设置外键为唯一(UNIQUE)
*/
use db2;
-- 删除表
DROP TABLE IF EXISTS tb_user;
DROP TABLE IF EXISTS tb_user_desc;

-- 用户详情表
CREATE TABLE tb_user_desc(
    id int primary key auto_increment,
    city varchar(100),
    edu varchar(10),
    income double(10,2),
    status varchar(10),
    descInfo varchar(200)
);

-- 用户表
CREATE TABLE tb_user(
    id int primary key auto_increment,
    phone varchar(100),
    nickname varchar(20),
    age int,
    gender char(1),
    desc_id int
);

-- 建完表后,添加外键
alter table tb_user change desc_id desc_id int unique;
alter table tb_user add constraint fk_1 foreign key (desc_id) references tb_user_desc (id);


多表查询

多表查询:从多张表查询数据,并消除笛卡尔积(笛卡尔积:取A,B集合所有组合情况)
      连接查询:
            内连接:相当于查询AB交集数据
            外连接:
                      左外连接:相当于查询A表所有数据和交集部分数据
                      右外连接:相当于查询B表所有数据和交集部分数据
子查询 :查询语句中的嵌套查询

use db2;
DROP TABLE IF EXISTS emp;
DROP TABLE IF EXISTS dept;


-- 创建部门表
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;

-- 多表查询
select * from emp,dept;
select * from emp e ,dept d where d.did=e.dep_id;
select * from emp left join dept d on d.did = emp.dep_id;
select * from emp right join dept d on d.did = emp.dep_id;

/*
-- 隐式内连接
SELECT 字段列表 FROM 表1,表2… WHERE 条件;

-- 显示内连接
SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 ON 条件 [INNER] JOIN 表3 ON 条件 …;

*/
-- 需求:查询员工的姓名、性别和部门名称
-- 隐式内连接
select e.name,e.gender,d.dname from emp e,dept d where e.dep_id=d.did;
select e.name,e.gender,d.dname from emp e,dept d where e.dep_id=d.did and e.name like '猪%';

-- 显式内连接
select e.name,e.gender,d.dname from emp e inner join dept d on e.dep_id=d.did;
select e.name,e.gender,d.dname from emp e inner join dept d on e.dep_id=d.did where e.name like '孙%';

/*
-- 左外连接
SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 ON 条件 LEFT [OUTER] JOIN 表3 ON 条件…;

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

*/
-- 需求:查询所有员工的和员工的部门信息
-- 左外连接
select * from emp e left join dept d on e.dep_id=d.did;

-- 右外连接
select * from emp e right join dept d on e.dep_id=d.did;

/*
	单行单列:作为条件值,使用 = != > <等进行条件判断
		SELECT 字段列表 FROM 表 WHERE 字段名 = (子查询);
	多行单列:作为条件值,使用 in 等关键字进行条件判断
		SELECT 字段列表 FROM 表 WHERE 字段名 in (子查询);
	多行多列:作为虚拟表
		SELECT 字段列表 FROM (子查询) WHERE 条件;
*/

use db2;
-- 需求1:查询工资高于猪八戒的员工信息
select * from emp where salary>(select salary from emp where NAME='猪八戒');

-- 需求2:查询 '财务部' 和 '市场部' 所有的员工信息
select * from emp where dep_id in (select did from dept where dname in ('财务部','市场部'));

-- 需求3:查询入职日期是 '2011-11-11' 之后的员工信息和部门信息
select * from (select * from emp inner join dept d on d.did = emp.dep_id) a where a.join_date>'2011-11-11';

事务

数据库的事务是一种机制,指的是把一组SQL操作看成一个整体,在执行的过程中要么同时成功,要么同时失败。
DROP TABLE IF EXISTS account;

-- 创建账户表
CREATE TABLE account(
    id int PRIMARY KEY auto_increment,
    name varchar(10),
    money double(10,2)
);

-- 添加数据
INSERT INTO account(name,money) values('张三',1000),('李四',1000);

UPDATE account set money = 1000;

select * from account;
-- 李四的窗口------------
-- 演示事务操作
-- 需求:张三向李四借500元
-- 开启事务,一旦开启事务了,在没有提交事务或者回滚事务时,所做的所有操作都是临时操作。
start transaction ; begin;

-- 1 李四账户-500
update account set money=money-500 where name='李四';

select * from abc;

-- 2 张三账户+500
update account set money=money+500 where name='张三';

-- 提交事务
commit ;
-- 回滚事务
rollback ;

事务四大特征

原子性A

事务是不可分割的最小操作单位,要么同时成功,要么同时失败

一致性C

数据库要一直处于一致的状态,事务的运行不会改变数据库原本的一致性约束。

隔离性I

多个事务之间是不能被相互影响。

持久性D

事务一旦提交或回滚,它对数据库中的数据的改变就是永久的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值