MariaDB数据库的外键约束实例详解

外键

外键的用途是确保数据的完整性。它通常包括以下几种:


1 实体完整性,确保每个实体是唯一的(通过主键来实施)

2 域完整性,确保属性值只从一套特定可选的集合里选择

3 关联完整性,确保每个外键或是NULL(如果允许的话)或含有与相关主键值相配的值

1.什么是外键约束

与主键约束不同,创建外键约束不会自动创建对应的索引。 但是由于以下原因,对外键手动创建索引通常是有用的:

  • 当在查询中组合相关表中的数据时,经常在联接条件中使用外键列,方法是将一个表的外键约束中的一列或多列与另一个表中的主键列或唯一键列匹配。 索引使 数据库引擎 可以在外键表中快速查找相关数据。 但是,创建此索引并不是必需的。 即使没有对两个相关表定义主键或外键约束,也可以对来自这两个表中的数据进行组合,但两个表间的外键关系说明已用其键作为条件对其进行了优化,以便组合到查询中。
  • 对主键约束的更改可由相关表中的外键约束检查。

外键约束(foreign key)就是表与表之间的某种约定的关系,由于这种关系的存在,我们能够让表与表之间的数据,更加的完整,关连性更强。

关于数据表的完整性和关连性,可以举个例子

有二张表,一张是用户表,一张是订单表:

1.如果我删除了用户表里的用户,那么订单表里面跟这个用户有关的数据,就成了无头数据了,不完整了。
2.如果我在订单表里面,随便插入了一条数据,这个订单在用户表里面,没有与之对应的用户。这样数据也不完整了。

如果有外键的话,就方便多了,可以不让用户删除数据,或者删除用户的话,通过外键同样删除订单表里面的数据,这样也能让数据完整。

通过外键约束,每次插入或更新数据表时,都会检查数据的完整性。

2.创建外键约束

2.1 方法一:通过create table创建外键


语法:

参数的解释:

RESTRICT: 拒绝对父表的删除或更新操作。
CASCADE: 从父表删除或更新且自动删除或更新子表中匹配的行。ON DELETE CASCADE和ON UPDATE CASCADE都可用

注意:on update cascade是级联更新的意思,on delete cascade是级联删除的意思,意思就是说当你更新或删除主键表,那外键表也会跟随一起更新或删除。

精简化后的语法:

2.1.1 插入测试数据

例子:我们创建一个数据库,包含用户信息表和订单表

create database market; # 创建market数据库 Query OK,1 row affected (0.00 sec)

MariaDB [book]> use market; # 使用market数据库
Database changed

MariaDB [market]> create table userprofile(id int(11) not null auto_increment,name varchar(50) not null default '',sex int(1) not null default '0',primary key(id))ENGINE=innodb; # 创建userprofile数据表,指定使用innodb引擎
Query OK,0 rows affected (0.07 sec)

MariaDB [market]> create table user_order(o_id int(11) auto_increment,u_id int(11) default '0',username varchar(50),money int(11),primary key(o_id),index(u_id),foreign key order_f_key(u_id) references userprofile(id) on delete cascade on update cascade); # 创建user_order数据表,同时为user_order表的u_id字段做外键约束,绑定userprofile表的id字段
Query OK,0 rows affected (0.04 sec)

MariaDB [market]> insert into userprofile(name,sex)values('HA',1),('LB',2),('HPC',1); # 向userprofile数据表插入三条记录
Query OK,3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0

MariaDB [market]> select * from userprofile; # 查询userprofile数据表的所有记录
+----+------+-----+
| id | name | sex |
+----+------+-----+
| 1 | HA | 1 |
| 2 | LB | 2 |
| 3 | HPC | 1 |
+----+------+-----+
3 rows in set (0.00 sec)

MariaDB [market]> insert into user_order(u_id,username,money)values(1,'HA',234),(2,'LB',146),(3,'HPC',256); # 向user_order数据表插入三条记录
Query OK,3 rows affected (0.02 sec)
Records: 3 Duplicates: 0 Warnings: 0

MariaDB [market]> select * from user_order; # 查询user_order数据表的所有记录
+------+------+----------+-------+
| o_id | u_id | username | money |
+------+------+----------+-------+
| 1 | 1 | HA | 234 |
| 2 | 2 | LB | 146 |
| 3 | 3 | HPC | 256 |
+------+------+----------+-------+
3 rows in set (0.00 sec)

MariaDB [market]> select id,name,sex,money,o_id from userprofile,user_order where id=u_id; # 联表查询
+----+------+-----+-------+------+
| id | name | sex | money | o_id |
+----+------+-----+-------+------+
| 1 | HA | 1 | 234 | 1 |
| 2 | LB | 2 | 146 | 2 |
| 3 | HPC | 1 | 256 | 3 |
+----+------+-----+-------+------+
3 rows in set (0.03 sec)

2.1.2 测试级联删除

delete from userprofile where id=1; # 删除user表中id为1的数据 Query OK,1 row affected (0.01 sec)

MariaDB [market]> select id,user_order where id=u_id;
+----+------+-----+-------+------+
| id | name | sex | money | o_id |
+----+------+-----+-------+------+
| 2 | LB | 2 | 146 | 2 |
| 3 | HPC | 1 | 256 | 3 |
+----+------+-----+-------+------+
2 rows in set (0.00 sec)

MariaDB [market]> select * from user_order; # 查看order表的数据
+------+------+----------+-------+
| o_id | u_id | username | money |
+------+------+----------+-------+
| 2 | 2 | LB | 146 |
| 3 | 3 | HPC | 256 |
+------+------+----------+-------+
3 rows in set (0.00 sec)

2.1.3 测试级联更新


更新数据之前的状态

select * from userprofile; # 查看userprofile表的数据 +----+------+-----+ | id | name | sex | +----+------+-----+ | 2 | LB | 2 | | 3 | HPC | 1 | +----+------+-----+ 3 rows in set (0.00 sec)

MariaDB [market]> select * from user_order; # 查看order表的数据
+------+------+----------+-------+
| o_id | u_id | username | money |
+------+------+----------+-------+
| 2 | 2 | LB | 146 |
| 3 | 3 | HPC | 256 |
+------+------+----------+-------+
3 rows in set (0.00 sec)

更新数据

update userprofile set id=6 where id=2; # 把userprofile数据表中id为2的用户改为id为6 Query OK,1 row affected (0.02 sec) Rows matched: 1 Changed: 1 Warnings: 0

更新数据后的状态

select id,user_order where id=u_id; # 联表查询,可以看出表中已经没有id为2的用户了 +----+------+-----+-------+------+ | id | name | sex | money | o_id | +----+------+-----+-------+------+ | 6 | LB | 2 | 146 | 2 | | 3 | HPC | 1 | 256 | 3 | +----+------+-----+-------+------+ 2 rows in set (0.00 sec)

MariaDB [market]> select * from userprofile; # 查看userprofile表的数据,id只剩下3和6
+----+------+-----+
| id | name | sex |
+----+------+-----+
| 3 | HPC | 1 |
| 6 | LB | 2 |
+----+------+-----+
2 rows in set (0.00 sec)

MariaDB [market]> select * from user_order; # 查看user_order表的数据,u_id也改为6
+------+------+----------+-------+
| o_id | u_id | username | money |
+------+------+----------+-------+
| 2 | 6 | LB | 146 |
| 3 | 3 | HPC | 256 |
+------+------+----------+-------+
2 rows in set (0.00 sec)

2.1.4 测试数据完整性


insert into user_order(u_id,money)values(5,"XJ",345); # 单独向user_order数据表中插入数据,插入数据失败 ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`market`.`user_order`,CONSTRAINT `user_order_ibfk_1` FOREIGN KEY (`u_id`) REFERENCES `userprofile` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)

在上面的例子中,user_order表的外键约束,user_order表受userprofile表的约束

在user_order里面插入一条数据u_id为5用户,在userprofile表里面根本没有,所以插入数据失败

先向userprofile表中插入记录,再向user_order表中插入记录就可以了

insert into userprofile values(5,1); # 先向userprofile数据表中插入id为5的记录,插入数据成功 Query OK,1 row affected (0.01 sec)

MariaDB [market]> insert into user_order(u_id,money) values(5,345); # 再向user_order数据表中插入数据,成功
Query OK,1 row affected (0.00 sec)

MariaDB [market]> select * from userprofile; # 查询userprofile数据表中的所有记录
+----+------+-----+
| id | name | sex |
+----+------+-----+
| 3 | HPC | 1 |
| 5 | XJ | 1 |
| 6 | LB | 2 |
+----+------+-----+
3 rows in set (0.00 sec)

MariaDB [market]> select * from user_order; # 查询user_order数据表中的所有记录
+------+------+----------+-------+
| o_id | u_id | username | money |
+------+------+----------+-------+
| 2 | 6 | LB | 146 |
| 3 | 3 | HPC | 256 |
| 5 | 5 | XJ | 345 |
+------+------+----------+-------+
3 rows in set (0.01 sec)

2.2 方法二:通过alter table创建外键和级联更新,级联删除


语法:

例子:

create table user_order1(o_id int(11) auto_increment,u_id int(11) default "0",index(u_id)); # 创建user_order1数据表,创建表时不使用外键约束 Query OK,0 rows affected (0.11 sec)

MariaDB [market]> show create table user_order1; # 查看user_order1数据表的创建信息,没有外键约束
+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| user_order1 | CREATE TABLE user_order1 (
o_id int(11) NOT NULL AUTO_INCREMENT,u_id int(11) DEFAULT '0',username varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,money int(11) DEFAULT NULL,PRIMARY KEY (o_id),KEY u_id (u_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

MariaDB [market]> alter table user_order1 add foreign key(u_id) references userprofile(id) on delete cascade on update cascade; # 使用alter修改user_order1数据表,为user_order1数据表添加外键约束
Query OK,0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0

MariaDB [market]> show create table user_order1; # 查看user_order1数据表的创建信息,已经添加了外键约束
+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| user_order1 | CREATE TABLE user_order1 (
o_id int(11) NOT NULL AUTO_INCREMENT,KEY u_id (u_id),CONSTRAINT user_order1_ibfk_1 FOREIGN KEY (u_id) REFERENCES userprofile (id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

3.删除外键

语法

例子:

show create table user_order1; # 查看user_order1数据表的创建信息,包含外键约束 +-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | user_order1 | CREATE TABLE `user_order1` ( `o_id` int(11) NOT NULL AUTO_INCREMENT,CONSTRAINT `user_order1_ibfk_1` FOREIGN KEY (`u_id`) REFERENCES `userprofile` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci | +-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)

MariaDB [market]> alter table user_order1 drop foreign key user_order1_ibfk_1; # 为user_order1数据表删除外键约束,外键名称必须与从show create table user_order1语句中查到的相同
Query OK,0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0

MariaDB [market]> show create table user_order1; # 查看user_order1数据表的创建信息,外键约束已经被删除了
+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| user_order1 | CREATE TABLE user_order1 (
o_id int(11) NOT NULL AUTO_INCREMENT,KEY u_id (u_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

4.使用外键约束的条件

要想外键创建成功,必须满足以下4个条件:

1、确保参照的表和字段存在。
2、组成外键的字段被索引。
3、必须使用type指定存储引擎为:innodb.
4、外键字段和关联字段,数据类型必须一致。

5.使用外键约束需要的注意事项

1.on delete cascade on update cascade 添加级联删除和更新:
2.确保参照的表userprofile中id字段存在。
3.确保组成外键的字段u_id被索引
4.必须使用type指定存储引擎为:innodb。
5.外键字段和关联字段,数据类型必须一致。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对编程之家的支持。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


安装开始...1.打开“https://dev.mysql.com/downloadsepo/yum/”下载Mysql源      将下载好的mysql源上传linux服务器 2.yumlocalinstallmysql80*#安装源 centos7中默认安装的是mariadb数据库,如果想要安装mysql,首先要移除mariadb;
安装Helm3#官网下载慢#wgethttps://get.helm.sh/helm-v3.5.4-linux-amd64.tar.gzwgethttp://qiniu.dev-share.top/helm-v3.5.4-linux-amd64.tar.gztar-zxvfhelm-v3.5.4-linux-amd64.tar.gzcplinux-amd64/helm/usr/local/bin#查看helmclient版本helmversion
通过Linux命令行启动用的指令:systemctlstartmariadb.service反馈:Failedtostartmariadb.service:Unitmariadb.servicenotfound.MariaDB简介MariaDB是MySQL的一个分支,MariaDB打算保持与MySQL的高度兼容性,确保具有库二进制奇偶校验的直接替换功能,以及与MySQLAPI和命令
InstallingMariaDBServer10.4TodeployMariaDBCommunityServer10.4onRHEL7orCentOS7,firstdownloadandusethe mariadb_repo_setup scripttoconfiguretheMariaDBrepositoriesforYUM:$sudoyuminstallwget$wgethttps://downloads.mariadb.com/
阅读目录一什么是存储引擎二mysql支持的存储引擎三使用存储引擎一什么是存储引擎mysql中建立的库--> 文件夹库中建立的表--> 文件现实生活中我们用来存储数据的文件有不同的类型,每种文件类型对应各自不同的处理机制:比如处理文本用txt类型,处理表格用excel,处理图片
1、安装MariaDB安装命令yum-yinstallmariadbmariadb-server安装完成MariaDB,首先启动MariaDBsystemctlstartmariadb设置开机启动systemctlenablemariadb[root@node1~]#systemctlenablemariadbCreatedsymlinkfrom/etc/systemd/system/multi-user.target.wants/m
Centos7.5 刚安装的mariadb数据库报错报错:ERROR1045(28000):Accessdeniedforuser'root'@'localhost'(usingpassword:NO)原因一:没有启动数据库解决方法:systemctlstartmariadbsystemctlenablemariadb原因二:未知解决方法:[root@db01~]#
基于YUM安装的mariadb多实例.=================================================================1.yum安装mariadb-server包#yuminstallmariadb-server2.创建多实例对应的目录结构#mkdir/mysql/{3306,3307,3308}/{data,etc,socket,log,bin,pid}-pv#tree/mysql//mysql/
一、系统环境[root@localhost~]#cat/etcedhat-releaseCentOSLinuxrelease7.6.1810(Core)二、mysql安装#yuminstallmysqlmysql-servermysql-devel安装mysql-server失败,如下图:[root@localhost~]#yuminstallmysql-serverLoadedplugins:fastestmirrorLoadingm
数据库的选择两大点是:开源和跨平台,满足这三点MySQL、MongoDB和MariaDB。其中MariaDB是MySQL的分支,也是它的进阶产品,未来很有可能替代MySQL。与MySQL相比较,MariaDB更强的地方在于:Maria 存储引擎PBXT存储引擎XtraDB 存储引擎FederatedX 存储引擎更快的复制查询处理线
使用Navicat连接数据库时出现了 HostxxxisnotallowedtoconnecttothisMariaDbserver的情况。发现了是因为授权的问题,使得连接权限受阻。所以,只需要进入数据库中,给予其权限即可。具体解决代码如下:[root@localhost~]#mysql-uroot-pEnterpassword:#首先进入mys
1.临时表当绘画结束时,临时表会自动销毁,无法用showtables查看临时表。MariaDB[jason]>createtemporarytabletmp(prochar(30),citychar(30));QueryOK,0rowsaffected(0.01sec)MariaDB[jason]>insertintotmpvalues('shanghai','shanghai');QueryOK,1
为了看阳光我来到世上数据库介绍数据库是一个存放数据的仓库,目前市面上最流行的数据库大致氛围的两种,一种叫做关系型数据库,一种叫做非关系型数据库,而关系型数据库近期流行的即为mysql,mysql原本是一个开源的数据库后被oracle公司收购,开始进行服务收费,因此,市面上大多数免费
1,Linux上的mysql MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可。开发这个分支的原因之一是:甲骨文公司收购了MySQL后,有将MySQL闭源的潜在风险,因此社区采用分支的方式来避开这个风险。MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松
启动Mariadb前提需安装mariadb-server-安装mariadb-serveryuminstall-ymariadb-server-启动服务systemctlstartmariadb.service-添加到开机启动systemctlenablemariadb.service-安全设置,以及修改数据库管理员密码mysql_secure_installation-启
1、查看是否安装及可用安装:yumlist|grepmaria2、安装maria(依赖其他几个安装包):yuminstallmariadb-server.x86_64输入'y'继续安装直到安装结束3、检查是否安装:4、安装完后登录提示错误:mysql-uroot-p是由于安装完但是并未启动maria服务5、启动maria有以下几种方法:system
通过yum安装mariadb,并配置MySQL主从服务器主服务器:192.168.10.11从服务器:192.168.10.12#!/bin/bash#====================================================#Author:Mr.Song#CreateDate:2019-02-21#Description:autoconfigMySQLmaster&slave#=====================
实验:实现基于SSL加密的主从复制实验步骤:环境:三台主机,一台CA:200,一台master:150,一台slave:100平时都是在CA上帮用户生成私钥,在服务器上做的1CA,master,slave的证书相关文件mkdir/etc/my.cnf.d/sslcd/etc/my.cnf.d/sslopensslgenrsa2048>cakey.pemopensslreq-new-x509-k
MariaDB[db1]>select*fromstudent;+----+------+-----+--------+-------+|id|name|age|gender|phone|+----+------+-----+--------+-------+|1|a|20|m|119||2|b|20|m|120||3|c|20|m|110
过年了,在老家闲余时间想敲敲代码,发现在安装mariaDb的时候一直报错错误信息:Service‘MySQL’(MySQL)Faildtostart,Verifythatyouhavesuffcientprivilegestostartsystemservices.服务的MySQL(MySQL)启动错误,确认你有权限启动系统服务。记得多年前在使用sqlserver数