故障安全 mysql 查询插入与其他 table 中的验证值

failsafe mysql query insert with verifying value in other table

我有 2 个表:dbvotes.votesdbsystem.topics 现在我想确定是否有人为某个主题投票。查询 "checks" 如果主题存在。我有以下内容(感谢关于 SO 的一些主题)。

此代码有效,但方法正确吗?

INSERT INTO dbvotes.votes (topicid,vote,voterid) VALUES(
(SELECT topicid 
 FROM dbsystem.topics 
 WHERE topicid = 20),
(12),
(1)
)

它在不同的 database.table 上使用 select 的部分是我的故障保险(因为它 returns Null/mysqlerror 当 topicid 不存在时)。使用的值是用户提交的。

这是在插入子句的 "values" 部分嵌套 sql 查询的正确方法吗?

没有。与其尝试通过代码确保数据完整性,不如定义外键约束来完成这项工作。在您的情况下,dbvotes.votes 将引用 dbsystem.topics,这意味着,当没有相应的主题时,您不能插入投票。顺便说一句,顾名思义,它们位于不同的数据库中。你这样做有什么特别的原因吗?有点像 "unusual",我不推荐它。

无论如何,您的 table 定义应该是这样的:

CREATE TABLE votes(
id int auto_increment,
topicid int,
vote tinyint,
voterid int,
PRIMARY KEY (id),
FOREIGN KEY (fk_topicid_topics) REFERENCES topics(id)
) ENGINE=InnoDB;

您还可以添加

等选项
...
FOREIGN KEY (fk_topicid_topics) REFERENCES topics(id) ON DELETE CASCADE
) ENGINE=InnoDB;

也就是说,删除相应的主题时,投票也会被删除。

为此,您必须使用支持外键的引擎,这意味着不是 MyISAM,但很可能是 InnoDB。
而且你必须在引用的列上有一个索引。

最后您的插入语句如下所示:

INSERT INTO votes(topicid,vote,voterid)
VALUES (20, 12, 1);

你可以使用这个:

INSERT INTO dbvotes.votes (topicid,vote,voterid) 
SELECT (20, 12, 1)
FROM  dbsystem.topics
WHERE topicid = 20;

如果 topictopicid 等于 20 存在于 table dbsystem.topics 中,INSERT 将以值 (20, 12, 1).否则就没有INSERT。