繁体   English   中英

InnoDB外键难点?

[英]InnoDB foreign key difficulty?

下面我有两个表

用户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_profiles表中插入带有来自users表的uid的行,以便在用户和个人资料之间存在链接。 但是当我在用户表中插入一条记录时,users.uid并没有插入到users_profiles表中。

我尝试了另一个示例以查看会发生什么,并且由于更新和删除的级联,该示例可以按我的预期工作。

如果我在用户表中插入一行,然后手动将users.uid插入users_profiles.uid(它们现在已链接)并添加例如first_name和last_name,然后在phpmyadmin中从users表中删除用户,则会删除users_profiles中的行表。 这显然应该工作,因为我不希望删除用户并保留个人资料。

这让我感到困惑,因为当我创建表单并进行用户注册时,他们基本上没有配置文件,因为在注册时没有为用户创建任何配置文件,user_profiles表中没有user.uid(他们之间没有链接),尽管我有一个外键。

有人可以解释为什么它没有按我预期的那样工作,也许它应该像我想要的那样工作,但是出了点问题,否则我会遗漏整个要点。


UPDATE

引用@Mark Wilkins的回复

我明白你的意思了。 但是我不确定100%是这样的:

用户注册,在用户表中创建一条记录; 他们登录并访问个人资料页面,可以在其中填写并提交表格。

在处理表格时,我认为我将需要执行以下操作:

用户填写个人资料表格并提交(他们是新用户时首次提交个人资料),在验证数据等之后,我首先检查users表中的uid是否与users_profile表中的uid匹配,如果存在匹配项,则具有新值的UPDATE记录(这意味着用户以前已经在那里填写了配置文件,因为他们没有注册),但是如果在两个表的uid上都找不到匹配项,那么我将执行INSERT查询,因为尚无配置文件为用户。 我认为显然我会在成功登录后将用户表中的uid与其他数据存储在一起,并且成功登录时的uid将是插入到列uid的users_profiles表中的uid? 这样,将在两个表之间创建链接,如果我现在决定删除该用户,那里的配置文件也将被删除。

外键约束不是设计用来创建行的。 它们的目的是通过强制在子表中引用父表值的值实际上存在于该父表中,并防止删除在子表中具有对其引用的父行来确保数据完整性。

插入时,调用代码必须将行写入两个表(首先是用户,然后是配置文件)。

如果我正确地遵循了说明,则它可以按预期运行。 外键关系从根本上说,给定的孩子必须有一个父母(在您的示例中,给定的user_profile必须有一个用户)。 不需要相反的操作(用户存在user_profile记录)。 它永远不会导致在子表上执行INSERT。 您必须将记录插入到user_profile表中,并且外键关系将保证对其进行维护。

编辑其他OP信息:通常,是的,我相信这是您想要做的事情。 我对Web开发的处理还不够,无法知道该特定过程是否正确。 但是,无论哪种情况(无论是否创建了个人档案记录),您都需要知道要修改哪个用户。 但是,我对此的看法是在创建用户记录后立即创建关联的user_profile记录(只需在其中保留信息字段为空)。 这样一来,您便可以知道在编辑时它的存在,而不必执行MERGE样式的操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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