2016-11-18 8 views
0

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

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

Однако моя проблема заключается в следующем. Если я вставляю новую запись в таблицу продаж для пользователя с id=10, и я неправильно вводим name='Peter Smith' вместо name='Roger Smith', он успешный, хотя 'Peter Smith' - это не имя человека с id=10 в таблице пользователей.

Может ли кто-нибудь указать мне в направлении, где я поступил неправильно? Большое спасибо.

CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT, 
`name` varchar(30) DEFAULT NULL, 
`dob` date DEFAULT NULL, 
PRIMARY KEY (`id`), 
KEY `name` (`name`) 
) ENGINE=InnoDB 

CREATE TABLE `sales` (
`salesid` int(11) NOT NULL AUTO_INCREMENT, 
`productname` varchar(30) DEFAULT NULL, 
`productprice` decimal(10,0) DEFAULT NULL, 
`quantity` int(11) DEFAULT NULL, 
`userid` int(11) NOT NULL, 
`user_name` varchar(30) DEFAULT NULL, 
PRIMARY KEY (`salesid`), 
KEY `FK_sales` (`userid`), 
KEY `FK_name` (`user_name`), 
CONSTRAINT `FK_name` FOREIGN KEY (`user_name`) REFERENCES `users` (`name`) ON DELETE CASCADE ON UPDATE CASCADE, 
CONSTRAINT `FK_sales` FOREIGN KEY (`userid`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE 
) ENGINE=InnoDB 

ответ

3

Где вы пошли неправильно это обновление аномалии, потому что реализация нарушает третью нормальную форму (3NF).

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


В модели, user_name в sales таблицы зависит от ключа sales таблицы. Похоже, вы хотите, чтобы он зависел от столбца userid.

Простое исправление удалитьuser_name столбец из таблицы sales. Когда вам нужно вернуть имя пользователя, выполните поиск в таблице users на основе user_id. В качестве примера, операция JOIN для таблицы users.

SELECT u.name AS user_name 
    , s.userid 
    , s.productprice 
    , ... 
    FROM sales s 
    JOIN users u 
    ON u.id = s.userid 

При таком подходе мы избегаем хранения избыточной информации. Атрибут e name зависит только от от столбца id в таблице users.


Если есть острая необходимость хранить user_name на sales столе, то логика приложения нужно будет следить за соблюдением правила о том, что user_name на строке в sales таблице должны быть такими же, как в name колонке в соответствующей строке в таблице users. Там нет декларативных ограничений, которые будут исполнять такого рода правила

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

Можно добавить ПЕРЕД ВСТАВКАМИ и ДОПОЛНИТЬ триггеры для обеспечения соблюдения правила, а также поиск и автоматическое заполнение столбца user_name.

+0

Фактически таблица продаж и таблица пользователей не находятся даже в 1NF, потому что в ней нет никакого натурального ключа. – nicomp

Смежные вопросы