首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用父表的引用在子表中添加两个外键和值

如何使用父表的引用在子表中添加两个外键和值
EN

Stack Overflow用户
提问于 2022-01-15 19:58:48
回答 2查看 289关注 0票数 0

我的数据库用户中有3个表,问题和答案。我希望询问表与用户进行交互,并对用户和询问表进行答复表和回答表。到目前为止,我已经使用外键与用户表相关联,答案表与问题表相关联。当我试图在mysql的应答表中添加第二个外键时,我得到一个错误( a)重复的外键约束名'userid‘,即使我试图添加使用query,它仍然给了我一个错误。

我可以用外键帮助用户表在问询表中添加值吗?例如,我在user表中有用户in 1,我想在问题表中添加值,其中quesid为1,并且userid也为1。

代码语言:javascript
运行
复制
INSERT INTO users_ques 
    SELECT "What is JAVA","Please Share the details" FROM users WHERE quesid = 1;

下面是我的表和它们的脚本

用户表

代码语言:javascript
运行
复制
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

试题表

代码语言:javascript
运行
复制
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

回答表

代码语言:javascript
运行
复制
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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-01-16 19:08:59

建议的结构(用作基准,根据实际数据调整):

代码语言:javascript
运行
复制
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;
代码语言:javascript
运行
复制
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;
代码语言:javascript
运行
复制
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个触发器(插入之前和更新之前)来添加它。

票数 2
EN

Stack Overflow用户

发布于 2022-01-16 14:38:52

您所得到的错误与它所说的完全一样,您正试图使用符号userid添加另一个约束,但在users_ques表中已经有一个具有该名称的约束。

根据13.1.20.5外键约束

如果定义了约束符号值,则必须在数据库中是唯一的。重复的符号会导致类似于: error 1005 (HY000):无法创建表'test.fk1‘的错误(errno: 121)。

因此,要么需要为约束分配数据库唯一名称,要么允许服务器为您分配一个。如果您想要显式地命名它们,请使用不太可能发生冲突的表现性名称。有点像FK_<table_name>_<column_name>

另外,可能是复制和粘贴错误,但您的users_ans看起来完全错误。ansid似乎是典型的代理键,但随后用作约束中的users_ques.quesid的外键。看起来你错过了useridquesidusers_ques上的约束和列也存在类似的问题

代码语言:javascript
运行
复制
/* 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) -

代码语言:javascript
运行
复制
/* 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添加到“试题表”中。如果您想要更多的帮助,请添加更多的细节到您的问题,以澄清问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70724956

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档