我有food_table
和person_table
。然后我有第三个表格fav_food_table
,使用food_id
和person_id
存储食物与人之间的关系。
当此人转到帐户信息并更新他喜欢的食物时,输入数据将作为选定food_id
的数组传递给PHP(HTTP)脚本。一个人可以拥有多个fav_food,这种关系是一对多的。
更新fav_food_table
的天真方法是从fav_food_table
删除属于person_id
的所有内容,然后重新插入所有行。因此,使用2个语句。
是否有一个声明可以做同样的事情?
PSUEDO代码:
CREATE TABLE food_table (food_id, food_name);
CREATE TABLE person_table (person_id, person_name);
CREATE TABLE fav_food (person_id, food_id);
答案 0 :(得分:0)
person_table
和food_table
之间存在m:n关系。这意味着您的关系表中有多个与同一个人相关的记录。当一个人更新他们喜欢的食物时,可能会出现四种独立病例的任意组合:
DELETE FROM fav_food_table
)INSERT INTO fav_food_table
)要正确保持数据库的最新状态,您必须处理所有四种情况。案例2和4很容易被覆盖。只是不做任何事情:))
这意味着,您必须至少执行两个步骤才能使数据库保持最新:1和3。
您的目标似乎是减少必须执行的sql语句的数量。
从表中删除一个人的所有收藏夹总是可以用一个语句来完成:
DELETE
FROM fav_food_table
WHERE person_id = ?;
要删除一个人的所选收藏夹,只需在AND food_id IN (?,?,?)
子句中添加WHERE
。
也可以使用single statement:
插入表格INSERT INTO fav_food_table (person_id,food_id)
VALUES (?,?),
(?,?),
(?,?),
.....;
截至目前的摘要: 无论我们是否删除此人的所有旧记录然后插入所有新记录,或者我们是否只删除所选记录并插入新记录:我们可以用两个陈述来做到这一点!
然而,在第二种情况下(" smart" case),我们不仅要知道关系的新状态,还要知道计算两者之间差异的旧状态。这将导致另外一个SELECT
语句或需要一些智能"客户端" (PHP)逻辑。
你的两步过程似乎并不天真,但对我来说简单有效。没有办法将此过程减少到少于两个语句。
如果您想减少必须有效地将命令从PHP发送到服务器的次数,您可以查看mysqli_multi_query()或创建一个包含{{1}的存储过程}和DELETE
语句。但最重要的是,这与执行两个查询本身是一回事。
您还可以查看MySQL Transactions以实现更安全的过程,并在以后发生错误时能够回滚INSERT
命令。
答案 1 :(得分:-1)
我可以提出一些与众不同的建议。而不是删除,更新?
应该考虑删除共同的数据。无法检索删除数据。所以看看这个。
我们正在调整您的代码。
CREATE TABLE food_table (food_id, food_name);
CREATE TABLE person_table (person_id, person_name);
CREATE TABLE fav_food (person_id, food_id, fav_food_active);
/* see the last column i added. It should be a bit type and can only hold the values 0 and 1. */
现在技术上每次都可以更新。无需删除值。这句话是
/* deletion */
UPDATE Fav_Food
SET fav_food_active = 0
WHERE food_id = (your food_id)
AND person_id = (your person_id)
/* activating it again */
UPDATE Fav_Food
SET fav_food_active = 1
WHERE food_id = (your food_id)
AND person_id = (your person_id)
所以现在你在这两个之间切换用于激活和删除它,而没有删除硬数据的后果。总之,你可以在你的代码中这样称呼它
SELECT *
FROM fav_food
WHERE (here your where clause on which you wanna search for)
AND fav_food_active = 1
请记住,当您在数据库中输入内容时,应始终将其添加为1.您可以将PHP myadmin中的内容添加为自动值,或在INSERT
语句中对其进行硬编码。
我不确定你的后端代码是什么(好吧拿回来,它的PHP,我看了你的帖子)看着你通过数组拍摄所有内容的问题,但尝试使用foreach
的一些检查fav_food条目,如果查询有问题,请先在数据库中检查。如果是,请更新它,如果没有,请插入它。让它在一个循环中运行。
类似
foreach ($food_id as $value){
// check here the overal statement if it excists in your db
// give back count
if ($count == 1){
// update query to delete it.
}else{
// create your insert query here
}
}
希望这会有所帮助。快乐的编码!