我的数据库用户中有3个表,问题和答案。我希望询问表与用户进行交互,并对用户和询问表进行答复表和回答表。到目前为止,我已经使用外键与用户表相关联,答案表与问题表相关联。当我试图在mysql的应答表中添加第二个外键时,我得到一个错误( a)重复的外键约束名'userid‘,即使我试图添加使用query,它仍然给了我一个错误。
我可以用外键帮助用户表在问询表中添加值吗?例如,我在user表中有用户in 1,我想在问题表中添加值,其中quesid为1,并且userid也为1。
INSERT INTO users_ques
SELECT "What is JAVA","Please Share the details" FROM users WHERE quesid = 1;
下面是我的表和它们的脚本
用户表
CREATE TABLE `users` (
`userid` int NOT NULL AUTO_INCREMENT,
`username` varchar(45) NOT NULL,
`password` varchar(45) NOT NULL,
`firstname` varchar(45) NOT NULL,
`lastname` varchar(45) DEFAULT NULL,
`email` varchar(45) DEFAULT NULL,
`address` varchar(45) DEFAULT NULL,
`phone` int DEFAULT NULL,
PRIMARY KEY (`userid`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
试题表
CREATE TABLE `users_ques` (
`quesid` int NOT NULL AUTO_INCREMENT,
`ques` varchar(50) NOT NULL,
`ques_desc` varchar(150) NOT NULL,
PRIMARY KEY (`quesid`),
CONSTRAINT `userid` FOREIGN KEY (`quesid`) REFERENCES `users` (`userid`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
回答表
CREATE TABLE `users_ans` (
`ansid` int NOT NULL AUTO_INCREMENT,
`ans` varchar(200) NOT NULL,
PRIMARY KEY (`ansid`),
CONSTRAINT `quesid` FOREIGN KEY (`ansid`) REFERENCES `users_ques` (`quesid`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
发布于 2022-01-16 19:08:59
建议的结构(用作基准,根据实际数据调整):
CREATE TABLE user (
user_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, -- unique index
username VARCHAR(255) NOT NULL,
password VARBINARY(255) NOT NULL, -- password hash, binary
firstname VARCHAR(255) NOT NULL,
lastname VARCHAR(255) DEFAULT NULL,
email VARCHAR(255) DEFAULT NULL,
address VARCHAR(255) DEFAULT NULL,
phone BIGINT DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
CREATE TABLE question (
question_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, -- unique index
question_text TEXT NOT NULL,
user_id INT NOT NULL, -- id of the user who have asked
CONSTRAINT user_to_question FOREIGN KEY (user_id) REFERENCES user (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
CREATE TABLE answer (
answer_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, -- unique index
answer_text TEXT NOT NULL,
question_id INT NOT NULL, -- what question it answers on
user_id INT NOT NULL, -- id of the user who have answered
CONSTRAINT user_to_answer FOREIGN KEY (user_id) REFERENCES user (user_id),
CONSTRAINT question_to_answer FOREIGN KEY (question_id) REFERENCES question (question_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
在这个方案中,我没有显示用户不能回答自己问题的限制。我认为这样的限制是没有意义的。但是,如果需要,那么可以通过在answer
表上创建2个触发器(插入之前和更新之前)来添加它。
发布于 2022-01-16 14:38:52
您所得到的错误与它所说的完全一样,您正试图使用符号userid
添加另一个约束,但在users_ques
表中已经有一个具有该名称的约束。
如果定义了约束符号值,则必须在数据库中是唯一的。重复的符号会导致类似于: error 1005 (HY000):无法创建表'test.fk1‘的错误(errno: 121)。
因此,要么需要为约束分配数据库唯一名称,要么允许服务器为您分配一个。如果您想要显式地命名它们,请使用不太可能发生冲突的表现性名称。有点像FK_<table_name>_<column_name>
。
另外,可能是复制和粘贴错误,但您的users_ans
看起来完全错误。ansid
似乎是典型的代理键,但随后用作约束中的users_ques
.quesid
的外键。看起来你错过了userid
和quesid
。users_ques
上的约束和列也存在类似的问题
/* Allowing the server to create the indices and auto-name the constraints */
CREATE TABLE `users_ans` (
`ansid` int UNSIGNED NOT NULL AUTO_INCREMENT,
`quesid` int UNSIGNED NOT NULL,
`userid` int UNSIGNED NOT NULL,
`ans` varchar(200) NOT NULL,
PRIMARY KEY (`ansid`),
FOREIGN KEY (`quesid`)
REFERENCES `users_ques` (`quesid`),
FOREIGN KEY (`userid`)
REFERENCES `users` (`userid`)
) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/* Explicitly naming indices and constraints */
CREATE TABLE `users_ans` (
`ansid` int UNSIGNED NOT NULL AUTO_INCREMENT,
`quesid` int UNSIGNED NOT NULL,
`userid` int UNSIGNED NOT NULL,
`ans` varchar(200) NOT NULL,
PRIMARY KEY (`ansid`),
INDEX `idx_users_ans_quesid` (quesid),
INDEX `idx_users_ans_userid` (userid),
CONSTRAINT `FK_users_ans_quesid`
FOREIGN KEY `idx_users_ans_quesid` (`quesid`)
REFERENCES `users_ques` (`quesid`),
CONSTRAINT `FK_users_ans_userid`
FOREIGN KEY `idx_users_ans_userid` (`userid`)
REFERENCES `users` (`userid`)
) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
如果用户每个问题只能有一个答案,那么您可以删除当前的代理键,转而使用自然密钥(quesid,userid) -
/* This option only applies if a user can only answer a question once */
CREATE TABLE `users_ans` (
`quesid` int UNSIGNED NOT NULL,
`userid` int UNSIGNED NOT NULL,
`ans` varchar(200) NOT NULL,
PRIMARY KEY (`quesid`, `userid`),
INDEX `idx_inv_primary` (`userid`, `quesid`), -- probably needed for joins in both directions and will be used by `FK_users_ans_userid`
CONSTRAINT `FK_users_ans_quesid`
FOREIGN KEY (`quesid`)
REFERENCES `users_ques` (`quesid`)
ON DELETE RESTRICT
ON UPDATE RESTRICT,
CONSTRAINT `FK_users_ans_userid`
FOREIGN KEY (`userid`)
REFERENCES `users` (`userid`)
ON DELETE RESTRICT
ON UPDATE RESTRICT
) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
正如在最后一个例子中所显示的,我更喜欢包含引用操作,即使在使用默认值时也是如此,因为它清楚地表明了意图。
这里有一个小db<>fiddle
你的试题表的名字似乎不恰当。根据上面的create语句的标题,questions
似乎是表的明显名称。
我不明白您的第二个问题,也不明白您为什么要将userid
添加到“试题表”中。如果您想要更多的帮助,请添加更多的细节到您的问题,以澄清问题。
https://stackoverflow.com/questions/70724956
复制相似问题