简体   繁体   中英

InnoDB foreign key difficulty?

Below I have two tables

users and users_profiles

Both are innoDB and collation: utf8_general_ci

They are as follows:

users

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;

After creating the tables in phpmyadmin I created a foreign key on the users_profiles table, code below is what phpMyAdmin created.

As follows:

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

basically the users_profiles.uid is a foreign key and references the users.uid

In phpMyAdmin I go to insert and fill in some sample data leaving the uid obviously to auto increment. When i have inserted a record in users table I goes into the users_profiles table and notice the users.uid is not inserted automatically in the users_profiles,

Is this normal?

Reason is when someone for example registers on a form, they will be asked for username, email and password, and i do a query in php to insert that data into users table, i thought that because i have a foreign key that it would also automatically insert a row in the users_profiles table with the uid from users table so there is a link between the user and there profile. But when i insert a record into users table the users.uid is not inserted into the users_profiles table.

I tried another example to see what would happen and this one works as i would expect due to the cascade on update and delete.

If i insert a row in users table and then manually insert the users.uid into users_profiles.uid (they are now linked) and add for example my first_name and last_name then in phpmyadmin delete the user from users table it deletes the row in the users_profiles table. This works like it should obviously as i don't want a user to be deleted and have there profile remain.

This has confused me as when I do create a form and a user signs up, they essentially would not have a profile because on signup no profile is created for them with there users.uid in the user_profiles table (no link between them) although I have a foreign key.

Can some explain why it's not working as I expect, maybe it should be working like I want it to but something is wrong or I am missing the whole point otherwise.


UPDATE

In reference to reply from @Mark Wilkins

I understand what you mean now. But something I am not 100% sure on is this:

User signs up, a record is created in users table; they login and visit profile page where the can fill it in and submit the form.

On processing the form am I right in thinking I would need to do the following:

user filled in profile form and submitted (first time they submitted profile as they are a new user), after validating data etc I first check to see if the uid in the users table match a uid in the users_profile table, if there's a match then UPDATE record with new values (this would mean the user has previously filled in there profile as on signup they don't have one) but if no match is found on uid from both tables then I would perform an INSERT query because no profile yet exists for the user. I take it that obviously I would store the uid from users table in session with other data on successful login and the uid in session would be the uid that is inserted into the users_profiles table in column uid? That way a link is created between two tables and if I now decide to delete the user there profile will also be deleted to.

Foreign key constraints are not designed to create rows. Their purpose is to ensure data integrity by forcing that a value in a child table that references a parent table value actually exists in that parent table and prevents a parent row from being deleted that has references to it in a child table.

On insert, the calling code must write rows into the two tables (first users then profiles).

If I followed the description correctly, it is working as expected. A foreign key relationship basically says that a parent must exist for a given child (a user must exist for a given user_profile in your example). It does not require the opposite (that a user_profile record exist for a user). It will never result in an INSERT being performed on the child table. You have to insert the record into the user_profile table and the foreign key relationship will guarantee that it is maintained.

Edit for the additional OP info: In general, yes I believe that is the thing you want to do. I have not dealt enough with web development to know if that particular process is correct. In either case, though (whether or not a profile record has been created), you will need to know which user to modify. My opinion about this, however, would be to create the associated user_profile record directly after creating the user record (just leave the informational fields empty in it). That way you know it exists when the go to edit it and you don't have to perform a MERGE style operation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM