Mysql的外键约束、内外连接查询以及锁(上)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: Mysql的外键约束、内外连接查询以及锁

一、Mysql外键约束foreign key


(1)外键约束概述


  • 外键约束用来在两个表的数据之间建立连接,它可以是一列或者多列,一个表可以有一个或者多个外键。
  • 在设置外键的时候,要有两张表,其中一个是主表,另外一个是从表
  • 外键的主要作用就是保持数据的一致性、完整性,能够实验级联删除和级联更新


主表:对于两个具有关联关系的表而言,相关联字段中的主键所在的表就是主表


从表:对于两个具有关联关系的表而言,相关联字段中的外键所在的表就是从表


主表和从表都可以有主键,但是从表的主键不能作为主表的外键

定义外键是由从表定义的,定义自己的某个项去关联某个表的某个项,从而定义外键与主表的主键进行关联

主表删除、修改数据时,从表会进行同步,而主表加数据从表是不会同步的


(2)选取设置Mysql外键约束的字段


定义一个外键时,需要遵守下列规则:


  1. 主表必须存在于数据库中,或者是当前正在创建的表,如果是第二种情况,则主表和从表是同一个表,这样的表称为自参照表,这种结构称为自参照完整性
  2. 必须为主表定义主键
  3. 主键不允许出现空值,但是允许在外键出现空值,也就是说只要外键的每个非空值出现在指定的主键中,那么这个外键的内容就是正确的
  4. 在主表的表名后面指定列名或列名的组合,这个列或列的组合必须是主表的主键或候选主键
  5. 外键中的列的数目必须和主表中的主键中的列的数目相同
  6. 外键中的列的数据类型必须和主表中的主键中的列的数据类型相同
  7. 存储引擎必须是innoDB,使用mysql5.0以上版本


(3)使用外键约束foreign key


-在创建表时设置外键约束

******(1)进入数据库,创建库和进入库
[root@rzy ~]# mysql -u root -p123123
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.12 Source distribution
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> create database aaa;
Query OK, 1 row affected (0.00 sec)
mysql> use aaa;
Database changed
******(2)创建主表和从表,aaa为主表,bbb为从表,bbb从表的uuid项为aaa主表的外键
mysql> create table aaa(id int primary key,name char(10) not null,age int);
Query OK, 0 rows affected (0.00 sec)
mysql> create table bbb(id int primary key,name char(10),uuid int,constraint waijian foreign key(uuid) references aaa(id));
Query OK, 0 rows affected (0.01 sec)
#constraint :定义外键名称,这里定义的是waijian
#foreign key(uuid) references aaa(id) :定义本表的uuid项为aaa表的外键并且与id项关联
******(3)可以查看两个表的信息,key列中pri为主键,mul为外键
mysql> desc aaa;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id    | int(11)  | NO   | PRI | NULL    |       |
| name  | char(10) | NO   |     | NULL    |       |
| age   | int(11)  | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> desc bbb;  
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id    | int(11)  | NO   | PRI | NULL    |       |
| name  | char(10) | YES  |     | NULL    |       |
| uuid  | int(11)  | YES  | MUL | NULL    |       |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)

-在修改表时添加外键约束

mysql> alter table bbb add constraint waijian foreign key(uuid) references aaa(id); #添加外键约束
Query OK, 1 row affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0
mysql> show create table bbb; #查看bbb表的信息
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                                                                                                          |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| bbb   | CREATE TABLE `bbb` (
  `id` int(11) NOT NULL,
  `name` char(10) DEFAULT NULL,
  `uuid` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `waijian` (`uuid`),
  CONSTRAINT `waijian` FOREIGN KEY (`uuid`) REFERENCES `aaa` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

-删除外键约束

mysql> alter table bbb drop foreign key waijian; #删除外键约束,在从表上面删除
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql> show create table bbb; #查看bbb表的信息
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                                     |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| bbb   | CREATE TABLE `bbb` (
  `id` int(11) NOT NULL,
  `name` char(10) DEFAULT NULL,
  `uuid` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `waijian` (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)


二、内外连接查询


(1)inner join内连接查询


内连接是通过在查询数据时设置连接条件的方式,来移除查询后结果的数据行的交叉连接,利用条件表达式来消除交叉连接的某些数据行


在Mysql from子句中使用关键字inner join连接两张表,并且使用on子句来设置连接条件,如果没有任何条件,inner join和cross join 在语法上是等同的,两者可以互换


内连接是系统默认的表连接,所有在from子句后面可以省略inner关键字,只用关键字join,使用内连接后,from子句中的on子句可以用来设置连接表的条件


在from子句中可以在多个表之间连续使用inner join或join,如此可以同时实现多个表的内连接

mysql> create table aaa(id int,name char (10),age int); #创建两个表
Query OK, 0 rows affected (0.00 sec)
mysql> create table bbb(id int,name char (10),sex char(10));
Query OK, 0 rows affected (0.00 sec)
mysql> insert into aaa values(1,"zhangsan",18); #给两个表插入数据
Query OK, 1 row affected (0.00 sec)
mysql> insert into aaa values(2,"lisi",20);
Query OK, 1 row affected (0.00 sec)
mysql> insert into bbb values(1,"zhangsan","man");
Query OK, 1 row affected (0.00 sec)
mysql> insert into bbb values(2,"lisi","woman");
Query OK, 1 row affected (0.00 sec)
mysql> select * from aaa; #查看两个表的数据
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|    1 | zhangsan |   18 |
|    2 | lisi     |   20 |
+------+----------+------+
2 rows in set (0.00 sec)
mysql> select * from bbb;
+------+----------+-------+
| id   | name     | sex   |
+------+----------+-------+
|    1 | zhangsan | man   |
|    2 | lisi     | woman |
+------+----------+-------+
2 rows in set (0.00 sec)
mysql> alter table bbb drop name; #先删除bbb表的name项,两个表只要有一个相同项就可以,如果有多个就没必要进行内连接查询了
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql> select * from bbb;
+------+-------+
| id   | sex   |
+------+-------+
|    1 | man   |
|    2 | woman |
+------+-------+
2 rows in set (0.00 sec)
mysql> select name,sex from aaa,bbb where aaa.id=bbb.id; #查看aaa和bbb表中id项相同的name和sex项的数据
+----------+-------+
| name     | sex   |
+----------+-------+
| zhangsan | man   |
| lisi     | woman |
+----------+-------+
2 rows in set (0.00 sec)
mysql> select name,sex from aaa inner join bbb on aaa.id=bbb.id; #和上面查询结果相同,这个使用了inner join内连接
+----------+-------+
| name     | sex   |
+----------+-------+
| zhangsan | man   |
| lisi     | woman |
+----------+-------+
2 rows in set (0.00 sec)


(2)left\right join外连接查询(左连接和右连接)


内连接是交叉显示两个表的数据,而左右连接是将左边或右边的表作为参照表来显示数据


左外链接以左表为主,右外链接以右表为主

mysql> insert into aaa values(3,"hehe",99); #给aaa表再次插入一条数据
Query OK, 1 row affected (0.00 sec)
mysql> select * from aaa; #查看aaa表和bbb表的数据
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|    1 | zhangsan |   18 |
|    2 | lisi     |   20 |
|    3 | hehe     |   99 |
+------+----------+------+
3 rows in set (0.00 sec)
mysql> select * from bbb;
+------+-------+
| id   | sex   |
+------+-------+
|    1 | man   |
|    2 | woman |
+------+-------+
2 rows in set (0.00 sec)
mysql> select name,sex from aaa a left outer join bbb b on a.id=b.id; #使用左连接,以左表为参照表,可以看到aaa表中的hehe就算在bbb表中没有,也可以显示,只不过是null的,aaa a表示别名为a,bbb的别名为b
+----------+-------+
| name     | sex   |
+----------+-------+
| zhangsan | man   |
| lisi     | woman |
| hehe     | NULL  |
+----------+-------+
3 rows in set (0.00 sec)
mysql> select name,sex from aaa a right outer join bbb b on a.id=b.id; #和上面大同小异,使用右连接,以右表为参照表,可以看到aaa表的hehe没有了,这是因为bbb表中没有,而bbb表又是参照表所以不会显示
+----------+-------+
| name     | sex   |
+----------+-------+
| zhangsan | man   |
| lisi     | woman |
+----------+-------+
2 rows in set (0.00 sec)


相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
2月前
|
缓存 关系型数据库 MySQL
MySQL索引策略与查询性能调优实战
在实际应用中,需要根据具体的业务需求和查询模式,综合运用索引策略和查询性能调优方法,不断地测试和优化,以提高MySQL数据库的查询性能。
196 66
|
9天前
|
存储 SQL 关系型数据库
【MySQL基础篇】MySQL约束语法
文章介绍了MySQL中表的约束概念,包括非空、唯一、主键、默认和外键约束,以及如何在创建和修改表时指定这些约束。外键约束用于保持数据的一致性和完整性,文章通过示例展示了添加、删除外键的语法,并讨论了不同的删除/更新行为,如CASCADE和SETNULL。
【MySQL基础篇】MySQL约束语法
|
13天前
|
存储 Oracle 关系型数据库
索引在手,查询无忧:MySQL索引简介
MySQL 是一款广泛使用的关系型数据库管理系统,在2024年5月的DB-Engines排名中得分1084,仅次于Oracle。本文介绍MySQL索引的工作原理和类型,包括B+Tree、Hash、Full-text索引,以及主键、唯一、普通索引等,帮助开发者优化查询性能。索引类似于图书馆的分类系统,能快速定位数据行,极大提高检索效率。
48 8
|
16天前
|
SQL 关系型数据库 MySQL
MySQL 窗口函数详解:分析性查询的强大工具
MySQL 窗口函数从 8.0 版本开始支持,提供了一种灵活的方式处理 SQL 查询中的数据。无需分组即可对行集进行分析,常用于计算排名、累计和、移动平均值等。基本语法包括 `function_name([arguments]) OVER ([PARTITION BY columns] [ORDER BY columns] [frame_clause])`,常见函数有 `ROW_NUMBER()`, `RANK()`, `DENSE_RANK()`, `SUM()`, `AVG()` 等。窗口框架定义了计算聚合值时应包含的行。适用于复杂数据操作和分析报告。
58 11
|
20天前
|
存储 关系型数据库 MySQL
mysql怎么查询longblob类型数据的大小
通过本文的介绍,希望您能深入理解如何查询MySQL中 `LONG BLOB`类型数据的大小,并结合优化技术提升查询性能,以满足实际业务需求。
79 6
|
8天前
|
存储 关系型数据库 MySQL
MySQL(条件约束)
为了校验数据,让数据的正确性能够得到保证,约束,能够引进更多的检查操作,但是也会增加系统的成本开销
|
2月前
|
关系型数据库 MySQL 网络安全
DBeaver连接MySQL提示Access denied for user ‘‘@‘ip‘ (using password: YES)
“Access denied for user ''@'ip' (using password: YES)”错误通常与MySQL用户权限配置或网络设置有关。通过检查并正确配置用户名和密码、用户权限、MySQL配置文件及防火墙设置,可以有效解决此问题。希望本文能帮助您成功连接MySQL数据库。
73 4
|
2月前
|
关系型数据库 MySQL 数据处理
MySQL函数与约束
MySQL 提供了丰富的函数和强大的约束机制,用于数据处理和完整性维护。通过掌握这些工具,可以有效地管理和分析数据库中的数据,确保数据的一致性和准确性。无论是在日常数据查询中使用内置函数,还是在数据库设计中应用各种约束,都是确保数据库系统稳定、高效运行的关键。希望本文对您理解和应用 MySQL 函数与约束有所帮助。
36 1
|
11天前
|
存储 Oracle 关系型数据库
数据库传奇:MySQL创世之父的两千金My、Maria
《数据库传奇:MySQL创世之父的两千金My、Maria》介绍了MySQL的发展历程及其分支MariaDB。MySQL由Michael Widenius等人于1994年创建,现归Oracle所有,广泛应用于阿里巴巴、腾讯等企业。2009年,Widenius因担心Oracle收购影响MySQL的开源性,创建了MariaDB,提供额外功能和改进。维基百科、Google等已逐步替换为MariaDB,以确保更好的性能和社区支持。掌握MariaDB作为备用方案,对未来发展至关重要。
38 3
|
11天前
|
安全 关系型数据库 MySQL
MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!
《MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!》介绍了MySQL中的三种关键日志:二进制日志(Binary Log)、重做日志(Redo Log)和撤销日志(Undo Log)。这些日志确保了数据库的ACID特性,即原子性、一致性、隔离性和持久性。Redo Log记录数据页的物理修改,保证事务持久性;Undo Log记录事务的逆操作,支持回滚和多版本并发控制(MVCC)。文章还详细对比了InnoDB和MyISAM存储引擎在事务支持、锁定机制、并发性等方面的差异,强调了InnoDB在高并发和事务处理中的优势。通过这些机制,MySQL能够在事务执行、崩溃和恢复过程中保持
38 3