MYSQL建立外键失败几种情况记录Can’t create table...

当你试图在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 声明中有语法错误


最后:建立外键有点麻烦,可以直接用Myeclipse生成ddl。。。
posted on 2011-07-29 17:01 donqiang 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/donqiang/archive/2011/07/29/2121243.html

### 可能的原因分析 `Can't create table zabbix.history_str` 的错误通常表明在执行 `source` 命令导入数据时,创建表的操作失败。以下是可能的原因及其解决方案: #### 1. 表已存在 如果目标数据库中已经存在名为 `history_str` 的表,则可能会导致冲突。 - **解决方法**: 在导入前确认是否存在同名表,并决定是否需要删除或重命名现有表。 ```sql DROP TABLE IF EXISTS zabbix.history_str; ``` 此操作会删除现有的 `history_str` 表[^1]。 #### 2. 权限不足 当前用户可能缺乏足够的权限来创建表。 - **解决方法**: 确认 MySQL 用户具有相应的权限。可以通过以下命令授予必要权限: ```sql GRANT ALL PRIVILEGES ON zabbix.* TO 'root'@'localhost'; FLUSH PRIVILEGES; ``` 上述命令假设使用的用户名为 `root` 和主机地址为 `localhost`[^2]。 #### 3. 存储引擎不支持 某些存储引擎(如 MyISAM 或 MEMORY)可能存在限制,尤其是在 Zabbix 数据库配置中默认使用 InnoDB 引擎的情况下。 - **解决方法**: 修改 SQL 文件中的存储引擎定义部分,确保其兼容性。例如,在 SQL 脚本中指定 `ENGINE=InnoDB`: ```sql CREATE TABLE history_str ( ... ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ``` 这一步骤可以防止因存储引擎不匹配而导致的错误[^3]。 #### 4. 字段长度超出限制 Zabbix 中的历史表字段设计较为复杂,可能导致字段长度超过 MySQL 支持的最大值。 - **解决方法**: 检查 SQL 文件中是否有超长字段定义,并调整至合理范围。例如,将过长的字符串类型改为更短的数据类型: ```sql ALTER TABLE history_str MODIFY COLUMN value VARCHAR(255); ``` 该语句适用于字段 `value` 需要缩短的情况[^4]。 #### 5. 约束问题 如果 `history_str` 表依赖于其他表的关系,而这些关联表尚未被正确创建或初始化,也可能引发错误。 - **解决方法**: 确保所有相关联的表都已被成功创建后再尝试导入 `history_str` 表结构。可以在脚本开头加入必要的前置条件检查逻辑: ```sql SET foreign_key_checks = 0; -- 执行 CREATE TABLE 语句... SET foreign_key_checks = 1; ``` 通过临时关闭检查机制可规避潜在冲突. --- ### 综合建议 为了有效解决问题,推荐按照以下顺序排查和处理: 1. 删除已有同名表 (如有). 2. 授予充分权限给执行用户的账户. 3. 核实并统一所用存储引擎设置. 4. 审核各字段定义, 尤其关注字符集与最大长度参数. 5. 如果涉及复杂的体系, 则需额注意它们的一致性和完整性. 最终完成以上步骤之后重新运行源码导入过程即可恢复正常功能状态。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值