故障保护mysql查询插入,验证其他表中的值

故障保护mysql查询插入,验证其他表中的值,mysql,sql-insert,Mysql,Sql Insert,我有两个表:dbvoces.voces和dbsystem.topics 现在我想确定,如果有人投票支持某个主题。查询“检查”主题是否存在。我有以下几点(多亏了一些相关的话题) 此代码有效,但这是正确的方法吗? INSERT INTO dbvotes.votes (topicid,vote,voterid) VALUES( (SELECT topicid FROM dbsystem.topics WHERE topicid = 20), (12), (1) ) 它在不同的database

我有两个表:
dbvoces.voces
dbsystem.topics
现在我想确定,如果有人投票支持某个主题。查询“检查”主题是否存在。我有以下几点(多亏了一些相关的话题)

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

INSERT INTO dbvotes.votes (topicid,vote,voterid) VALUES(
(SELECT topicid 
 FROM dbsystem.topics 
 WHERE topicid = 20),
(12),
(1)
)
它在不同的database.table上使用select的部分是我的故障保护(因为当topicid不存在时,它返回Null/mysqlerror)。使用的值由用户提交


这是在insert子句的“values”部分嵌套sql查询的正确方法吗?

否。不应试图通过代码确保数据完整性,而应定义外键约束来完成这项工作。在您的情况下,
dbvoces.voces
将引用
dbsystem.topics
,这意味着,当没有相应的主题时,您无法插入到投票中。顺便说一句,这些名字表明它们在不同的数据库中。你有什么特别的原因吗?这有点“不寻常”,我不推荐

无论如何,您的表定义如下所示:

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;
INSERT INTO votes(topicid,vote,voterid)
VALUES (20, 12, 1);
您还可以添加以下选项:

...
FOREIGN KEY (fk_topicid_topics) REFERENCES topics(id) ON DELETE CASCADE
) ENGINE=InnoDB;
这意味着,当相应的主题被删除时,投票被删除

要实现这一点,您必须使用支持外键的引擎,这意味着不是MyISAM,但很可能是InnoDB。
你必须在被引用的列上有一个索引

最后,您的insert语句如下所示:

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;
INSERT INTO votes(topicid,vote,voterid)
VALUES (20, 12, 1);

不可以。您不应该试图通过代码来确保数据完整性,而应该定义外键约束来完成这项工作。在您的情况下,
dbvoces.voces
将引用
dbsystem.topics
,这意味着,当没有相应的主题时,您无法插入到投票中。顺便说一句,这些名字表明它们在不同的数据库中。你有什么特别的原因吗?这有点“不寻常”,我不推荐

无论如何,您的表定义如下所示:

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;
INSERT INTO votes(topicid,vote,voterid)
VALUES (20, 12, 1);
您还可以添加以下选项:

...
FOREIGN KEY (fk_topicid_topics) REFERENCES topics(id) ON DELETE CASCADE
) ENGINE=InnoDB;
这意味着,当相应的主题被删除时,投票被删除

要实现这一点,您必须使用支持外键的引擎,这意味着不是MyISAM,但很可能是InnoDB。
你必须在被引用的列上有一个索引

最后,您的insert语句如下所示:

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;
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;
如果表
dbsystem.topics
中存在
topicid
等于
20
topic
,则插入值将为
(20,12,1)
。否则,将无法插入。

您可以使用以下选项:

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

如果表
dbsystem.topics
中存在
topicid
等于
20
topic
,则插入值将为
(20,12,1)
。否则,将无法插入。

哇,太棒了!!非常感谢你。当一个用户被删除时,我可以做级联吗?或者这需要魔法吗?我确实使用了两个数据库。原因是我正在尝试创建某种投票功能,而不必将原始系统的数据库弄乱。因此,用户只能从系统数据库中选择值。外键还能用吗?我想是的。对于“用户已删除”的内容,只需为users表创建另一个外键。另外,提示一下,您还可以授予对单个表的只读访问权,即使是对列。不需要将它保存在两个数据库中,但无论如何它都应该工作。非常感谢您的提醒,这似乎是最好的解决方案!干杯哇,太棒了!!非常感谢你。当一个用户被删除时,我可以做级联吗?或者这需要魔法吗?我确实使用了两个数据库。原因是我正在尝试创建某种投票功能,而不必将原始系统的数据库弄乱。因此,用户只能从系统数据库中选择值。外键还能用吗?我想是的。对于“用户已删除”的内容,只需为users表创建另一个外键。另外,提示一下,您还可以授予对单个表的只读访问权,即使是对列。不需要将它保存在两个数据库中,但无论如何它都应该工作。非常感谢您的提醒,这似乎是最好的解决方案!干杯