Не удается добавить ограничение внешнего ключа-ошибка MySQL 1215 (HY000)

Я пытаюсь создать базу данных для системы управления тренажерным залом, но я не могу понять, почему я получаю эту ошибку. Я пытался найти ответ здесь, но не смог его найти.

ERROR 1215 (HY000): Cannot add foreign key constraint

CREATE TABLE sales(
    saleId int(100) NOT NULL AUTO_INCREMENT,
    accountNo int(100) NOT NULL,
    payName VARCHAR(100) NOT NULL,
    nextPayment DATE,
    supplementName VARCHAR(250),
    qty int(11),
    workoutName VARCHAR(100),
    sDate datetime NOT NULL DEFAULT NOW(),
    totalAmount DECIMAL(11,2) NOT NULL,
    CONSTRAINT PRIMARY KEY(saleId, accountNo, payName),
    CONSTRAINT FOREIGN KEY(accountNo) REFERENCES accounts(accountNo) ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT FOREIGN KEY(payName) REFERENCES paymentFor(payName) ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT FOREIGN KEY(supplementName) REFERENCES supplements(supplementName) ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT FOREIGN KEY(workoutName) REFERENCES workouts(workoutName) ON DELETE CASCADE ON UPDATE CASCADE
);
    ALTER TABLE sales AUTO_INCREMENT = 2001;

вот родительские таблицы.

CREATE TABLE accounts(
    accountNo int(100) NOT NULL AUTO_INCREMENT,
    accountType VARCHAR(100) NOT NULL,
    firstName VARCHAR(50) NOT NULL,
    lastName VARCHAR(60) NOT NULL,
    birthdate DATE NOT NULL,
    gender VARCHAR(7),
    city VARCHAR(50) NOT NULL,
    street VARCHAR(50),
    cellPhone VARCHAR(10),
    emergencyPhone VARCHAR(10),
    email VARCHAR(150) NOT NULL,
    description VARCHAR(350),
    occupation VARCHAR(50),
    createdOn datetime NOT NULL DEFAULT NOW(),
    CONSTRAINT PRIMARY KEY(accountNo)
);
    ALTER TABLE accounts AUTO_INCREMENT = 1001; 


CREATE TABLE supplements(
    supplementId int(100) NOT NULL AUTO_INCREMENT,
    supplementName VARCHAR(250) NOT NULL,
    manufacture VARCHAR(100),
    description VARCHAR(150),
    qtyOnHand INT(5),
    unitPrice DECIMAL(11,2),
    manufactureDate DATE,
    expirationDate DATE,
    CONSTRAINT PRIMARY KEY(supplementId, supplementName)
);
    ALTER TABLE supplements AUTO_INCREMENT = 3001;

CREATE TABLE workouts(
    workoutId int(100) NOT NULL AUTO_INCREMENT,
    workoutName VARCHAR(100) NOT NULL,
    description VARCHAR(7500) NOT NULL,
    duration VARCHAR(30),
    CONSTRAINT PRIMARY KEY(workoutId, workoutName)
);
    ALTER TABLE workouts AUTO_INCREMENT = 4001;



CREATE TABLE paymentFor(
    payId int(100) NOT NULL AUTO_INCREMENT,
    payName VARCHAR(100) NOT NULL,
    amount DECIMAL(11,2),
    CONSTRAINT PRIMARY KEY(payId, payName)
);
    ALTER TABLE paymentFor AUTO_INCREMENT = 5001;

вы можете помочь мне с этой проблемой? Спасибо.

8 ответов


для поля, определяемого как foreign key, указанное родительское поле должно иметь определенный индекс.

согласно документации на foreign key ограничения:

ссылки parent_tbl_name (index_col_name,...)

определение INDEX on workouts.workoutName, paymentFor.paymentName и supplements.supplementName соответственно. И убедитесь,что определения дочерних столбцов должны совпадать с определениями родительских столбцов.

изменить workouts определение таблицы, как показано ниже:

CREATE TABLE workouts(
    workoutId int(100) NOT NULL AUTO_INCREMENT,
    workoutName VARCHAR(100) NOT NULL,
    description VARCHAR(7500) NOT NULL,
    duration VARCHAR(30),

    KEY ( workoutName ), -- <---- this is newly added index key

    CONSTRAINT PRIMARY KEY(workoutId, workoutName)
);

изменить supplements определение таблицы как ниже:

CREATE TABLE supplements(
    supplementId int(100) NOT NULL AUTO_INCREMENT,
    supplementName VARCHAR(250) NOT NULL,
    manufacture VARCHAR(100),
    description VARCHAR(150),
    qtyOnHand INT(5),
    unitPrice DECIMAL(11,2),
    manufactureDate DATE,
    expirationDate DATE,

    KEY ( supplementName ), -- <---- this is newly added index key

    CONSTRAINT PRIMARY KEY(supplementId, supplementName)
);

изменить paymentFor определение таблицы как ниже:

CREATE TABLE paymentFor(
    payId int(100) NOT NULL AUTO_INCREMENT,
    payName VARCHAR(100) NOT NULL,
    amount DECIMAL(11,2),

    KEY ( payName ), -- <---- this is newly added index key

    CONSTRAINT PRIMARY KEY(payId, payName)
);

теперь измените определение дочерней таблицы, как показано ниже:

CREATE TABLE sales(
    saleId int(100) NOT NULL AUTO_INCREMENT,
    accountNo int(100) NOT NULL,
    payName VARCHAR(100) NOT NULL,
    nextPayment DATE,
    supplementName VARCHAR(250) NOT NULL,
    qty int(11),
    workoutName VARCHAR(100) NOT NULL,
    sDate datetime NOT NULL DEFAULT NOW(),
    totalAmount DECIMAL(11,2) NOT NULL,
    CONSTRAINT PRIMARY KEY(saleId, accountNo, payName),
    CONSTRAINT FOREIGN KEY(accountNo) 
       REFERENCES accounts(accountNo) 
       ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT FOREIGN KEY(payName) 
       REFERENCES paymentFor(payName) 
       ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT FOREIGN KEY(supplementName) 
       REFERENCES supplements(supplementName) 
       ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT FOREIGN KEY(workoutName) 
       REFERENCES workouts(workoutName) 
       ON DELETE CASCADE ON UPDATE CASCADE
);

смотрите:

[ограничение [символ]] внешний ключ
[аргумент index_name] (index_col_name, ...)
Ссылки tbl_name оператор (index_col_name,...)
[ON DELETE reference_option]
[При обновлении reference_option]

reference_option:
RESTRICT | CASCADE | SET NULL | NO ACTION


Если вы когда-нибудь хотите узнать, почему эта ошибка была , все, что вам нужно сделать, это запустить ниже команды и искать "ПОСЛЕДНЯЯ ОШИБКА ВНЕШНЕГО КЛЮЧА"

команда для запуска :-

mysql> SHOW ENGINE INNODB STATUS

вы будете знать причину подобных ошибок.


Внешние Ключи - это способ реализации отношений / ограничений между столбцами в разных таблицах.

существуют различные категории ограничений, которые влияют на то, как они применяются при обновлении или удалении строки из родительской таблицы:

Cascade: если строка удаляется из родительской, то также будут удалены все строки в дочерней таблице с соответствующим значением FK. Аналогично для изменений значения в Родительском таблица.

Restrict: строку нельзя удалить из родительской таблицы, если это нарушит ограничение FK с дочерней таблицей. Аналогично для изменений значения в родительской таблице.

No Action: очень похоже на "Restrict", за исключением того, что любые события/триггеры в родительской таблице будут выполняться до того, как ограничение будет применено – предоставление писателю приложения возможности разрешить любые конфликты ограничений FK с помощью хранимой процедуры.

Set NULL: Если NULL является допустимым значением для столбца FK в дочерней таблице, то он будет установлен в NULL, если связанные данные в родительской таблице обновляется или удаляется.

Set Default: если есть значение по умолчанию для столбца FK в дочерней таблице, то он будет использоваться, если связанные данные в родительской таблице обновляются или удаляются. Обратите внимание, что это не реализовано в этой версии – ограничение может быть добавлено в схему, но любое последующее удаление или обновление столбца в родительской таблице потерпеть неудачу.


несколько раз вы получите эту ошибку "#1215-не удается добавить ограничение внешнего ключа " из-за типа таблицы (InnoDB, MyISAM,..) несоответствие.

поэтому измените тип таблицы на тот же и попробуйте применить ограничение внешнего ключа

mysql> ALTER TABLE table_name ENGINE=InnoDB;

mysql> ALTER TABLE Orders ADD FOREIGN KEY (P_Id) REFERENCES Persons(P_Id)


это может сработать для некоторых людей. Просто добавьте набор символов по умолчанию как utf8

DEFAULT CHARACTER SET = utf8;

Я получал ту же ошибку. Причина была в том, что я имел в виду столбец в таблице, созданной с помощью charset utf8 из таблицы, созданной с помощью charset latin.

таблицы, созданные с помощью mySQL workbench create table utility, имеют латинскую кодировку по умолчанию.

легкий подход, чтобы узнать это, если вы используете workbench для просмотра таблицы create оператор любой таблицы. В конце будет строка кодировки по умолчанию.


Я не отвечаю на вышеуказанный вопрос, но только для людей, которые столкнутся с той же ошибкой mysql.

все, что я сделал, это изменить ссылочный движок таблицы на innodb.


я сталкиваюсь с этой ошибкой я добавляю ограничение внешнего ключа для столбца, который имеет "не нулевое ограничение", но я указал "on delete set null" во внешнем ограничении. Это противоречие поначалу может быть неочевидным.

вот мои две таблицы:

CREATE TABLE study (
    id int(11) NOT NULL AUTO_INCREMENT primary key,
    name varchar(100) NOT NULL,
    introduction text,
    objective varchar(250) DEFAULT NULL,
    method text,
    result text,
    conclusion varchar(250) DEFAULT NULL,
    future_action varchar(100) DEFAULT NULL
);

drop table client_study;
CREATE TABLE client_study (
      id int(11) NOT NULL AUTO_INCREMENT primary key,
      client_id int(11),
      study_id int(11) not null, --If delete 'not null' error goes away!
      contact_person int(11),
      effective_date datetime DEFAULT CURRENT_TIMESTAMP,
      trial_site int(11) DEFAULT NULL,
      UNIQUE KEY unqidx_client_study (client_id,study_id)
);

ALTER TABLE client_study
ADD CONSTRAINT FOREIGN KEY (study_id) REFERENCES study(id)
ON DELETE SET NULL ON UPDATE CASCADE;

ERROR 1215 (HY000): Cannot add foreign key constraint

если удалить ограничение NOT NULL для столбца study_id в таблице client_study, можно добавить внешний ключ. Другой альтернативой является сохранение ограничения not null на client_table, но измените определение внешнего ключа на on delete no action или другие варианты.