Сложность внешнего ключа InnoDB? - PullRequest
1 голос
/ 22 апреля 2011

Ниже у меня есть две таблицы

users и users_profiles

Оба являются innoDB и параметрами сортировки: utf8_general_ci

Ониследующим образом:

пользователи

CREATE TABLE `users` (
`uid` int(11) NOT NULL AUTO_INCREMENT,
`status` char(10) NOT NULL,
`username` varchar(15) NOT NULL,
`email` varchar(50) NOT NULL,
`password` char(32) NOT NULL,
`reg_date` int(11) NOT NULL,
`ip` varchar(39) DEFAULT NULL,
PRIMARY KEY (`uid`),
UNIQUE KEY `username` (`username`,`email`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

users_profiles

CREATE TABLE `users_profiles` (
`uid` int(11) NOT NULL,
`first_name` varchar(40) DEFAULT NULL,
`last_name` varchar(50) DEFAULT NULL,
`gender` char(6) DEFAULT NULL,
`website` varchar(100) DEFAULT NULL,
`msn` varchar(60) DEFAULT NULL,
`aim` varchar(60) DEFAULT NULL,
`yim` varchar(60) DEFAULT NULL,
`twitter` varchar(15) DEFAULT NULL,
UNIQUE KEY `uid` (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

После создания таблиц в phpmyadmin я создалвнешний ключ в таблице users_profiles, приведенный ниже код - это то, что phpMyAdmin создал.

Как показано ниже:

ALTER TABLE `users_profiles`
ADD CONSTRAINT `users_profiles_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `users` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE;

в основном users_profiles.uid является внешним ключом и ссылается на users.uid

В phpMyAdmin я захожу на , вставляю и заполняю некоторые примеры данных, оставляя uid, очевидно, с автоматическим приращением.Вставив запись в таблицу пользователей, я захожу в таблицу users_profiles и замечаю, что users.uid автоматически не вставляется в users_profiles,

Это нормально?

Причина, по которой, например, кто-то регистрируется в форме, у него спрашивают имя пользователя, адрес электронной почты и пароль, и я делаю запрос в php, чтобы вставить эти данные в users table, iЯ подумал, что, поскольку у меня есть внешний ключ, он также автоматически вставит строку в таблицу users_profiles с таблицей uid from users, поэтому существует связь между пользователем и его профилем.Но когда я вставляю запись в таблицу пользователей, users.uid не вставляется в таблицу users_profiles.

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

Если я вставлю строку в таблицу users , а затем вручную добавлю users.uid в users_profiles.uid (теперь они связаны) и добавлю, например, мои first_name и last_name,в phpmyadmin удалить пользователя из таблицы users он удаляет строку в таблице users_profiles.Это работает, как и должно быть, так как я не хочу, чтобы пользователь был удален и профиль остался.

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

Может кто-нибудь объяснить, почему он не работает, как я ожидал, может быть, он должен работать так, как я хочу, но что-то не так, или я упускаю весь смысл в противном случае.


ОБНОВЛЕНИЕ

Что касается ответа от @Mark Wilkins

Я понимаю, что вы имеете в виду сейчас.Но я не уверен на 100% в следующем:

Пользователь регистрируется, запись создается в таблице пользователей;они входят в систему и заходят на страницу профиля, где могут заполнить ее и отправить форму.

При обработке формы я прав, думая, что мне нужно будет сделать следующее:

пользователь заполнил профильзаполнить форму и отправить (впервые они представили профиль как новый пользователь), после проверки данных и т. д. Сначала я проверяю, совпадает ли uid в таблице пользователей с uid в таблице users_profile, если есть совпадение, то запись UPDATE с новымзначения (это будет означать, что пользователь ранее заполнил там свой профиль, так как при регистрации у него его нет), но если совпадения не найдены в uid из обеих таблиц, я бы выполнил запрос INSERT, потому что для пользователя еще не существует профиля.Я полагаю, что очевидно, что я сохраню uid из таблицы users в сеансе с другими данными при успешном входе в систему, а uid в сеансе будет uid, который вставлен в таблицу users_profiles в столбце uid?Таким образом, создается связь между двумя таблицами, и если я сейчас решу удалить пользователя, его профиль также будет удален в.

Ответы [ 2 ]

2 голосов
/ 22 апреля 2011

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

При вставке вызывающий код должен записывать строки в две таблицы (сначала пользователи, а затем профили).

1 голос
/ 22 апреля 2011

Если я правильно следовал описанию, он работает как положено.Отношение внешнего ключа в основном говорит, что родительский объект должен существовать для данного дочернего элемента (пользователь должен существовать для данного user_profile в вашем примере).Это не требует обратного (для пользователя существует запись user_profile).Это никогда не приведет к выполнению INSERT на дочернем столе.Вы должны вставить запись в таблицу user_profile, и отношение внешнего ключа будет гарантировать ее сохранение.

Изменить для дополнительной информации OP: В общем, да, я считаю, чтовещь, которую вы хотите сделать.Я недостаточно разбирался в веб-разработке, чтобы понять, правильн ли этот конкретный процесс.Однако в любом случае (независимо от того, была ли создана запись профиля), вам нужно будет знать, какого пользователя нужно изменить.Мое мнение по этому поводу, однако, было бы создать соответствующую запись user_profile непосредственно после создания записи пользователя (просто оставьте в ней информационные поля пустыми).Таким образом, вы знаете, что он существует, когда вы его редактируете, и вам не нужно выполнять операцию в стиле MERGE.

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