MySQL详细学习教程(二)

目录

一、约束

二、数据库设计

三、多表查询


一、约束

1.1概念

  • 约束是作用于表中上的规则,用于限制加入表的数据
  • 约束的存在保证了数据库中数据的正确性、有效性和完整性
  • 添加约束可以在添加数据的时候就限制不正确的数据,年龄是3000,数学成绩是-5分这样无效的数据,继而保障数据的完整性。

1.2分类

注意:MySQL不支持检查约束。

1.3 非空约束

概念:非空约束用于保证列中所有数据不能有null值;

语法:

添加约束:

1.-----创建表时添加非空约束
create table 表名(
  列名 数据类型 NOT NULL;
  ....
);
2.-----建完表后添加非空约束
alter table 表名 modify 字段名 数据类型  NOT NULL;

删除约束:
alter table 表名 modify 字段名 数据类型;

1.4 唯一约束

 概念:唯一约束用于保证列中所有数据各不相同;

语法:

添加约束:

1.-----创建表时添加唯一约束

 create table 表名(

    列名  数据类型 UNIQE [AUTO_INCREMENT],

   ----- AUTO_INCREMENT:当不指定值时自动增长;

  .....

) ;

 create table 表名(

   列名  数据类型,

   ...

  [CONSTRAINT] [约束名称] UNIQUE(列名)

);

2.----建完表后添加唯一约束

alter table 表名  modify 字段名 数据类型 UNIQUE;

删除约束:

alter   table 表名 DROP INDEX 字段名;

1.5 主键约束

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

语法:

添加约束:

1.----创建表时添加主键约束

create table 表名(

  列名 数据类型 PRIMARY KEY [AUTO_INCREMENT],

  ....

);

 create table 表名(

列名 数据类型,

...

[CONSTRAINT] [约束名称] PRIMAY KEY (列名)

);

2.----建完表后添加主键约束

alter table 表名 add PRIMARY KEY(字段名);

删除约束

alter table 表名 drop PRIMARY KEY;

1.6 默认约束

概念:保存数据时,未指定值则采用默认值;

语法:

添加约束:
1.-----创建表时添加默认约束

create table 表名(

 列名 数据类型 DEFAULT 默认值,

...

);

2.建完表添加默认约束

alter table 表名 alter 列名 set DEFAULT 默认值;

删除约束:

alter table 表名 alter 列名 drop DEFAULT;

约束练习:
根据需求,给表中添加合适的约束:
---员工表:
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, -- 员工id,主键且自增长 
ename VARCHAR(50) NOT NULL UNIQUE, -- 员工姓名,非空并且唯一 
joindate DATE NOT NULL , -- 入职日期,非空 
salary DOUBLE(7,2) NOT NULL , -- 工资,非空 
bonus DOUBLE(7,2) DEFAULT 0 -- 奖金,如果没有奖金默认为0 );

1.7外键约束

概念:外键用来让两个表的数据之间建立链接,保证数据的一致性和完整性。
语法:
添加约束:
1.---创建表时添加外键约束
create table 表名(
列名 数据类型,
...
[CONSTRAINT] [外键名称] FOREIGN KEY(外键列名) REFERENCES(主表列名)
);
2.---建完表后添加外键约束
ALTER TABLE 表名 add  CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称);
删除约束
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;
1.根据上述语法创建员工表和部门表,并添加上外键约束:
 -- 部门表 
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) ); 

2.添加数据
-- 添加 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);

3.此时删除研发部这条数据,会发现无法删除
删除外键:
alter table emp drop FOREIGN key fk_emp_dept; 
重新添加外键
alter table emp add CONSTRAINT fk_emp_dept FOREIGN key(dep_id) REFERENCES dept(id); 

二、数据库设计

2.1数据设计简介

 数据库设计概念:

  • 数据库设计就是根据业务系统的具体需求,结合我们所选用的DBMS,为这个业务系统构造出最优的数据存储模型。
  • 建立数据库中的表结构以及表与表之间的关联关系的过程。

数据库设计步骤:

  • 需求分析(数据是什么? 数据具有哪些属性? 数据与属性的特点是什么)
  • 逻辑分析(通过ER图对数据库进行逻辑建模,不需要考虑我们所选用的数据库管理系统)
  • 物理设计(根据数据库自身的特点把逻辑设计转换为物理设计)
  • 维护设计(1.对新的需求进行建表;2.表优化)

表关系:

  •  一对一
  • 一对多
  • 多对多

2.2表关系

2.2.1 一对多

例如:部门和员工;一个部门对应多个员工,一个员工对应一个部门;

实现方式在多的一方建立外键,指向一的一方的主键

以员工表和部门表进行举例:

经过分析发现,员工表属于多的一方,而部门表属于一的一方,此时我们会在员工表中添加一列(dep_id),指向于部门表的主键(id)

建表语句如下:
-- 部门表 
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.2.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);

查看表结构模型图:

 2.2.3  表关系(一对一)

例如:用户和用户详情

一对一关系多用于表拆分,将一个实体中经常使用的字段放一张表,不经常使用的字段放另一张表,用于提升查询性能。

实现方式在任意一方中加入外键,关联另一方主键,并且设置外键为唯一(UNIQE)

而在真正使用过程中发现 idphotonicknameagegender 字段比较常用,此时就可以将这张表查分成两张表。 

 建表语句如下:

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) );

查看表结构模型图:

三、多表查询

多表查询顾名思义就是从多张表中一次性的查询出我们想要的数 

  连接查询分类:

  • 内连接查询 :相当于查询AB交集数据
  • 外连接查询左外连接查询 :相当于查询A表所有数据和交集部门数据;右外连接查询 : 相当于查询B表所有数据和交集部分数据

3.1 内连接查询

内连接相当于查询 A B 交集数据

语法:

----隐式内连接

select 字段列表 from 表1,表2 ... where 条件;

----显式内连接

select 字段列表 from 表1 [inner] join 表2 on 条件;

案例1:隐式内连接

练习:
select *from emp,dept where emp.dep_id =dept.id;

 上述语句的执行效果:

查询emp的name,gender,dept表的dname
select emp.NAME,emp.gender,dept.dname from emp,dept where emp.dep_id = dept.did;

上述语句的查询结果是: 

 

上述语句使用表名指定字段所属有点麻烦,sql也支持给表指别名
select t1.NAME,t1.gender,t2.dname from emp t1 ,dept t2 where t1.dep_id = t2.did;

 案例2:显示内连接

select *from emp inner join dept on emp.dep_id =dept.did;
----上面的语句inner可以省略写成下面的语句
select *from emp join dept on emp.dep_id =dept.did;

上述结果如下:

3.2外连接查询

语法:

--左外连接

select 字段列表 from 表1 LEFT [OUTER] JOIN 表2 ON 条件;

--右外连接

select 字段列表 from 表1 RIGHT [OUTER] JOIN 表2 ON 条件;

左外连接:相当于查询A表所有数据和交集部分数据
右外连接:相当于查询B表所有数据和交集部分数据
练习:
1.查询emp表所有数据和对应的部门信息(左外连接)
select * from emp left join dept on emp.dep_id = dept.did;
2.查询dept表所有数据和对应的员工信息(右外连接)
select * from emp right join dept on emp.dep_id = dept.did; 

 

 以上是上述第一个语句的执行结果,结果显示查询到了左表(emp)中所有的数据及两张表能关联到的数据。

 以上是第二条语句的执行结果,结果显示查询到右表(dept)中所有的的数据及两张表能关联的数据。

3.3子查询

查询中有嵌套查询,称嵌套查询为子查询;

什么是查询中嵌套查询呢?我们通过一个例子来看:
需求:查询工资高于张三的员工信息
1.先查询出张三的工资
select salary from emp where name="张三";
2.查询工资高于张三的员工信息
select *from emp where salary >3600;

这里的3600可以通过第一步的sql查询出来,所以3600用sql的第一步进行替换
select * from emp where salary > (select salary from emp where name = '猪八戒');
子查询根据查询结果不同,作用不同
  • 子查询语句结果是单行单列,子查询语句作为条件值,使用 = != > < 等进行条件判断
  • 子查询语句结果是多行单列,子查询语句作为条件值,使用 in 等关键字进行条件判断
  • 子查询语句结果是多行多列,子查询语句作为虚拟表
练习:
1.查询“财务部”和“市场部”所有的员工信息
-- 查询 '财务部' 或者 '市场部' 所有的员工的部门did 
select did from dept where dname = '财务部' or dname = '市场部'; 
select * from emp where dep_id in (select did from dept where dname = '财务部' or dname = '市场部');
2.查询入职日期是 '2011-11-11' 之后的员工信息和部门信息
-- 查询入职日期是 '2011-11-11' 之后的员工信息 
select * from emp where join_date > '2011-11-11' ; 
-- 将上面语句的结果作为虚拟表和dept表进行内连接查询 
select * from (select * from emp where join_date > '2011-11-11' ) t1, dept where t1.dep_id = dept.did;

 3.4事务

  • 数据库的事务(Transaction)是一种机制、一个操作序列,包含了一组数据库操作命令
  • 事务把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么同时成功,要么同时失败
  • 事务是一个不可分割的工作逻辑单元

事务的理解:

张三和李四账户中各有 100 块钱,现李四需要转换 500 块钱给张三,具体的转账操作为
  • 第一步:查询李四账户余额;
  • 第二步:从李四账户金额-500;
  • 第三步:给张三账户+500;
现在假设在转账过程中第二步完成后出现了异常第三步没有执行,就会造成李四账户金额少了 500 ,而张三金额并没有多500;这样的系统是有问题的。
如果解决呢?使用事务可以解决上述问题。

从上图可以看到在转账前开启事务,如果出现了异常回滚事务,三步正常执行就提交事务,这样就可以完美解决问题。

语法:

1.开启事务:

START TRANSACTION;

或者

BEGIN;

2.提交事务

commit;

3.回滚事务:

rollback; 

-- 开启事务 
BEGIN; 
-- 转账操作 
-- 1. 查询李四账户金额是否大于500 
-- 2. 李四账户 -500 
UPDATE account set money = money - 500 where name = '李四'; 
出现异常了... -- 此处不是注释,在整体执行时会出问题,后面的sql则不执行 -- 
3. 张三账户 +500 
UPDATE account set money = money + 500 where name = '张三'; 
-- 提交事务 
COMMIT; 
-- 回滚事务 
ROLLBACK;

事务的四大特征:

  • 原子性(Atomicity: 事务是不可分割的最小操作单位,要么同时成功,要么同时失败
  • 一致性(Consistency :事务完成时,必须使所有的数据都保持一致状态
  • 隔离性(Isolation :多个事务之间,操作的可见性
  • 持久性(Durability :事务一旦提交或回滚,它对数据库中的数据的改变就是永久的

 说明:

mysql中事务是自动提交的。也就是说我们不添加事务执行sql语句,语句执行完毕会自动的提交事务。 可以通过下面语句查询默认提交方式:

select @@autocommit;
查询到的结果是1 则表示自动提交,结果是0 表示手动提交。
当然也可以通过下面语句修改提交方式.
set @@autocommit =0;

猜你喜欢

转载自blog.csdn.net/m0_74890428/article/details/127842857