简体   繁体   English

使用 mysql 工作台创建 CHAR 类型的外键时出错:错误 1005:无法创建表(错误号:150)

[英]Error when creating foreign key of type CHAR with mysql workbench: Error 1005: Can't create table (errno: 150)

I have defined the following 2 tables:我定义了以下 2 个表:

record_status记录状态

SHOW CREATE TABLE record_status显示创建表记录状态

CREATE TABLE `record_status` (  
  `record_status_id` int(10) unsigned NOT NULL AUTO_INCREMENT,  
  `status` char(6) NOT NULL,  
  `status_description` varchar(15) NOT NULL,  
  `created_at` datetime NOT NULL,  
  `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,  
  PRIMARY KEY (`record_status_id`,`status`)  
  ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1

user用户

SHOW CREATE TABLE user显示创建表用户

CREATE TABLE `user` (  
  `user_id` int(10) unsigned NOT NULL AUTO_INCREMENT,  
  `handle` varchar(45) NOT NULL,  
  `email` varchar(255) NOT NULL,  
  `password` char(64) DEFAULT NULL,  
  `password_salt` binary(1) DEFAULT NULL,  
  `first_name` varchar(50) NOT NULL,  
  `last_name` varchar(50) NOT NULL,  
  `gender` char(1) DEFAULT NULL,  
  `birthday` date NOT NULL,  
  `created_at` datetime NOT NULL,  
  `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,  
  `user_status` char(6) DEFAULT NULL,  
  PRIMARY KEY (`user_id`),  
  KEY `usr_status_idx` (`user_status`)  
) ENGINE=InnoDB DEFAULT CHARSET=latin1

and I tried adding the foreign key user_status of type CHAR using mysql Workbench as follows:我尝试使用 mysql Workbench 添加 CHAR 类型的外键 user_status ,如下所示:

ALTER TABLE `mydatabase`.`user`  
  ADD CONSTRAINT `usr_status`  
    FOREIGN KEY (`user_status`)  
    REFERENCES `mydatabase`.`record_status` (`status`)
    ON DELETE NO ACTION  
    ON UPDATE NO ACTION;

but I am getting the following error:但我收到以下错误:

Error :错误

Executing SQL script in server
ERROR: Error 1005: Can't create table 'mydatabase.#sql-420_1b0' (errno: 150)

ALTER TABLE 'mydatabase'.'user'
ADD CONSTRAINT 'usr_status'
 FOREIGN KEY ('user_status')
 REFERENCES 'mydatabase'.'record_status'('status')
 ON DELETE NO ACTION
 ON UPDATE NO ACTION

SQL script execution finished: statements: 4 succeeded, 1 failed.

Question
My intention is to have the status column clearly show the current status for each user (ACTIVE, INACTV, DELETD) while still having the flexibility to join the record_status table with the user table using the record_status_id to find any rows with a given status for better performance.我的目的是让状态列清楚地显示每个用户的当前状态(ACTIVE、INACTV、DELETD),同时仍然可以灵活地使用 record_status_id 将 record_status 表与用户表连接起来,以更好地查找具有给定状态的任何行表现。

I found a similar post here Adding foreign key of type char in mysql which suggests to change my primary key's collation but, how would that affect my user table?我在这里找到了一个类似的帖子在 mysql 中添加 char 类型的外键,它建议更改我的主键的排序规则,但是,这将如何影响我的用户表?

Will I have to change the collation to the user_status field in my user table as well?我是否也必须将排序规则更改为用户表中的 user_status 字段? The user table will be queried every time a user logs in and I am concerned about performance or any constraints this may cause.每次用户登录时都会查询用户表,我担心性能或这可能导致的任何限制。

I also intend to add a foreign key for the status to a few other tables as well.我还打算将状态的外键添加到其他几个表中。 I would just like to know how this affects performance, or does it add any constraints?我只想知道这如何影响性能,或者它是否增加了任何限制?

Any input regarding my design will also be appreciated.任何有关我的设计的意见也将不胜感激。 Thank you for your help!感谢您的帮助!

The issue you're facing isn't actually related to collation (though collation can be a cause of the error you're experiencing under different circumstances).您面临的问题实际上与整理无关(尽管整理可能是您在不同情况下遇到错误的原因)。

Your FOREIGN KEY constraint is failing because you don't have an index individually on record_status.status .您的FOREIGN KEY约束失败,因为您在record_status.status上没有单独的索引。 You have that column as part of the composite PRIMARY KEY (record_status_id, status) , but for successful foreign key constraint creation, both the referencing table and the referenced table must have indexes on exactly the columns used in the key relationship (in addition to the same data types).您有列作为复合材料的一部分PRIMARY KEY (record_status_id, status) ,但对于外键约束创建成功,无论是引用表和引用表必须有准确的关键关系中使用的列的索引(除相同的数据类型)。

Adding the FOREIGN KEY constraint implicitly creates the necessary index on the referencing table, but you must still ensure you have the corresponding index on the referenced table.添加FOREIGN KEY约束会隐式地在引用表上创建必要的索引,但您仍必须确保在被引用表上具有相应的索引。

So given what you have now, if you added a single index on record_status.status , the constraint would correctly be created.因此,鉴于您现在拥有的情况,如果您在record_status.status上添加了单个索引,则将正确创建约束。

CREATE TABLE `record_status` (  
  `record_status_id` int(10) unsigned NOT NULL AUTO_INCREMENT,  
  `status` char(6) NOT NULL,  
  `status_description` varchar(15) NOT NULL,  
  `created_at` datetime NOT NULL,  
  `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,  
  PRIMARY KEY (`record_status_id`,`status`),
  -- This would make your relationship work...
  KEY (`status`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1

However, I don't think that's the best course of action.但是,我认为这不是最好的做法。 I don't see a need for the composite primary key on (record_status_id, status) , chiefly because the record_status_id is itself AUTO_INCREMENT and guaranteed to be unique.我认为(record_status_id, status)上不需要复合主键,主要是因为record_status_id本身就是AUTO_INCREMENT并且保证是唯一的。 That column alone could be the PRIMARY KEY , while still adding an additional UNIQUE KEY on status to satisfy the foreign key constraint's indexing requirement.该列本身可以是PRIMARY KEY ,同时仍然在status上添加一个额外的UNIQUE KEY以满足外键约束的索引要求。 After all, it is not the combination of record_status_id and status which uniquely identifies each row (making a primary key)毕竟,不是record_status_idstatus组合唯一标识每一行( record_status_id键)

CREATE TABLE `record_status` (  
  `record_status_id` int(10) unsigned NOT NULL AUTO_INCREMENT,  
  `status` char(6) NOT NULL,  
  `status_description` varchar(15) NOT NULL,  
  `created_at` datetime NOT NULL,  
  `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,  
  -- Primary only on record_status_id
  PRIMARY KEY (`record_status_id`),
  -- Additional UNIQUE index on status
  UNIQUE KEY (`status`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1

About the design -- eliminating record_status_id ...关于设计——去掉record_status_id ...

Without knowing how the rest of your application currently uses record_status_id , I can't say for sure if it required by your application code.在不知道您的应用程序的其余部分当前如何使用record_status_id ,我无法确定您的应用程序代码是否需要它。 But, if you wish to make the actual status value easily available to other tables, and it is merely CHAR(6) , it is possible that you actually have no need for record_status_id as an integer value.但是,如果您希望让其他表轻松获得实际status值,并且它只是CHAR(6) ,则您实际上可能不需要将record_status_id作为整数值。 After all, if the status string is intended to be unique, then it is perfectly capable of serving as the PRIMARY KEY on its own, without any auto-increment integer key.毕竟,如果status字符串是唯一的,那么它完全可以单独用作PRIMARY KEY ,而无需任何自动递增的整数键。

In that case, your record_status table would look like below, and your FOREIGN KEY constraint would correctly be added to users .在这种情况下,您的record_status表将如下所示,并且您的FOREIGN KEY约束将正确添加到users

CREATE TABLE `record_status` (
  -- Remove the auto_increment column!!
  `status` char(6) NOT NULL,  
  `status_description` varchar(15) NOT NULL,  
  `created_at` datetime NOT NULL,  
  `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,  
  -- Status is unique, and therefore can be the PK on its own
  PRIMARY KEY (`status`)  
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1

Given this setup, here's a sample showing the successful creation of the tables and addition of the FK constraint.鉴于此设置,以下示例显示成功创建表和添加 FK 约束。

You asked about performance implications of adding a status FK to other tables as well.您还询问了向其他表添加状态 FK 的性能影响。 It's tough to speculate on that without knowing the purpose, but if other tables share the same status values, then it makes sense to create their FK constraints to link to it in the same say you're doing with users .在不知道目的的情况下很难推测,但如果其他表共享相同的status值,那么创建它们的 FK 约束以链接到它是有意义的,就像你对users所做的一样。 And if that's the case, I would recommend doing it the same way, wherein the status column is CHAR(6) (or consider changing all of them to VARCHAR(6) ).如果是这种情况,我会建议以相同的方式执行此操作,其中status列是CHAR(6) (或考虑将它们全部更改为VARCHAR(6) )。 The value of record_status.status still makes sense as the true primary key, and can be used as the FK in as many related tables as necessary. record_status.status的值作为真正的主键仍然有意义,并且可以根据需要在尽可能多的相关表中用作 FK。

In all but the most gigantic scale, there should be no appreciable performance difference between using an INT value and a CHAR(6)/VARCHAR(6) value as the foreign key.除了最大的规模之外,在使用INT值和使用CHAR(6)/VARCHAR(6)值作为外键之间应该没有明显的性能差异。 And the storage size difference between them is equally tiny.并且它们之间的存储大小差异同样很小。 It isn't worth worrying about unless you must scale this to positively enormous proportions.除非您必须将其扩展到非常大的比例,否则不值得担心。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 MySQL Workbench-正向工程-错误1005:无法创建表(错误号:150) - MySQL Workbench - Forward Engineering - Error 1005: Can't create table (errno: 150) 外键错误 - 错误 1005 (HY000) … 无法创建表 … `stored_on` (errno: 150) - Foreign Key Error - ERROR 1005 (HY000) … Can't create table … `stored_on` (errno: 150) MySql错误代码:1005无法创建表错误:150 - MySql Error Code: 1005 Can't create table errno: 150 MySQL错误:1005无法创建表“ myTable”(错误号:150) - MySQL ERROR: 1005 Can't create table 'myTable' (errno : 150) MySQL ERROR 1005:无法创建表(错误号:150) - MySQL ERROR 1005: Can't create table (errno: 150) MYSQL Error Code: 1005. Can't create table `db_xcruz`.`users` (errno: 150 "Foreign key constraint is wrongly forms") - MYSQL Error Code: 1005. Can't create table `db_xcruz`.`users` (errno: 150 "Foreign key constraint is incorrectly formed") 外键问题:错误1005(HY000):无法创建表(错误号:150) - Foreign key issue:ERROR 1005 (HY000): Can't create table (errno: 150) 一般错误:1005 无法创建表(错误号:150“外键约束格式不正确”) - General error: 1005 Can't create table (errno: 150 "Foreign key constraint is incorrectly formed") 错误#1005-无法创建表`testdb`.`blog`(错误号:150“外键约束格式不正确”)? - error #1005 - Can't create table `testdb`.`blog` (errno: 150 “Foreign key constraint is incorrectly formed”)? 一般错误:1005 无法创建表...(errno:150“外键约束格式不正确” - General error : 1005 Can't create table ... (errno:150 "Foreign key constraint is incorrectly formed"
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM