首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

mysql建表时怎么加外键

在MySQL中,创建外键是为了维护两个表之间的关联性。外键约束确保了引用完整性,即只有在被引用的表(父表)中存在的值才能被插入到引用表(子表)的外键列中。以下是在MySQL中创建外键的基本步骤和语法:

基础概念

  • 父表:包含主键的表,子表将引用这个表的主键。
  • 子表:包含外键的表,它引用父表的主键。
  • 外键约束:确保子表中的外键值必须在父表的主键中存在。

创建外键的语法

代码语言:txt
复制
CREATE TABLE 子表 (
    ...
    外键列名 数据类型,
    ...
    FOREIGN KEY (外键列名) REFERENCES 父表(主键列名)
    [ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION}]
    [ON UPDATE {RESTRICT | CASCADE | SET NULL | NO UPDATE}]
);

相关优势

  • 数据完整性:外键约束确保了数据的引用完整性,防止了孤立的记录。
  • 级联操作:可以设置外键约束,使得当父表中的记录被删除或更新时,子表中的相关记录也会相应地被删除或更新。

类型

  • 单表外键:一个表的外键引用同一个表的主键。
  • 跨表外键:一个表的外键引用另一个表的主键。

应用场景

假设我们有两个表,一个是students(学生表),另一个是courses(课程表)。每个学生可以选修多门课程,我们可以在students表中创建一个外键,引用courses表的主键。

代码语言:txt
复制
CREATE TABLE courses (
    course_id INT PRIMARY KEY,
    course_name VARCHAR(100)
);

CREATE TABLE students (
    student_id INT PRIMARY KEY,
    student_name VARCHAR(100),
    course_id INT,
    FOREIGN KEY (course_id) REFERENCES courses(course_id)
        ON DELETE RESTRICT
        ON UPDATE CASCADE
);

在这个例子中,students表的course_id列是一个外键,它引用了courses表的course_id主键。如果尝试删除courses表中的一个课程,而这个课程被某个学生选修了,那么删除操作将被阻止(RESTRICT)。如果更新了courses表中的某个课程ID,那么所有选修这门课程的学生记录中的课程ID也会自动更新(CASCADE)。

常见问题及解决方法

问题:无法创建外键约束

原因:可能是父表中没有定义主键,或者数据类型不匹配。

解决方法:确保父表中定义了主键,并且子表中外键列的数据类型与父表中主键列的数据类型相匹配。

代码语言:txt
复制
ALTER TABLE courses ADD PRIMARY KEY (course_id);

问题:外键约束导致插入或更新失败

原因:尝试插入或更新的子表记录中的外键值在父表中不存在。

解决方法:检查并确保插入或更新的值在父表的主键列中存在,或者修改外键约束的级联操作。

代码语言:txt
复制
INSERT INTO students (student_id, student_name, course_id) VALUES (1, 'Alice', 1);

确保courses表中存在course_id为1的记录。

参考链接

通过以上步骤和示例,你应该能够在MySQL中成功创建外键,并理解其相关概念和应用场景。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

oracle主键、基本语法

主键:唯一标识,不能为空,加快查询速度,自动创建索引 :约束内的数据的更新,从定义可以发现 是和主键联系,数据类型要统一,长度(存储大小)要统一。...这样在更新数据的时候会保持一致性 -创建表格语法: create table 名( 字段名1 字段类型(长度) 是否为空, 字段名2 字段类型 是否为空...); -增加主键 alter table 名 add constraint 主键名 primary key (字段名1); -增加: alter table 名...add constraint 键名 foreign key (字段名1) references 关联 (字段名2); 在建立表格就指定主键和 create table...varchar2(8) not null, constraint PK_T_STU primary key (STU_ID) ); 主键和一起建立

3.1K50
  • mysql如何添加一个

    1:创建一个父,主键作为子表的: 1 create table province( 2 pId int primary key auto_increment, 3 pName varchar...(20) 4 ); 2:创建子表,是父的主键: 1 create table user( 2 userId int primary key auto_increment, 3 userName varchar...(40), 4 pid int, 5 foreign key(pid) references province(pId) 6 ); 给一张添加,即给子表的添加主键的规则: 在子表声明一个字段pid...int,用于作为子表的,foreign key(子表的字段) references 父名(父的主键的字段名); 3:当创建好数据添加约束: alter table user add...foreign key(pid) references province(pId); alter table 子表的数据名 add foreign key(子表的键名称) references 父的数据名称

    4.3K70

    MySQL 核心模块揭秘 | 20 期 | 怎么锁?

    本文基于 MySQL 8.0.32 源码,存储引擎为 InnoDB。 正文 1. 是否已经加锁? 一个事务,在执行过程中,可能多次操作同一个。...接下来,我们看看 InnoDB 怎么判断事务是否已经对某个加了相同或者更高级别的锁。...这些会共用同一个锁互斥量,多个事务对这些锁,同一间把各自的锁结构加入对象的 locks 链表,申请获得同一个锁互斥量,会相互影响。 3. 会不会被阻塞?...上图是锁结构的所有属性,除 type_mode 属性,其它属性的初始化没有什么特殊的,我们就不一一展开介绍了。...当有事务需要对这个 AUTO-INC 锁,如果能立即获得锁,就直接使用 autoinc_lock 属性中保存的锁结构,不需要再额外创建一个新的锁结构。

    8110

    MySQL数据库——的约束(非空约束、唯一约束、主键约束、约束)

    以上仍然存在一个问题,当在员工中输入不存的部门,数据依然可以添加,不符合实际,因此,这里就可以通过使用约束来解决。 【概念】什么是约束?...,就是从中与主表主键对应的那一列,如:员工中的dep_id,其中,主表是一方,用来约束别人的,从可以是多方,被别人约束的。 注意:可以为NULL,但是不能是不存在的键值。 ?...1)创建添加 语法:         create table 名(                    ...                    ...列                    constraint 键名称 foreign key (列名称) references 主表名称(主表主键名称)         ); -- 创建部门...; 3)在创建后添加: ALTER TABLE 名称 ADD CONSTRAINT 键名称 FOREIGN KEY (字段名称) REFERENCES 主表名称(主表列名称); -- 添加

    14.2K21

    MySQL 外码约束原理:如何解决数据库添加数据产生的外码()约束?

    总结 ---- 前言 我们在使用 MySQL 数据库,添加数据如果设计不合理很容易出现外码约束的情况,为什么会产生这样的问题?那我们该如何处理这一问题呢?依据又是什么?...---- 说明:本次案例的案例情景是传统的数据库:学生-课程数据库。 一、插入新数据时报错约束?...我们在 Course 中插入课程号为 1 的数据提示违反了约束,插入命令如下: insert into course(cno,cname,cpno,ccredit) values('1','数据库...','5',4); 二、对于出错 SQL 语句的分析 我们先根据 Course 的定义,看哪一个是,查看 Course 定义的 SQL 语句如下: create table course ( cno...---- 总结 本文我们掌握了 MySQL 数据库如何在设计不合理遇到的外码约束的问题,并通过经典案例为大家分析了为何会出现这样的问题,同时顺着思路来设计业务的解决方案。

    3.1K20

    2024Mysql And Redis基础与进阶操作系列(4)作者——LJS

    但是索引名是的约束名 根据查询效率很高 删除外约束后,必须手动删除对应的索引 1.5 添加约束 (1) create table 主表名称( 字段1...(2)删除,先删除从emp,再删除主表dept 后一般情况下,的关联都是提前设计好了的,因此会在创建的时候就把约束定义好。...(一对一、一对多),比如:员工和部门(一对多),它们之间是否 一定要约束?...答案 答:不是的 问题2:建和不约束有什么区别? 答案: 约束,你的操作(创建、删除、添加、修改、删除)会受到限制,从语法层面受到限制。...面试题补充(2) 面试1.为什么 not null default '' 或 default 0 答:不让中出现null值。

    9610

    MySQL】04_约束

    (根据查询效率很高) 删除外约束后,必须 手动 删除对应的索引 添加约束 create table 主表名称( 字段1 数据类型 primary key, 字段2 数据类型 );...(2)删除,先删除从emp,再删除主表dept 后 一般情况下,的关联都是提前设计好了的,因此,会在创建的时候就把约束定义好。...不一定要约束 约束,你的操作(创建、删除、添加、修改、删除)会受到限制,从语法层面受到限制。...字段名 数据类型 not null; #删除默认值约束,保留非空约束 面试 (1) 为什么 not null default '' 或 default 0?...答:MySQL支持多种存储引擎,每一个都可以指定一个不同的存储引擎,需要注意的是:约束是用来保证数据的参照完整性的,如果之间需要关联,却指定了不同的存储引擎,那么这些之间是不能创建约束的

    2.4K20

    六年开发经验,整理Mysql数据库技巧笔记,全网最详细的笔记集合!

    ; 约束 添加约束 CREATE TABLE 名( 列名 数据类型 约束, ......KEY 键名; 后单独添加约束 ALTER TABLE 名 ADD CONSTRAINT 键名 FOREIGN KEY (本列名) REFERENCES 主表名(主键列名); 的级联更新和级联删除...:ALTER TABLE 名 ADD PRIMARY KEY(主键列名); 索引:ALTER TABLE 名 ADD CONSTRAINT 键名 FOREIGN KEY (本列名) REFERENCES...方式一:给数据中添加一个 version 列,每次更新后都将这个列的值 1。 读取数据,将版本号读取出来,在执行更新的时候,比较版本号。...读取数据,将时间读取出来,在执行更新的时候,比较时间。 如果相同则执行更新,如果不相同,说明此条数据已经发生了变化。 行锁和锁 InnoDB的行锁是针对索引的锁,不是针对记录的锁。

    1.4K20

    第13章_约束

    (根据查询效率很高) (9)删除外约束后,必须 手动 删除对应的索引 # 6.5 添加约束 (1) create table 主表名称( 字段1 数据类型 primary key,...(2)删除,先删除从emp,再删除主表dept (2)后 一般情况下,的关联都是提前设计好了的,因此,会在创建的时候就把约束定义好。...员工和部门(一对多),它们之间是否一定要约束?...答:不是的 问题 2:建和不约束有什么区别? 答:约束,你的操作(创建、删除、添加、修改、删除)会受到限制,从语法层面受到限制。...例如:在员工中,可以添加一个员工的信息,它的部门指定为一个完全不存在的部门。 问题 3:那么建和不约束和查询有没有关系? 答:没有 在 MySQL 里,约束是有成本的,需要消耗系统资源。

    37930

    第22问:我有带,你有数据么?

    问题 在实验 8 中,我们为生成了测试数据。 有小伙伴问:如果两个关系,我们生成的随机数据没法满足关系,怎么办? 实验 先来一个测试库: ? 两张有关系的: ?...先为 office 灌入一些基础数据: ? 然后为 user 灌入支持的数据: ? 来看一下我们生成的效果: ?...可以看到生成工具为 office1 和 office2 两个列都生成了符合规范的数据: ? 而外数据的采样数量正是 100。 ?...小技巧 如果大家希望为不同的列,生成不同采样数量的数据,可以创建多张,每张分别配置一个列,最后将多张合并为一张。.../fix_max-fk-samples/mysql_random_data_load.fix.tar.gz 下载作者临时修复的 linux 版本。

    74510

    MySQL 数据库添加数据为什么会产生外码()约束?原理就是什么?如何解决?

    文章目录 前言 一、插入新数据时报错约束? 二、对于出错 SQL 语句的分析 三、对于外码约束的分析 四、如何处理约束?...总结 ---- 前言 我们在使用 MySQL 数据库,添加数据如果设计不合理很容易出现外码约束的情况,为什么会产生这样的问题?那我们该如何处理这一问题呢?依据又是什么?...---- 本次案例的案例情景是传统的数据库:学生-课程数据库。 一、插入新数据时报错约束? 我们在 Course 中插入课程号为 1 的数据提示违反了约束。...,看哪一个是。...---- 总结 本文我们掌握了 MySQL 数据库如何在设计不合理遇到的外码约束的问题,并通过经典案例为大家分析了为何会出现这样的问题,同时顺着思路来设计业务的解决方案。

    3K31

    设计数据库中常见的规范

    避免使用MySQL保留字 不要关联,一般用代码维护 一般都选择INNODB存储引擎 选择合适的字符集 如果数据库字段是枚举,就在comment注释清楚 时间类型的选择 不建议使用存储过程,触发器...否则设计的时候,如果有查询条件的字段,一般就要索引 索引使用的注意事项: 索引不要的太多,一般单索引个数不要超过5个 去分度不高的字段,不能索引,如:性别 索引建立完成后,还是要避免索引失效的情况...不要关联,一般用代码维护 这个在阿里的java规范也有提到: 【强制】不得使用与级联,一切概念必须在业务层解决 使用存在性能问题、并发死锁问题、使用起来不方使等等。...每次做 DELETE 或者 UPDATE 都必须考虑约束,会导致开发的时候很难受,测试数据造数据也不方便。 还有一个场景不能使用,就是分库分。...又或者是把商品需要频繁增删改查的数据和基本不怎么用的数据给分离开来。 参考视频:21个MySQL设计的经验准则

    1.6K91

    必会的这15个Mysql优化问题,面试官、DBA都要高看你一眼,速度收藏

    你知道怎么调优SQL吗? 怎么设计或优化? 为什么要合理的使用字段的长度? 为什么要用冗余设计? 临时是什么? 为什么垂直分可以提升性能?...索引无法存储null值,当使用is null或is not nulli时会全扫描 like查询以"%"开头 对于复合索引,查询条件中没有给出索引中第一列的值 mysql内部评估全扫描比索引快...不得使用与级联,一切概念必须在应用层解决。 说明:以学生和成绩的关系为例,学生的 student_id 是主键,成绩的 student_id 则为。...与级联更新适用于单机低并发,不适合分布式、高并发集群;级联更新是强阻塞,存在数据库更新风暴的风险;影响数据库的插入速度。 禁止使用存储过程。存储过程难以调试和扩展,更没有移植性。...ORM 映射 POJO 类的布尔属性不能 is,而数据库字段必须 is_,要求在 resultMap 中进行字段与属性的映射。

    68730
    领券