mysql - 在现有 MYSQL 数据库中使用 Alter Table 添加外键时出现问题 - 无法添加!帮助!

标签 mysql foreign-keys alter-table mysql-error-1005 mysql-error-1025

我有一个生产数据库,我在其中重命名了几个外键列。显然,根据我的经验,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)

此表中没有任何值会与我尝试添加的外键冲突。数据库没有改变。外键 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

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

这是 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

如果我尝试从“company_to_module”中删除索引,我会收到此错误:

#1025 - Error on rename of './jobprep_production/#sql-44a5_23a' to './jobprep_production/company_to_module' (errno: 150) 

这是我的 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                  |
+---------------------------------+------------------------+

我还想补充一点,当我尝试添加外键时,mysql 破坏了我的数据库并将其销毁。我必须从备份重新加载才能重试。

帮助? :/

最佳答案

两个表都是InnoDB类型吗?

company 表是否有 company_id 的索引?

我猜您的表是 MyISAM(如果您没有更改配置,则为默认表)并且您不能在 MyISAM 中创建外键约束。请参阅两个表的 CREATE TABLE 的说明。

如果两个表都是空的,删除它们并重新创建它们,选择 InnoDB 作为引擎。您还可以在表创建脚本中添加 FOREIGN KEY 约束。


来自 MySQL Reference Manual :

Foreign keys definitions are subject to the following conditions:

  • Both tables must be InnoDB tables and they must not be TEMPORARY tables.

  • Corresponding columns in the foreign key and the referenced key must have similar internal data types inside InnoDB so that they can be compared without a type conversion. The size and sign of integer types must be the same. The length of string types need not be the same. For nonbinary (character) string columns, the character set and collation must be the same.

  • InnoDB requires indexes on foreign keys and referenced keys so that foreign key checks can be fast and not require a table scan. In the referencing table, there must be an index where the foreign key columns are listed as the first columns in the same order. Such an index is created on the referencing table automatically if it does not exist. (This is in contrast to some older versions, in which indexes had to be created explicitly or the creation of foreign key constraints would fail.) index_name, if given, is used as described previously.

  • InnoDB permits a foreign key to reference any index column or group of columns. However, in the referenced table, there must be an index where the referenced columns are listed as the first columns in the same order.

  • Index prefixes on foreign key columns are not supported. One consequence of this is that BLOB and TEXT columns cannot be included in a foreign key because indexes on those columns must always include a prefix length.

  • If the CONSTRAINT symbol clause is given, the symbol value must be unique in the database. If the clause is not given, InnoDB creates the name automatically.


@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 ;

如果你运行:

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;

关于mysql - 在现有 MYSQL 数据库中使用 Alter Table 添加外键时出现问题 - 无法添加!帮助!,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5672472/

相关文章:

mysql 查询 - 如何合并另一个表中的表

mysql - 复杂的 MySQL Select Left Join 优化索引

database-design - 数据库设计和外键 : Where should they be added in related tables?

tsql - 尝试将列添加到临时表失败

sql - 错误 : syntax error at or near "modify" - in postgres

.net - OpenCart 1.5.3.1 中自动删除选项值

mysql - 无法连接到本地数据库

mysql - InnoDB 外键定义无法解析列名

mysql - 无法删除 MySQL 中带有外键的列

mysql - 如何仅在一个请求中创建 mysql 表并编辑(或选择)某些列的名称