MySQL创建外键关联错误 - errno:150

本文详细解析了MySQL在创建外键时遇到的常见错误及其解决方案,包括字段类型匹配、索引建立、键名唯一性、表引擎选择等关键因素。提供了解决这些问题的步骤和建议,帮助开发者避免常见的创建外键失败情况。
当你试图在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. 要连接的两个表的编码格式不同
<think>首先,用户的问题是:“我想在MySQL 8.0中创建表时如何添加 请问MySQL 8.0 创建表时添加的方法”。我需要根据系统级指令来回答。 系统级指令包括: - 所有行内数学表达式使用$...$格式。 - 独立公式使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识。 - 回答结构清晰,帮助用户逐步解决问题,保证真实可靠。 用户的问题是关于MySQL 8.0中创建表时添加的方法。参考提供的引用: - 引用[1]:提到了约束的错误3780,原因是主表和从表的列数据类型不兼容,比如无符号约束不匹配。 - 引用[2]:描述了如何创建表,包括约束。 - 引用[3]:提到了创建表的顺序,因为约束需要先创建主表。 - 引用[4]:讨论了创建错误1005,可能原因是约束名重复。 我需要整合这些信息,提供一个清晰的步骤指南。 回答结构: 1. **引言**:简要解释的作用和重要性。 2. **步骤**:逐步说明如何在创建表时添加。 3. **注意事项**:基于引用,强调数据类型兼容性、约束名唯一性等。 4. **示例**:提供一个简单的SQL示例。 5. **相关问题**:生成相关问题。 生成相关问题: - 基于主题,如错误处理、优化等。 确保使用中文回答。 最终回答格式: - 使用Markdown,结构清晰。 - 在引用信息时,添加引用标识如[^1]。 - 结尾添加相关问题部分。 现在,构建内容: 1. **引言**:用于维护表间的引用完整性。在MySQL 8.0中,添加需要在创建表时指定。 2. **步骤**: - 确保存储引擎是InnoDB(因为MyISAM不支持)。 - 主表(被引用的表)必须先创建-创建从表时,使用FOREIGN KEY约束。 - 语法:在CREATE TABLE语句中,添加CONSTRAINT约束名 FOREIGN KEY (列名) REFERENCES 主表名(主列)。 3. **注意事项**: - 数据类型必须兼容:整数类型的大小和符号必须相同;字符串类型字符集和排序规则必须相同(引用[1])。 - 约束名必须在数据库中唯一(引用[4])。 - 列必须索引;如果未索引,MySQL会自动创建索引。 4. **示例**:基于引用[2]和[3],创建一个简单的例子。 - 例如,创建orders表和invoices表,其中invoices表有关联到orders。 5. **错误处理**:简要提及常见错误如3780(数据类型不兼容)和1005(约束名重复或表问题)。 相关问题: 1. 如何解决MySQL约束错误3780? 2. 约束在MySQL中有什么限制? 3. 如何修改现有表以添加? 确保回答真实可靠:基于MySQL文档和提供的引用。</think>### MySQL 8.0 创建表时添加的方法 在 MySQL 8.0 中,用于维护表间的引用完整性,确保数据一致性。添加需在创建表时指定,并遵循特定规则。以下是详细步骤和注意事项,基于 MySQL 官方文档和实际案例[^1][^2][^3]。 #### 步骤 1: 确保前提条件 - **存储引擎**:主表和从表必须使用 InnoDB 引擎MySQL 默认引擎),因为 MyISAM 不支持- **主表先创建**:被引用的表(主表)必须先于从表创建。例如,如果关联到 `orders` 表的 `id` 列,则需先创建 `orders` 表[^3]。 - **数据类型兼容**:列和主列的数据类型必须完全兼容: - 整数类型:大小和符号(如 UNSIGNED)必须相同。 - 字符串类型:字符集和排序规则必须相同,长度可不同[^1]。 #### 步骤 2: 创建表时添加语法 在 `CREATE TABLE` 语句中,使用 `FOREIGN KEY` 子句定义约束: ```sql CREATE TABLE 从表名 ( 列1 数据类型, 列2 数据类型, ... CONSTRAINT 约束名 FOREIGN KEY (列名) REFERENCES 主表名(主列名) [ON DELETE 操作] [ON UPDATE 操作] -- 可选:定义级联操作 ) ENGINE=InnoDB; ``` - **约束名**:必须唯一,避免重复(否则报错 1005)[^4]。 - **级联操作**:可选参数,如 `ON DELETE CASCADE`(主表删除时从表自动删除关联行)或 `ON UPDATE SET NULL`(主表更新时从表列设为 NULL)。 #### 步骤 3: 完整示例 假设创建两个表:`orders`(主表)和 `invoices`(从表),其中 `invoices` 的 `order_id` 列关联到 `orders.id`。 1. **先创建主表 `orders`**: ```sql CREATE TABLE orders ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, --,需带 UNSIGNED name VARCHAR(100) NOT NULL, price FLOAT, quantity INT, category VARCHAR(50) ) ENGINE=InnoDB; ``` 2. **再创建从表 `invoices`**: ```sql CREATE TABLE invoices ( number INT AUTO_INCREMENT PRIMARY KEY, order_id INT UNSIGNED, -- 数据类型与 orders.id 完全一致(包括 UNSIGNED) in_date DATE, total_amount FLOAT CHECK (total_amount > 0), CONSTRAINT fk_order -- 约束名唯一 FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE -- 可选级联删除 ) ENGINE=InnoDB; ``` - **关点**:`order_id` 的数据类型(`INT UNSIGNED`)必须与 `orders.id` 完全匹配,否则报错 3780[^1]。 #### 注意事项 1. **数据类型兼容**:常见错误 3780 因数据类型不匹配(如主有 UNSIGNED 而无)。检查符号、字符集等[^1]。 2. **约束名唯一**:约束名(如 `fk_order`)必须在数据库内唯一,否则报错 1005(errno: 121)[^4]。 3. **索引要求**:列会自动创建索引,无需手动添加。 4. **验证创建**:使用 `SHOW CREATE TABLE invoices;` 检查是否生效。 5. **错误处理**: - 报错 3780:检查数据类型兼容性。 - 报错 1005:确认约束名唯一或表名无冲突[^4]。 #### 示例场景 基于引用[2][^3],创建产品库时顺序应为: 1. 创建的表(如 `employees`)。 2. 创建主表(如 `orders`)。 3. 最后创建的从表(如 `invoices`)。 通过以上步骤,您可高效添加,确保数据完整性。💅
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值