MySQL и конфликт внешних ключей при попытке ВСТАВИТЬ - PullRequest
0 голосов
/ 26 августа 2010

Я делаю книгу Agile Yii.

В любом случае, я пытаюсь выполнить эту команду:

INSERT INTO tbl_project_user_assignment (project_id, user_id) values ('1','1'), ('1','2');

И я получаю эту ошибку:

ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`trackstar_dev`.`tbl_project_user_assignment`, CONSTRAINT `FK_project_user` FOREIGN KEY (`project_id`) REFERENCES `tbl_project` (`id`) ON DELETE CASCADE)

Итак ... я думаю, давайте посмотрим, есть ли в таблице tbl_project project_id = 1. Сделал быстрый SELECT * FROM tbl_project; и проект существует.

Хорошо, тогда давайте просто проверим пользователя, SELECT * FROM tbl_user; Yup 2 пользователь с id 1 и 2.

Что я делаю не так? Есть ли опечатка? В книге Agile YII есть несколько опечаток, но они не настолько серьезны и слишком новы, так что нет сообщений об ошибках (уже проверено).

Вот схема базы данных из исходного кода:

-- Disable foreign keys
SET FOREIGN_KEY_CHECKS = 0 ;

-- Create tables section -------------------------------------------------

-- Table tbl_project

CREATE TABLE IF NOT EXISTS `tbl_project` (
  `id` INTEGER NOT NULL auto_increment,
  `name` varchar(128) NOT NULL,
  `description` text NOT NULL,
  `create_time` DATETIME default NULL,
  `create_user_id` INTEGER default NULL,
  `update_time` DATETIME default NULL,
  `update_user_id` INTEGER default NULL,
  PRIMARY KEY  (`id`)
) ENGINE = InnoDB
;

-- DROP TABLE IF EXISTS `tbl_issue` ;

CREATE TABLE IF NOT EXISTS `tbl_issue` 
( 
  `id` INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `name` varchar(256) NOT NULL,
  `description` varchar(2000), 
  `project_id` INTEGER,
  `type_id` INTEGER,
  `status_id` INTEGER,
  `owner_id` INTEGER,
  `requester_id` INTEGER,
  `create_time` DATETIME,
  `create_user_id` INTEGER,
  `update_time` DATETIME,
  `update_user_id` INTEGER  
) ENGINE = InnoDB
; 

-- DROP TABLE IF EXISTS `tbl_user` ;

-- Table User

CREATE TABLE IF NOT EXISTS `tbl_user` 
(
  `id` INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `email` Varchar(256) NOT NULL,
  `username` Varchar(256),
  `password` Varchar(256),
  `last_login_time` Datetime,
  `create_time` DATETIME,
  `create_user_id` INTEGER,
  `update_time` DATETIME,
  `update_user_id` INTEGER
) ENGINE = InnoDB
; 

-- DROP TABLE IF EXISTS `tbl_project_user_assignment` ;

-- Table User

CREATE TABLE IF NOT EXISTS `tbl_project_user_assignment`
(
  `project_id` Int(11) NOT NULL,
  `user_id` Int(11) NOT NULL,
  `create_time` DATETIME,
  `create_user_id` INTEGER,
  `update_time` DATETIME,
  `update_user_id` INTEGER,
 PRIMARY KEY (`project_id`,`user_id`)
) ENGINE = InnoDB
;


-- The Relationships 
ALTER TABLE `tbl_issue` ADD CONSTRAINT `FK_issue_project` FOREIGN KEY (`project_id`) REFERENCES `tbl_project` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT;

ALTER TABLE `tbl_issue` ADD CONSTRAINT `FK_issue_owner` FOREIGN KEY (`owner_id`) REFERENCES `tbl_user` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT; 

ALTER TABLE `tbl_issue` ADD CONSTRAINT `FK_issue_requester` FOREIGN KEY (`requester_id`) REFERENCES `tbl_user` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT; 

ALTER TABLE `tbl_project_user_assignment` ADD CONSTRAINT `FK_project_user` FOREIGN KEY (`project_id`) REFERENCES `tbl_project` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT;

ALTER TABLE `tbl_project_user_assignment` ADD CONSTRAINT `FK_user_project` FOREIGN KEY (`user_id`) REFERENCES `tbl_user` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT;   

-- Insert some seed data so we can just begin using the database
INSERT INTO `tbl_user` 
  (`email`, `username`, `password`) 
VALUES 
  ('test1@notanaddress.com','Test_User_One', MD5('test1')),
  ('test2@notanaddress.com','Test_User_Two', MD5('test2'))    
;

-- Enable foreign keys
SET FOREIGN_KEY_CHECKS = 1 ;

В любом случае, спасибо заранее!

EDIT: Разъяснение того, что проект действительно существует ^^.

mysql> выбрать идентификатор, имя из tbl_project;

+ ---- + ------------------- +

| id | имя |

+ ---- + ------------------- +

| 6 | Проект 1 |

| 1 | проект зомби 1 |

+ ---- + ------------------- +

2 строки в наборе (0,00 с)

Ответы [ 2 ]

2 голосов
/ 26 августа 2010

project_id и user_id в tbl_project_user_assignment набираются как INT (11), а не как INTEGER. Я склонен думать, что INTEGER равен 4 байта, а INT (11) будет идти до 8 байтов.

Как уже говорилось выше, INTEGER решает проблему.

0 голосов
/ 23 сентября 2010

Это странная проблема, с которой вы столкнулись, а также странное исправление.Насколько мне известно, между INTEGER, INT или OR INT (XX) нет внутренней разницы (где XX - некоторое число). Все они имеют один и тот же тип данных с одинаковым распределением байтов и минимальным / максимальным диапазоном.Это не должно играть роль в оценке MySQL несоответствия типов для некоторых отношений fk.Моя версия / конфигурация MySQL (5.1.49) не генерирует того же нарушения ограничения, которое вы испытываете, когда используете INT (11) в одной таблице и INTEGER в другой.Интересно, связано ли это как-то с вашей конфигурацией или вы используете другие внешние инструменты БД.

Подробнее о внутреннем типе данных MySQL можно прочитать здесь:

http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html

особый интерес на этой странице:

Еще одно расширение поддерживается MySQL для дополнительного указания ширины отображения целочисленных типов данных в скобках после ключевого слова base для типа (дляНапример, INT (4)).Эта необязательная ширина отображения может использоваться приложениями для отображения целочисленных значений, ширина которых меньше ширины, указанной для столбца, путем добавления их слева с пробелами.(То есть эта ширина присутствует в метаданных, возвращаемых с наборами результатов. Независимо от того, используется ли она или нет, зависит от приложения.) Ширина отображения не ограничивает ни диапазон значений, которые могут быть сохранены в столбце, ни числоцифр, отображаемых для значений, ширина которых превышает указанную для столбца.Например, столбец, указанный как SMALLINT (3), имеет обычный диапазон SMALLINT от -32768 до 32767, а значения, выходящие за пределы диапазона, разрешенного тремя символами, отображаются с использованием более трех символов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...