-
2021-01-19 09:55:40
当 你试图在mysql中创建一个外键的时候,这个出错会经常发生,这是非常令人沮丧的。像这种不能创建一个.frm 文件的报错好像暗示着操作系统的文件的权限错误或者其它原因,但实际上,这些都不是的,事实上,这个mysql报错已经被报告是一个mysql本身的 bug并出现在mysql 开发者列表当中很多年了,然而这似乎又是一种误导。
在很多实例中,这种错误的发生都是因为mysql一直以来都不能很好的支持的关系的问题, 更不幸的是它也并没有指明到底是哪一个问题会导致上面那种错误,下面我把导致这个可怕 的150错误的常见原因列出来了,并且我以可能性的大小作了排序
已知的原因:
1, 两个字段的类型或者大小不严格匹配,例如,如果一个是INT(10), 那么外键也必须设置成INT(10), 而不是 INT(11) 也不能是
TINYINT. 你得使用 SHOW 命令来查看字段的大小,因为一些查询浏览器有时候把 int(10) 和int(11)
都显示为integer。另外,你还必须确定两个字段是否一个为 SIGNED,而另一个又是UNSIGNED,
这两字段必须严格地一致匹配,更多关于signed 和 unsigned
的信息,请参阅:http://www.verysimple.com/blog/?p=57
2, 你试图引用的其中一个外键没有建立起索引,或者不是一个primary key , 如果其中一个不是primary key 的放,你必须为它创建一个索引。
3, 外键的名字是一个已经存在的一个键值了,这个时候,你应该检查你的数据库以确保外健名字是唯一的,或者你在键名后面加上几个随机的字符以测试是否是这个原因。
4, 其中一个或者两个表是MyISAM引擎的表,若想要使用外键约束,必须是InnoDB引擎,(实际上,如果两个表都是MyISAM 引擎的,这个错误根本不会发生,但也不会产生外键),你可以通过查询浏览器来设置表的引擎类型
5, 你可能设置了ON DELETE SET NULL, 但是相关的键的字段又设置成了NOTS NULL 值。你可能通过修改cascade 的属性值或者把字段属性设置成 allow null 来搞定这个bug.
6, 请确定你的Charset 和 Collate 选项在表级和字段级上的一致
7, 你可能设置为外键设置了一个默认值,如 default=0
8, 在这个关系里面,其中的一个字段是一个混合键值中的一个,它没有自己独立的索引,这时,你必须为它创建一个独立的索引。
9, ALTER 声明中有语法错误
10. 要连接的两个表的编码格式不同
更多相关内容 -
MySQL—外键关联操作
2022-03-25 16:24:30注意,MySQL 的 InnoDB 表引擎才支持外键关联,MyISAM 不支持。MySQL 还支持手动打开或关闭外键约束:SET FOREIGN_KEY_CHECKS = 0/1;。 使用外键约束最大的好处在于 MySQL 帮助我们完成数据的一致性检查。当我们...MySQL 的外键约束
注意,MySQL 的 InnoDB 表引擎才支持外键关联,MyISAM 不支持。MySQL 还支持手动打开或关闭外键约束:SET FOREIGN_KEY_CHECKS = 0/1;。
使用外键约束最大的好处在于 MySQL 帮助我们完成数据的一致性检查。当我们使用默认的外键类型 RESTRICT 时,在创建、修改或者删除记录时都会检查引用的合法性。
假设我们的数据库中包含 posts(id, author_id, content) 和 authors(id, name) 两张表,在执行如下所示的操作时都会触发数据库对外键的检查:
向 posts 表中插入数据时,检查 author_id 是否在 authors 表中存在;
修改 posts 表中的数据时,检查 author_id 是否在 authors 表中存在;
删除 authors 表中的数据时,检查 posts 中是否存在引用当前记录的外键;
作为专门用于管理数据的系统,数据库与应用服务相比能够更好地保证完整性,而上述的这些操作都是引入外键带来的额外工作,不过这也是数据库保证数据完整性的必要代价。上述的这些分析都是理论上的定性分析,我们其实可以简单地定量分析一下引入外键对性能的影响。
创建表时定义外键(References,参照)
在 CREATE TABLE 语句中,通过 FOREIGN KEY 关键字来指定外键,具体的语法格式如下:
[CONSTRAINT <外键名>] FOREIGN KEY 字段名 [,字段名2,…] REFERENCES <主表名> 主键列1 [,主键列2,…]
示例:
# 部门表 tb_dept1(主表) CREATE TABLE tb_dept1 ( id INT(11) PRIMARY KEY, name VARCHAR(22) NOT NULL, location VARCHAR(50) ) ENGINE=InnoDB DEFAULT CHARSET=gb2312; # 员工表 tb_emp6(从表),创建外键约束,让 deptId 作为外键关联到 tb_dept1 的主键 id。 CREATE TABLE tb_emp6 ( id INT(11) PRIMARY KEY, name VARCHAR(25), deptId INT(11), salary FLOAT, CONSTRAINT fk_emp_dept1 FOREIGN KEY(deptId) REFERENCES tb_dept1(id) ) ENGINE=InnoDB DEFAULT CHARSET=gb2312;
NOTE:从表的外键关联的必须是主表的主键,且主键和外键的数据类型必须一致。
以上语句执行成功之后,在表示 tb_emp6 上添加了名称为 fk_emp_dept1 的外键约束,外键名称为 deptId,其依赖于表 tb_dept1 的主键 id。
查看主表的约束信息
MariaDB [test_db]> select * from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where REFERENCED_TABLE_NAME='tb_dept1'\G; *************************** 1. row *************************** CONSTRAINT_CATALOG: def CONSTRAINT_SCHEMA: test_db CONSTRAINT_NAME: fk_emp_dept1 TABLE_CATALOG: def TABLE_SCHEMA: test_db TABLE_NAME: tb_emp6 COLUMN_NAME: deptId ORDINAL_POSITION: 1 POSITION_IN_UNIQUE_CONSTRAINT: 1 REFERENCED_TABLE_SCHEMA: test_db REFERENCED_TABLE_NAME: tb_dept1 REFERENCED_COLUMN_NAME: id 1 row in set (0.00 sec)
修改原有表的外键约束
外键约束也可以在修改表时添加,但是添加外键约束的前提是:从表中外键列中的数据必须与主表中主键列中的数据一致或者是没有数据。
在修改数据表时添加外键约束的语法格式如下:
ALTER TABLE <数据表名> ADD CONSTRAINT <外键名> FOREIGN KEY(<列名>) REFERENCES <主表名> (<列名>);
示例:修改数据表 tb_emp2,将字段 deptId 设置为外键,与数据表 tb_dept1 的主键 id 进行关联。
# 创建 tb_emp2(从表) CREATE TABLE tb_emp2 ( id INT(11) PRIMARY KEY, name VARCHAR(25), deptId INT(11), salary FLOAT ) ENGINE=InnoDB DEFAULT CHARSET=gb2312; MariaDB [test_db]> desc tb_emp2; +--------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | varchar(25) | YES | | NULL | | | deptId | int(11) | YES | | NULL | | | salary | float | YES | | NULL | | +--------+-------------+------+-----+---------+-------+ # 添加外键约束 ALTER TABLE tb_emp2 ADD CONSTRAINT fk_tb_dept1 FOREIGN KEY(deptId) REFERENCES tb_dept1(id); MariaDB [test_db]> desc tb_emp2; +--------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | varchar(25) | YES | | NULL | | | deptId | int(11) | YES | MUL | NULL | | | salary | float | YES | | NULL | | +--------+-------------+------+-----+---------+-------+ MariaDB [test_db]> SHOW CREATE TABLE tb_emp2\G *************************** 1. row *************************** Table: tb_emp2 Create Table: CREATE TABLE `tb_emp2` ( `id` int(11) NOT NULL, `name` varchar(25) DEFAULT NULL, `deptId` int(11) DEFAULT NULL, `salary` float DEFAULT NULL, PRIMARY KEY (`id`), KEY `fk_tb_dept1` (`deptId`), CONSTRAINT `fk_tb_dept1` FOREIGN KEY (`deptId`) REFERENCES `tb_dept1` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=gb2312
删除外键约束
当一个表中不需要外键约束时,就需要从表中将其删除。外键一旦删除,就会解除主表和从表之间的关联关系。
删除外键约束的语法格式如下所示:
ALTER TABLE <表名> DROP FOREIGN KEY <外键约束名>;
示例:删除数据表 tb_emp2 中的外键约束 fk_tb_dept1。
ALTER TABLE tb_emp2 DROP FOREIGN KEY fk_tb_dept1; MariaDB [test_db]> SHOW CREATE TABLE tb_emp2\G *************************** 1. row *************************** Table: tb_emp2 Create Table: CREATE TABLE `tb_emp2` ( `id` int(11) NOT NULL, `name` varchar(25) DEFAULT NULL, `deptId` int(11) DEFAULT NULL, `salary` float DEFAULT NULL, PRIMARY KEY (`id`), KEY `fk_tb_dept1` (`deptId`) ) ENGINE=InnoDB DEFAULT CHARSET=gb2312
如果感觉小编写得不错,请素质三连:点赞+转发+关注。我会努力写出更好的作品分享给大家。更多JAVA进阶学习资料小编已打包好,可以关注私信找我领取哦
-
mysql建立外键
2021-01-20 00:11:20建立外键的前提:本表的列必须与外键类型相同(外键必须是外表主键)。 外键作用: 使两张表形成关联,外键只能引用外表中的列的值! 指定主键关键字: foreign key(列名) 引用外键关键字: references <外键... -
解析MySQL创建外键关联错误 - errno:150
2020-09-10 20:24:55本篇文章是对MySQL创建外键关联错误-errno:150进行了详细的分析介绍,需要的朋友参考下 -
mysql外键关联
2021-02-01 21:28:32主键:是唯一标识一条记录,不能有重复的,不允许为空,用来...创建外键的方式:方式一:表已经创建好了,继续修改表的结构来添加外键,代码如下:create table student(id int primary key auto_increment,name c...主键:是唯一标识一条记录,不能有重复的,不允许为空,用来保证数据完整性
外键:是另一表的主键, 外键可以有重复的, 可以是空值,用来和其他表建立联系用的。所以说,如果谈到了外键,一定是至少涉及到两张表。
创建外键的方式:
方式一:表已经创建好了,继续修改表的结构来添加外键,代码如下:
create table student(
id int primary key auto_increment,
name char(32) not null,
sex char(32)
);
create table class(
id int primary key auto_increment,
name char(32) not null,
age int,
dept_id int
);
在上述的俩个已经创建好的表中,添加外键:
alter table class add foreign key(dept_id) references student(id)
alter table class:在从表class中进行操作;
add foreign key (dept_id):将从表的字段dept_id添加为外键;
references student(id):映射到主表studentt当中为id的字段
方式一:在创建表的时候增加外键,代码如下create table student(
id int primary key auto_increment,
name char(32) not null,
sex char(32)
);
create table class(
id int primary key auto_increment,
name char(32) not null,
age int,
dept_id int
constraint FK_id foreign key(dept_id) references student(id) );格式:[CONSTRAINT symbol] FOREIGN KEY [id] (从表的字段1) REFERENCES tbl_name (主表的字段2)
CONSTRAINT symbol:可以给这个外键约束起一个名字,有了名字,以后找到它就很方便了。如果不加此参数的话,系统会自动分配一个名字。
FOREIGN KEY:将从表中的字段1作为外键的字段。
REFERENCES:映射到主表的字段2。
删除外键:
alter table student drop foreign key 外键名;
-
解析MySQL创建外键关联错误 – errno:150
2021-01-19 22:25:08当你试图在mysql中创建一个外键的时候,这个出错会经常发生,这是非常令人沮丧的。像这种不能创建一个.frm 文件的报错好像暗示着操作系统的文件的权限错误或者其它原因,但实际上,这些都不是的,事实上,这个mysql... -
mysql创建外键关联
2021-01-31 05:59:55自己的代码总提示“ERROR 1005: Can't create table (errno: 150)”的错误郁闷了好几天,看了下面的文章终于成功了,犯了下面提到的三情况中...在系统不同的列表中,当数据库所有参照合法或非合法关联时都会涉及到参...自己的代码总提示“ERROR 1005: Can't create table (errno: 150)”的错误郁闷了好几天,看了下面的文章终于成功了,犯了下面提到的三情况中的第三种,太不细心了,居然忽略了“UNSIGNED ”,大家也要多留意呀!!
参照完整性(Referentialintegrity)是数据库设计中一个重要的概念。在系统不同的列表中,当数据库所有参照合法或非合法关联时都会涉及到参照完整性。当参照完整性存在时,任何与不存在记录的关联将变得无效化,由此可防止用户出现各种错误,从而提供更为准确和实用的数据库。
参照完整性通常通过外键(foreign key)的使用而被广泛应用。长久以来,流行工具开源RDBMSMySQL并没有支持外键,原因是这种支持将会降低RDBMS的速度和性能。然而,由于很多用户对参照完整性的优点倍感兴趣,最近MySQL的不同版本都通过新InnoDB列表引擎支持外键。由此,在数据库组成的列表中保持参照完整性将变得非常简单。
为了建立两个MySQL表之间的一个外键关系,必须满足以下三种情况:
* 两个表必须是InnoDB表类型。
* 使用在外键关系的域必须为索引型(Index)。
* 使用在外键关系的域必须与数据类型相似。
例子是理解以上要点的最好方法,新建一个parts的表,cpu字段用来存放所有的cpu配件型号,再新建一个pc的表,其中的cpumodel字段用来存放pc机中的cpu型号,显然,cpumodel字段中的所有记录应该存在于parts表中。
mysql> create table parts(
-> cpu char(20) not null,
-> index(cpu)
-> )engine=innodb;
Query OK, 0 rows affected (0.01 sec)
mysql> create table pc(
-> cpumodel char(20) not null,
-> index(cpumodel),
-> foreign key(cpumodel) references parts(cpu)
-> )engine=innodb;
Query OK, 0 rows affected (0.01 sec)
注意:对于非InnoDB表, FOREIGN KEY 语句将被忽略。对parts表添加数据1,2,3,接着对pc表进行测试,满足条件的 1 可以顺利insert进去,而不符合条件的字符 5 在insert表的时候,出现外键约束性错误,这正是我们想要的结果
mysql> insert into parts values('1'),('2'),('3');
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> insert into pc values('1');
Query OK, 1 row affected (0.01 sec)
mysql> insert into pc values('5');
ERROR 1452 (23000): Cannot add or update a child row: a foreign
key constraint fails (`Orange/pc`, CONSTRAINT `pc_ibfk_1` FOREIGN KEY
(`cpumodel`) REFERENCES `parts` (`cpu`))
如以上例子解释的,外键在捉摸数据入口错误上起着重要的作用,由此可建立更为强健更加集成的数据库。另一方面值得提到的是,执行外键核实是内部资料处理的过程,且不同表之间指定复杂的内部关系可以导致数据库的性能下降。所以,在参照完整性与性能考虑之间找到平衡点相当重要,而使用外键就是能够确保性能与稳健之间的最优结合。 我期望本期的有关外键的介绍对你有所好处,你将会在下回的MySQL数据库设计中感受到外键的好处。编程快乐!
分享到:
2009-07-14 10:30
浏览 6887
评论
-
使用navicat创建MySQL外键关联
2020-12-22 14:27:14要在Mysql数据库平台建立外键关联,必须满足以下几个条件:1.两个表必须为 InnoDB 类型。2. 外键和被引用键必须是索引中的第一列,InnoDB 不会自动为外键和被引用键建立索引,必须明确创建它们。3. 外键与对应的被... -
关于mysql的外键关联
2021-06-14 18:34:26关于mysql的外键关联 今天写项目的时候突然发现自己对外键掌握的不太熟练,所以特意去学了一下。 1.创建表的顺序 先建立父表!!!!再建立子表 2.删除表的顺序 先删除子表 再删父表 3.插入表的顺序 先插入父,再... -
mysql 创建表和外键关联
2021-07-19 17:29:44创建表 CREATE TABLE student( id INT(10) NOT NULL PRIMARY KEY, NAME VARCHAR(30) DEFAULT NULL, tid INT(10) DEFAULT NULL, KEY `fktid` (`tid`), CONSTRAINT `fktid` FOREIGN KEY(`tid`) ...外键关联语句 KEY `f -
MySQL无法创建外键的原因及解决方法
2020-09-09 13:14:07主要介绍了MySQL无法创建外键的原因及解决方法,然后在文中给大家及时了MySQL无法创建外键、查询外键的属性知识,感兴趣的朋友一起看看吧 -
mysql主外键建立心得
2021-02-08 03:20:12(1)、确保参照的表和字段是存在的(2)、关联表必须是Innodb存储类型(3)、必须设置主关联表主键(4)、主键与外键数据类型和字符编码(unsigned)必须一致(5)、确保以上声明的句法是正确的附:mysql建立表默认类型为:... -
mysql建外键+两表关联
2021-01-01 22:14:43mysql建外键+两表关联 说明: 一般情况下,开发过程中是不建立外键 以创建员工部门表为例 第一种方式 建表的时候指明外键 -- 创建部门表 create table dept( id int primary key auto_increment, -- 部门编号 name... -
5.MySQL建立表的关系(外键)
2021-11-07 09:03:151.前言 2.表与表关系 1.一对多关系 2.多对多关系: 3.一对一关系 3.对表总结: 4.补充: 1.修改表 2.复制表 -
MySQL创建外键关联报错1005
2018-09-28 17:31:03主要原因有 ...附上建立索引以及外键的语句(参考) ALTER TABLE country add INDEX index_name(emp_id) ALTER TABLE emp add INDEX index_name(c_id) ALTER TABLE emp ADD CONSTRAINT fk_em... -
mysql innodb 外键关联约束讲解
2021-01-19 14:01:11可通过查表信息查看外键的创建信息:Show create table tablename \G;从mysql3.23.44开始,innodb支持外键约束,跟Oracle基本相同,语法形式如下[CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...)REFERENCES... -
MySQL外键关联(一对多)&MySQL连接查询
2020-04-04 21:02:57MySQL外键关联(一对多) 外键说明 什么是外键? 1)表A中有字段(如身份证号)做了主键,表B中也有这个字段(身份证号),这里的身份证号一定来自表A同样字段里的内容,但再B表中身份证号对应id可以重复 2)... -
深入mysql外键关联问题的详解
2020-12-15 07:08:34今儿继续再看老师给推荐的深入浅出mysql数据库开发这本书,看到innodb数据库的外键关联问题时,遇到了一个问题,书上写的是可以对父表进行修改,从而同步到子表的外键上去,可是自己的实验却是没有能够。 代码如下:... -
sql语句创建外键关联
2021-01-29 10:26:47以创建学生教师表为例: 学生 id 关联教师 tid 学生表: student 教师表: teacher sql语句 : USE school; CREATE TABLE student( id INT(10) NOT NULL PRIMARY KEY, NAME VARCHAR(30) DEFAULT NULL, tid INT(10) ... -
MySQL 创建主键,外键和复合主键的语句 | 很文博客
2021-04-20 00:37:58MySQL 创建主键,外键和复合主键的方法,需要的朋友可以参考下。1.创建主键语法ALTER TABLE ...2.创建外键语法ALTER TABLE news_info[子表名] ADD CONSTRAINT FK_news_info_news_type[约束名] FOREIGN KEY (info_i... -
mysql中表设置了外键关联,可以语句强制更新
2017-06-15 16:15:33mysql中表设置了外键关联,可以语句强制更新 -
MySQL外键约束的实例讲解
2020-12-14 06:44:31对于两个通过外键关联的表,相关联字段中主键所在的表是主表,也称之为父表,外键所在的表是从表,也称之为子表,定义外键的时候需要遵守几个规则: 1、父表必须已经存在于数据库中,或者是当前正在创建的表。如果是... -
MYSQL外键约束和表关联
2021-07-05 16:50:08foreign key 功能 : 建立表与表之间的某种约束的关系,由于这种关系的存在,能够让表与表之间的数据,更加的完整,关连性更强,为了具体说明创建如下部门表和人员表。 示例 # 创建部门表 CREATE TABLE dept (id int... -
MySQL创建数据表并建立主外键关系详解
2020-09-09 02:55:06主要介绍了MySQL创建数据表并建立主外键关系详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 -
MySQL外键创建方式
2021-09-07 19:39:17创建外键的两种方式: 方式一: 先创建两张单独的表,在对表约束进行修改,添加外键约束。 USE school; ALTER TABLE `student1` RENAME `student`; SHOW CREATE TABLE `student`; CREATE TABLE `student` ( `id`... -
mysql外键(Foreign Key)介绍和创建外键的方法
2020-12-15 11:58:112.外键列必须建立了索引,MySQL 4.1.2以后的版本在建立外键时会自动创建索引,但如果在较早的版本则需要显示建立;3.外键关系的两个表的列必须是数据类型相似,也就是可以相互转换类型的列,比如int和tinyint可以,...