ege*_*ari 9 mysql foreign-keys alter-table mysql-error-1025 mysql-error-1005
我有一个生产数据库,我已经重命名了几个外键的列.显然,mysql使我的经历真的很痛苦.
我的解决方案是删除所有索引和外键,重命名id列,然后重新添加索引和外键.
这适用于开发数据库的Windows上的mysql 5.1.
我去我的debian服务器上运行我的迁移脚本,它也使用mysql 5.1,它给出了以下错误:
mysql> ALTER TABLE `company_to_module`
-> ADD CONSTRAINT `FK82977604FE40A062` FOREIGN KEY (`company_id`) REFERENCES `company` (`company_id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
ERROR 1005 (HY000): Can't create table 'jobprep_production.#sql-44a5_76' (errno: 150)
Run Code Online (Sandbox Code Playgroud)
此表中没有值与我尝试添加的外键冲突.数据库没有改变.外键DID存在于...之前,因此数据很好.我们没有提到我使用了服务器上的SAME数据库,它可以在Windows上正常迁移.但是这些相同的外键迁移并没有采用Debian.
列使用相同的类型 - BIGINT(20)
这些名称实际上存在于各自的表中.
这些表是innodb.它们已经在其他列中具有外键.这不是一个新的数据库.
我不能删除表,因为这是一个生产数据库.
我的数据库中的"按原样"表格:
CREATE TABLE `company_to_module` (
`company_id` bigint(20) NOT NULL,
`module_id` bigint(20) NOT NULL,
KEY `FK8297760442C8F876` (`module_id`),
KEY `FK82977604FE40A062` (`company_id`) USING BTREE,
CONSTRAINT `FK8297760442C8F876` FOREIGN KEY (`module_id`) REFERENCES `module` (`module_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Run Code Online (Sandbox Code Playgroud)
和
Create Table: CREATE TABLE `company` (
`company_id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`address` varchar(255) DEFAULT NULL,
`postal_code` varchar(255) DEFAULT NULL,
`province_id` bigint(20) DEFAULT NULL,
`phone_number` varchar(255) DEFAULT NULL,
`is_enabled` bit(1) DEFAULT NULL,
`director_id` bigint(20) DEFAULT NULL,
`homepage_viewable` bit(1) NOT NULL DEFAULT b'1',
`courses_created` int(10) NOT NULL DEFAULT '0',
`header_background` varchar(25) DEFAULT '#172636',
`display_name` varchar(25) DEFAULT '#ffffff',
`tab_background` varchar(25) DEFAULT '#284767',
`tab_text` varchar(25) DEFAULT '#ffffff',
`hover_tab_background` varchar(25) DEFAULT '#284767',
`hover_tab_text` varchar(25) DEFAULT '#f2e0bd',
`selected_tab_background` varchar(25) DEFAULT '#f5f5f5',
`selected_tab_text` varchar(25) DEFAULT '#172636',
`hover_table_row_background` varchar(25) DEFAULT '#c0d2e4',
`link` varchar(25) DEFAULT '#4e6c92',
PRIMARY KEY (`company_id`),
KEY `FK61AE555A71DF3E03` (`province_id`),
KEY `FK61AE555AAC50C977` (`director_id`),
CONSTRAINT `company_ibfk_1` FOREIGN KEY (`director_id`) REFERENCES `user_account` (`user_account_id`),
CONSTRAINT `FK61AE555A71DF3E03` FOREIGN KEY (`province_id`) REFERENCES `province` (`province_id`)
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8
Run Code Online (Sandbox Code Playgroud)
这是innodb状态:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
110415 3:14:34 Error in foreign key constraint of table jobprep_production/#sql-44a5_1bc:
FOREIGN KEY (`company_id`) REFERENCES `company` (`company_id`) ON DELETE RESTRICT ON UPDATE RESTRICT:
Cannot resolve column name close to:
) ON DELETE RESTRICT ON UPDATE RESTRICT
Run Code Online (Sandbox Code Playgroud)
如果我尝试从'company_to_module'中删除索引,我收到此错误:
#1025 - Error on rename of './jobprep_production/#sql-44a5_23a' to './jobprep_production/company_to_module' (errno: 150)
Run Code Online (Sandbox Code Playgroud)
这是我的innodb变量:
+---------------------------------+------------------------+
| Variable_name | Value |
+---------------------------------+------------------------+
| innodb_adaptive_hash_index | ON |
| innodb_additional_mem_pool_size | 1048576 |
| innodb_autoextend_increment | 8 |
| innodb_autoinc_lock_mode | 1 |
| innodb_buffer_pool_size | 8388608 |
| innodb_checksums | ON |
| innodb_commit_concurrency | 0 |
| innodb_concurrency_tickets | 500 |
| innodb_data_file_path | ibdata1:10M:autoextend |
| innodb_data_home_dir | |
| innodb_doublewrite | ON |
| innodb_fast_shutdown | 1 |
| innodb_file_io_threads | 4 |
| innodb_file_per_table | OFF |
| innodb_flush_log_at_trx_commit | 1 |
| innodb_flush_method | |
| innodb_force_recovery | 0 |
| innodb_lock_wait_timeout | 50 |
| innodb_locks_unsafe_for_binlog | OFF |
| innodb_log_buffer_size | 1048576 |
| innodb_log_file_size | 5242880 |
| innodb_log_files_in_group | 2 |
| innodb_log_group_home_dir | ./ |
| innodb_max_dirty_pages_pct | 90 |
| innodb_max_purge_lag | 0 |
| innodb_mirrored_log_groups | 1 |
| innodb_open_files | 300 |
| innodb_rollback_on_timeout | OFF |
| innodb_stats_on_metadata | ON |
| innodb_support_xa | ON |
| innodb_sync_spin_loops | 20 |
| innodb_table_locks | ON |
| innodb_thread_concurrency | 8 |
| innodb_thread_sleep_delay | 10000 |
+---------------------------------+------------------------+
Run Code Online (Sandbox Code Playgroud)
我还想补充一点,当我在玩添加外键时,mysql损坏了我的数据库并将其销毁.我不得不从备份重新加载再试一次.
救命?:/
两个表都是InnoDB类型吗?
公司表是否有关于company_id的索引?
我猜您的表是MyISAM(默认情况下,如果您没有更改配置),并且您无法在MyISAM中创建外键约束.有关两个表,请参阅CREATE TABLE的说明.
如果两个表都是空的,则删除它们并重新创建它们,选择InnoDB作为引擎.您还可以在表创建脚本中添加FOREIGN KEY约束.
来自MySQL 参考手册:
外键定义符合以下条件:
两个表都必须是InnoDB表,它们不能是TEMPORARY表.
外键和引用键中的相应列必须在InnoDB 内部具有类似的内部数据类型,以便可以在不进行类型转换的情况下对它们进行比较.整数类型的大小和符号必须相同.字符串类型的长度不必相同.对于非二进制(字符)字符串列,字符集和排序规则必须相同.
InnoDB需要外键和引用键的索引,以便外键检查可以快速,不需要表扫描.在引用表中,必须有一个索引,其中外键列以相同的顺序列为第一列.如果引用表不存在,则会自动在引用表上创建此索引.(这与一些旧版本形成对比,在旧版本中必须显式创建索引或者外键约束的创建将失败.)如果给定,则使用index_name,如前所述.
InnoDB允许外键引用任何索引列或列组.但是,在引用的表中,必须有一个索引,其中引用的列被列为相同顺序的第一列.
不支持外键列上的索引前缀.这样做的一个结果是BLOB和TEXT列不能包含在外键中, 因为这些列上的索引必须始终包含前缀长度.
如果给出了CONSTRAINT符号子句,则符号值在数据库中必须是唯一的.如果未给出该子句,InnoDB会自动创建名称.
@egervari:如果你运行它会发生什么:
CREATE TABLE `test` (
`company_id` bigint(20) NOT NULL,
`module_id` bigint(20) NOT NULL,
KEY (`module_id`),
KEY (`company_id`),
CONSTRAINT `test_fk_module`
FOREIGN KEY (`module_id`)
REFERENCES `module` (`module_id`),
CONSTRAINT `test_fk_company`
FOREIGN KEY (`company_id`)
REFERENCES `company` (`company_id`)
ON DELETE RESTRICT
ON UPDATE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
Run Code Online (Sandbox Code Playgroud)
如果你跑:
ALTER TABLE `company_to_module`
ADD CONSTRAINT `company_to_module_fk_company`
FOREIGN KEY (`company_id`)
REFERENCES `company` (`company_id`)
ON DELETE RESTRICT
ON UPDATE RESTRICT;
Run Code Online (Sandbox Code Playgroud)
我只是使用 Windows 应用了重构,然后将数据库重新导入到 Debian - 它有效。
我认为可以肯定地说,Debian 服务器上或者 Linux 版本的 Mysql 上出现了一些问题 - 也许是 5.1 版本中的错误?
无论如何,我也将服务器上的内存从 1GB 升级到 2GB,这些问题都消失了。
我认为 MySQL 可能只是没有足够的内存来完成操作。如果是这样的话(看起来确实如此),我认为 MySQL 应该简单地这么说,而不是吐出这些错误 - 让我和这里的每个人都认为这是一个语法或与模式相关的问题。
不管怎样,感谢那些试图提供帮助的人。至少它帮助我隔离了所有不可能的事情。