Programing

errno : 150을 제공하는 외래 키를 사용하여 MySQL 생성 테이블

crosscheck 2020. 8. 26. 07:22
반응형

errno : 150을 제공하는 외래 키를 사용하여 MySQL 생성 테이블


다른 두 테이블의 기본 키를 참조하는 두 개의 외래 키를 사용하여 MySQL에서 테이블을 만들려고하는데 errno : 150 오류가 발생하고 테이블이 생성되지 않습니다.

다음은 세 테이블 모두에 대한 SQL입니다.

CREATE TABLE role_groups (
  `role_group_id` int(11) NOT NULL `AUTO_INCREMENT`,
  `name` varchar(20),
  `description` varchar(200),
  PRIMARY KEY (`role_group_id`)
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS `roles` (
  `role_id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50),
  `description` varchar(200),
  PRIMARY KEY (`role_id`)
) ENGINE=InnoDB;

create table role_map (
  `role_map_id` int not null `auto_increment`,
  `role_id` int not null,
  `role_group_id` int not null,
  primary key(`role_map_id`),
  foreign key(`role_id`) references roles(`role_id`),
  foreign key(`role_group_id`) references role_groups(`role_group_id`)
) engine=InnoDB;

어떤 도움이라도 대단히 감사하겠습니다.


나는 ALTER TABLE ADD FOREIGN KEY.

한 시간 후 오류 150이 발생하지 않도록 다음 조건이 충족되어야합니다.

  1. 참조 할 외래 키를 정의하기 전에 Parent 테이블이 있어야합니다. 올바른 순서로 테이블을 정의해야합니다. 먼저 상위 테이블, 그 다음 하위 테이블. 두 테이블이 서로를 참조하는 경우 FK 제약 조건없이 하나의 테이블을 생성 한 다음 두 번째 테이블을 생성 한 다음를 사용하여 첫 번째 테이블에 FK 제약 조건을 추가해야합니다 ALTER TABLE.

  2. 두 테이블은 모두 외래 키 제약 조건을 지원해야합니다 ENGINE=InnoDB. 다른 스토리지 엔진은 외래 키 정의를 자동으로 무시하므로 오류나 경고를 반환하지 않지만 FK 제약 조건은 저장되지 않습니다.

  3. Parent 테이블에서 참조 된 열은 키의 가장 왼쪽 열이어야합니다. 상위의 키가 PRIMARY KEY또는 인 경우 가장 UNIQUE KEY좋습니다.

  4. FK 정의는 PK 정의와 동일한 순서로 PK 열을 참조해야합니다. 예를 들어 FK 인 경우 REFERENCES Parent(a,b,c)상위의 PK가 순서대로 열에 정의되어서는 안됩니다 (a,c,b).

  5. Parent 테이블의 PK 열은 Child 테이블의 FK 열과 동일한 데이터 유형이어야합니다. 예를 들어 상위 테이블의 PK 열이 UNSIGNEDUNSIGNED경우 하위 테이블 필드의 해당 열에 대해 정의해야 합니다.

    예외 : 문자열의 길이는 다를 수 있습니다. 예를 들어, VARCHAR(10)참조 할 수 VARCHAR(20)있거나 그 반대 수 있습니다 .

  6. 모든 문자열 유형 FK 열은 해당 PK 열과 동일한 문자 집합 및 데이터 정렬을 가져야합니다.

  7. 자식 테이블에 이미 데이터가있는 경우 FK 열의 모든 값은 부모 테이블 PK 열의 값과 일치해야합니다. 다음과 같은 쿼리로 확인하십시오.

    SELECT COUNT(*) FROM Child LEFT OUTER JOIN Parent ON Child.FK = Parent.PK 
    WHERE Parent.PK IS NULL;
    

    일치하지 않는 값을 0으로 반환해야합니다. 분명히이 쿼리는 일반적인 예입니다. 테이블 이름과 열 이름을 대체해야합니다.

  8. 부모 테이블과 자식 테이블 모두 테이블이 될 수 없습니다 TEMPORARY.

  9. 부모 테이블과 자식 테이블 모두 테이블이 될 수 없습니다 PARTITIONED.

  10. ON DELETE SET NULL옵션을 사용 하여 FK를 선언하는 경우 FK 열은 null을 허용해야합니다.

  11. If you declare a constraint name for a foreign key, the constraint name must be unique in the whole schema, not only in the table in which the constraint is defined. Two tables may not have their own constraint with the same name.

  12. If there are any other FK's in other tables pointing at the same field you are attempting to create the new FK for, and they are malformed (i.e. different collation), they will need to be made consistent first. This may be a result of past changes where SET FOREIGN_KEY_CHECKS = 0; was utilized with an inconsistent relationship defined by mistake. See @andrewdotn's answer below for instructions on how to identify these problem FK's.

Hope this helps.


MySQL’s generic “errno 150” message “means that a foreign key constraint was not correctly formed.” As you probably already know if you are reading this page, the generic “errno: 150” error message is really unhelpful. However:

You can get the actual error message by running SHOW ENGINE INNODB STATUS; and then looking for LATEST FOREIGN KEY ERROR in the output.

For example, this attempt to create a foreign key constraint:

CREATE TABLE t1
(id INTEGER);

CREATE TABLE t2
(t1_id INTEGER,
 CONSTRAINT FOREIGN KEY (t1_id) REFERENCES t1 (id));

fails with the error Can't create table 'test.t2' (errno: 150). That doesn’t tell anyone anything useful other than that it’s a foreign key problem. But run SHOW ENGINE INNODB STATUS; and it will say:

------------------------
LATEST FOREIGN KEY ERROR
------------------------
130811 23:36:38 Error in foreign key constraint of table test/t2:
FOREIGN KEY (t1_id) REFERENCES t1 (id)):
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.

It says that the problem is it can’t find an index. SHOW INDEX FROM t1 shows that there aren’t any indexes at all for table t1. Fix that by, say, defining a primary key on t1, and the foreign key constraint will be created successfully.


Make sure that the properties of the two fields you are trying to link with a constraint are exactly the same.

Often, the 'unsigned' property on an ID column will catch you out.

ALTER TABLE `dbname`.`tablename` CHANGE `fieldname` `fieldname` int(10) UNSIGNED NULL;

What's the current state of your database when you run this script? Is it completely empty? Your SQL runs fine for me when creating a database from scratch, but errno 150 usually has to do with dropping & recreating tables that are part of a foreign key. I'm getting the feeling you're not working with a 100% fresh and new database.

If you're erroring out when "source"-ing your SQL file, you should be able to run the command "SHOW ENGINE INNODB STATUS" from the MySQL prompt immediately after the "source" command to see more detailed error info.

You may want to check out the manual entry too:

If you re-create a table that was dropped, it must have a definition that conforms to the foreign key constraints referencing it. It must have the right column names and types, and it must have indexes on the referenced keys, as stated earlier. If these are not satisfied, MySQL returns error number 1005 and refers to error 150 in the error message. If MySQL reports an error number 1005 from a CREATE TABLE statement, and the error message refers to error 150, table creation failed because a foreign key constraint was not correctly formed.

MySQL 5.1 reference manual.


For people who are viewing this thread with the same problem:

There are a lot of reasons for getting errors like this. For a fairly complete list of causes and solutions of foreign key errors in MySQL (including those discussed here), check out this link:

MySQL Foreign Key Errors and Errno 150


For others that find this SO entry via Google: Be sure that you aren't trying to do a SET NULL action on a foreign key (to be) column defined as "NOT NULL." That caused great frustration until I remembered to do a CHECK ENGINE INNODB STATUS.


Definitely it is not the case but I found this mistake pretty common and unobvious. The target of a FOREIGN KEY could be not PRIMARY KEY. Te answer which become useful for me is:

A FOREIGN KEY always must be pointed to a PRIMARY KEY true field of other table.

CREATE TABLE users(
   id INT AUTO_INCREMENT PRIMARY KEY,
   username VARCHAR(40));

CREATE TABLE userroles(
   id INT AUTO_INCREMENT PRIMARY KEY,
   user_id INT NOT NULL,
   FOREIGN KEY(user_id) REFERENCES users(id));

As pointed by @andrewdotn the best way is to see the detailed error(SHOW ENGINE INNODB STATUS;) instead of just an error code.

One of the reasons could be that an index already exists with the same name, may be in another table. As a practice, I recommend prefixing table name before the index name to avoid such collisions. e.g. instead of idx_userId use idx_userActionMapping_userId.


Please make sure at first that

  1. you are using InnoDB tables.
  2. field for FOREIGN KEY has the same type and length (!) as source field.

I had the same trouble and I've fixed it. I had unsigned INT for one field and just integer for other field.


Helpful tip, use SHOW WARNINGS; after trying your CREATE query and you will receive the error as well as the more detailed warning:

    ---------------------------------------------------------------------------------------------------------+
| Level   | Code | Message                                                                                                                                                                                                                                 |
+---------+------+--------------------------------------------------------------------------                          --------------------------------------------------------------------------------------------                          ---------------+
| Warning |  150 | Create table 'fakeDatabase/exampleTable' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns.
|
| Error   | 1005 | Can't create table 'exampleTable' (errno:150)                                                                                                                                                                           |
+---------+------+--------------------------------------------------------------------------                          --------------------------------------------------------------------------------------------                          ---------------+

So in this case, time to re-create my table!


This is usually happening when you try to source file into existing database. Drop all the tables first (or the DB itself). And then source file with SET foreign_key_checks = 0; at the beginning and SET foreign_key_checks = 1; at the end.


I've found another reason this fails... case sensitive table names.

For this table definition

CREATE TABLE user (
  userId int PRIMARY KEY AUTO_INCREMENT,
  username varchar(30) NOT NULL
) ENGINE=InnoDB;

This table definition works

CREATE TABLE product (
  id int PRIMARY KEY AUTO_INCREMENT,
  userId int,
  FOREIGN KEY fkProductUser1(userId) REFERENCES **u**ser(userId)
) ENGINE=InnoDB;

whereas this one fails

CREATE TABLE product (
  id int PRIMARY KEY AUTO_INCREMENT,
  userId int,
  FOREIGN KEY fkProductUser1(userId) REFERENCES User(userId)
) ENGINE=InnoDB;

The fact that it worked on Windows and failed on Unix took me a couple of hours to figure out. Hope that helps someone else.


MySQL Workbench 6.3 for Mac OS.

Problem: errno 150 on table X when trying to do Forward Engineering on a DB diagram, 20 out of 21 succeeded, 1 failed. If FKs on table X were deleted, the error moved to a different table that wasn't failing before.

Changed all tables engine to myISAM and it worked just fine.

enter image description here


Also worth checking that you aren't accidentally operating on the wrong database. This error will occur if the foreign table does not exist. Why does MySQL have to be so cryptic?


Make sure that the foreign keys are not listed as unique in the parent. I had this same problem and I solved it by demarcating it as not unique.


In my case it was due to the fact that the field that was a foreign key field had a too long name, ie. foreign key (some_other_table_with_long_name_id). Try sth shorter. Error message is a bit misleading in that case.

Also, as @Jon mentioned earlier - field definitions have to be the same (watch out for unsigned subtype).


(Side notes too big for a Comment)

There is no need for an AUTO_INCREMENT id in a mapping table; get rid of it.

Change the PRIMARY KEY to (role_id, role_group_id) (in either order). This will make accesses faster.

Since you probably want to map both directions, also add an INDEX with those two columns in the opposite order. (There is no need to make it UNIQUE.)

More tips: http://mysql.rjweb.org/doc.php/index_cookbook_mysql#speeding_up_wp_postmeta


When the foreign key constraint is based on varchar type, then in addition to the list provided by marv-el the target column must have an unique constraint.


execute below line before creating table : SET FOREIGN_KEY_CHECKS = 0;

FOREIGN_KEY_CHECKS option specifies whether or not to check foreign key constraints for InnoDB tables.

-- Specify to check foreign key constraints (this is the default)

SET FOREIGN_KEY_CHECKS = 1;

 

-- Do not check foreign key constraints

SET FOREIGN_KEY_CHECKS = 0;

When to Use : Temporarily disabling referential constraints (set FOREIGN_KEY_CHECKS to 0) is useful when you need to re-create the tables and load data in any parent-child order


I encountered the same problem, but I check find that I hadn't the parent table. So I just edit the parent migration in front of the child migration. Just do it.

참고URL : https://stackoverflow.com/questions/1457305/mysql-creating-tables-with-foreign-keys-giving-errno-150

반응형