РЕШЕНО: Удалив атрибут первичного ключа из внешних ключей.
Я создаю базу данных SQL для школы, чтобы отслеживать учителей, студентов, группы и платежи.
Я установил каскадирование всех внешних ключей при обновлении (поскольку я считаю, что это будет лучший способ), но я хочу установить для них значение null при удалении (то есть: если кто-то удаляет группу, студенты могут быть назначены в другую группу с обновлением), но сервер выдает мне это сообщение в таблицах grupo и grupoalumno, когда я пытаюсь создать базу данных:
Error: 150 "Foreign key constraint is incorrectly formed".
У меня есть внешние ключи, не отмеченные нулевым значением (что означает, что внешний ключ может быть нулевым значением), и, насколько я понял, решение состоит в том, чтобы установить первичные ключи, на которые ссылаются, как имеющие значение NULL, что заставляет меня сомневаться, что это было бы неплохо иметь PK null.
Я также подумал об ограничении удаления и использовании только обновлений (то есть: редактирование группы до тех пор, пока она не станет правильной, вместо ее удаления), но я думаю, что иметь возможность фактически удалить группу без каскадирования всей базы данных было бы разумно.
Я создаю таблицы в том порядке, в котором они должны быть (то есть: я не создаю таблицу, которая ссылается на ключ, который еще не был создан.

Я использую PHPMyAdmin и MySQL Workbench. Я считаю, что MySQL экспортирует базу данных с InnoDB в качестве движка.
Надеюсь, я объяснил. Заранее спасибо. Надеюсь многому научиться!
Код:
-- MySQL Script generated by MySQL Workbench
-- 10/29/18 21:25:26
-- Model: New Model Version: 1.0
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';
-- -----------------------------------------------------
-- Schema celex
-- -----------------------------------------------------
CREATE SCHEMA IF NOT EXISTS `celex` DEFAULT CHARACTER SET utf8 COLLATE utf8_spanish_ci ;
USE `celex` ;
-- -----------------------------------------------------
-- Table `celex`.`Grupo`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `celex`.`Grupo` (
`idGrupo` INT NOT NULL AUTO_INCREMENT,
`idioma` VARCHAR(45) NOT NULL,
`nivel` VARCHAR(45) NOT NULL,
`horarioInicio` TIME NULL,
`horarioTermino` TIME NULL,
PRIMARY KEY (`idGrupo`))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `celex`.`Alumno`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `celex`.`Alumno` (
`idAlumno` INT NOT NULL AUTO_INCREMENT,
`nombre` VARCHAR(45) NOT NULL,
`primerApellido` VARCHAR(45) NOT NULL,
`segundoApellido` VARCHAR(45) NOT NULL,
`email` VARCHAR(45) NOT NULL,
`telefono` VARCHAR(45) NULL,
`edad` INT NULL,
`procedencia` VARCHAR(45) NULL,
`fechaIngreso` DATE NOT NULL,
`nivelIngreso` VARCHAR(45) NOT NULL,
`moduloIngreso` INT NOT NULL,
`nivelColocacion` VARCHAR(45) NULL,
`moduloColocacion` INT NULL,
PRIMARY KEY (`idAlumno`))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `celex`.`Periodo`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `celex`.`Periodo` (
`idPeriodo` INT NOT NULL AUTO_INCREMENT,
`nombre` VARCHAR(45) NULL,
`inicio` DATE NOT NULL,
`termino` DATE NOT NULL,
PRIMARY KEY (`idPeriodo`))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `celex`.`GrupoAlumno`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `celex`.`GrupoAlumno` (
`idGrupoAlumno` INT NOT NULL AUTO_INCREMENT,
`modulo` INT NOT NULL,
`calificacionParcial` DOUBLE NULL,
`calificacionFinal` DOUBLE NULL,
`calificacionExtra` DOUBLE NULL,
`Periodo_idPeriodo` INT NULL,
`Grupo_idGrupo` INT NULL,
`Alumno_idAlumno` INT NULL,
PRIMARY KEY (`idGrupoAlumno`, `Periodo_idPeriodo`, `Grupo_idGrupo`, `Alumno_idAlumno`),
INDEX `fk_Grupo_has_Alumno_Alumno1_idx` (`Alumno_idAlumno` ASC),
INDEX `fk_Grupo_has_Alumno_Grupo_idx` (`Grupo_idGrupo` ASC),
INDEX `fk_GrupoAlumno_Periodo1_idx` (`Periodo_idPeriodo` ASC),
CONSTRAINT `fk_Grupo_has_Alumno_Grupo`
FOREIGN KEY (`Grupo_idGrupo`)
REFERENCES `celex`.`Grupo` (`idGrupo`)
ON DELETE SET NULL
ON UPDATE CASCADE,
CONSTRAINT `fk_Grupo_has_Alumno_Alumno1`
FOREIGN KEY (`Alumno_idAlumno`)
REFERENCES `celex`.`Alumno` (`idAlumno`)
ON DELETE SET NULL
ON UPDATE CASCADE,
CONSTRAINT `fk_GrupoAlumno_Periodo1`
FOREIGN KEY (`Periodo_idPeriodo`)
REFERENCES `celex`.`Periodo` (`idPeriodo`)
ON DELETE SET NULL
ON UPDATE CASCADE)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `celex`.`PeriodoAlumno`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `celex`.`PeriodoAlumno` (
`idPeriodoAlumno` INT NOT NULL AUTO_INCREMENT,
`cuota` TINYINT(1) NULL,
`Periodo_idPeriodo` INT NULL,
`Alumno_idAlumno` INT NULL,
PRIMARY KEY (`idPeriodoAlumno`, `Periodo_idPeriodo`, `Alumno_idAlumno`),
INDEX `fk_Periodo_has_Alumno_Alumno1_idx` (`Alumno_idAlumno` ASC),
INDEX `fk_Periodo_has_Alumno_Periodo1_idx` (`Periodo_idPeriodo` ASC),
CONSTRAINT `fk_Periodo_has_Alumno_Periodo1`
FOREIGN KEY (`Periodo_idPeriodo`)
REFERENCES `celex`.`Periodo` (`idPeriodo`)
ON DELETE SET NULL
ON UPDATE CASCADE,
CONSTRAINT `fk_Periodo_has_Alumno_Alumno1`
FOREIGN KEY (`Alumno_idAlumno`)
REFERENCES `celex`.`Alumno` (`idAlumno`)
ON DELETE SET NULL
ON UPDATE CASCADE)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `celex`.`Maestro`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `celex`.`Maestro` (
`idMaestro` INT NOT NULL AUTO_INCREMENT,
`nombre` VARCHAR(45) NOT NULL,
`primerApellido` VARCHAR(45) NOT NULL,
`segundoApellido` VARCHAR(45) NOT NULL,
`email` VARCHAR(45) NOT NULL,
`telefono` VARCHAR(45) NULL,
PRIMARY KEY (`idMaestro`))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `celex`.`GrupoMaestro`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `celex`.`GrupoMaestro` (
`idGrupoMaestro` INT NOT NULL AUTO_INCREMENT,
`Grupo_idGrupo` INT NULL,
`Maestro_idMaestro` INT NULL,
PRIMARY KEY (`idGrupoMaestro`, `Grupo_idGrupo`, `Maestro_idMaestro`),
INDEX `fk_Grupo_has_Maestro_Maestro1_idx` (`Maestro_idMaestro` ASC),
INDEX `fk_Grupo_has_Maestro_Grupo1_idx` (`Grupo_idGrupo` ASC),
CONSTRAINT `fk_Grupo_has_Maestro_Grupo1`
FOREIGN KEY (`Grupo_idGrupo`)
REFERENCES `celex`.`Grupo` (`idGrupo`)
ON DELETE SET NULL
ON UPDATE CASCADE,
CONSTRAINT `fk_Grupo_has_Maestro_Maestro1`
FOREIGN KEY (`Maestro_idMaestro`)
REFERENCES `celex`.`Maestro` (`idMaestro`)
ON DELETE SET NULL
ON UPDATE CASCADE)
ENGINE = InnoDB;
SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
изменить: добавление запроса для создания базы данных.
Увидев схему вашей базы данных, я чувствую, что вы можете просто удалить строки из GrupoAluno, поскольку это сводная таблица, которая связывает Aluno и Grupo, чтобы отсоединить учащегося от группы.
Вот почему я смущен, нет смысла иметь нулевой PK, но я не понимаю, почему mysql не принимает установку ограничения удаления для установки null. Я все перепроверяю, но сейчас у меня может быть туннельное зрение. Подожду пару часов, чтобы узнать причину.
Я собираюсь изучить эту возможность (об обновлении таблиц с учетом вашего предложения). Я придумал эту модель, потому что в течение года группы будут сильно меняться. Спасибо за предложение.
@Phiter Я собираюсь попробовать сделать таблицу n-n с maestro и grupo. Чтобы все отношения выходили за рамки основных таблиц, и посмотреть, поможет ли это.






При установке ограничения внешнего ключа, в дополнение к каскаду при обновлении, вы можете установить значение null при удалении следующим образом:
FOREIGN KEY (Grupo_idGrupo) REFERENCES Grupo (idGrupo)
ON DELETE SET NULL ON UPDATE CASCADE
Да, но ошибка продолжает выскакивать. Я обновил вопрос, добавив дополнительную информацию.
Нет. Первичные ключи никогда не должны быть нулевыми. Внешний ключ может ссылаться на ненулевой столбец. Вот как это делается на самом деле. Ваша ошибка могла быть по другой причине.