大量的“If 语句”,还是冗余的 mysql 查询?

Posted

技术标签:

【中文标题】大量的“If 语句”,还是冗余的 mysql 查询?【英文标题】:Lots of 'If statement', or a redundant mysql query? 【发布时间】:2010-06-23 11:07:50 【问题描述】:

$url = mysql_real_escape_string($_POST['url']); $shoutcast_url = mysql_real_escape_string($_POST['shoutcast_url']); $site_name = mysql_real_escape_string($_POST['site_name']); $site_subtitle = mysql_real_escape_string($_POST['site_subtitle']); $email_suffix = mysql_real_escape_string($_POST['email_suffix']); $logo_name = mysql_real_escape_string($_POST['logo_name']); $twitter_username = mysql_real_escape_string($_POST['twitter_username']);

表格中的所有这些选项都是预先填写的(由数据库),但是用户可以选择更改它们,从而更新原始数据库。尽管有一些行可能没有更新,但对我来说更新所有列会更好,还是只对每个行执行 if ($original_db_entry = $possible_new_entry) (这本身就是一个查询)?

谢谢

【问题讨论】:

【参考方案1】:

我想说这两种方式都无关紧要 - 您发送到服务器的查询的大小在这里几乎不相关,并且对于将不公正地更新的列没有“最后更新”信息,所以。 ..

顺便说一句,在处理大量数据时,我喜欢做的是创建一个临时数组。

$fields = array("url", "shoutcast_url", "site_name", "site_subtitle" , ....); 

foreach ($fields as $field)
 $$field = mysql_real_escape_string($_POST[$field]);

这里唯一需要注意的是,您必须小心不要将变量名放入$fields,这会覆盖现有变量。

更新: Col. Shrapnel 提出了正确且有效的观点,即使用可变变量不是一个好习惯。虽然我认为在函数范围内使用变量变量是完全可以接受的,但确实最好不要使用它们。清理所有传入字段并使它们以可用形式出现的更好方法是:

$sanitized_data = array();
$fields = array("url", "shoutcast_url", "site_name", "site_subtitle" , ....); 

foreach ($fields as $field)
 $sanizited_data[$field] = mysql_real_escape_string($_POST[$field]);

这将为您留下一个可以使用的数组:

$sanitized_data["url"] = ....
$sanitized_data["shoutcast_url"] = ....

【讨论】:

@Sam $$field 设置 $url$shoutcast_url$site_name.... 无论当前循环正在运行的数组中的哪个字符串。代码与您的代码块一样设置变量,只是行数更少。 这里不需要真正的变量变量,因为我们不需要变量本身,而是SQL查询字符串。 @Col 这取决于他在插入数据之前对数据所做的其他事情。此外,它是一种减少特定代码块所需行数的技术的一般演示。我真的不明白这对你来说有什么价值。 变量变量总是值得你知道的。不要混合代码和数据。不要使用技巧解释器允许你【参考方案2】:

只需运行一个更新所有列的查询:

UPDATE table SET col1='a', col2='b', col3='c' WHERE id = '5'

【讨论】:

【参考方案3】:

我建议您使用所有列值执行 UPDATE。这比尝试确认该值与数据库中当前的值不同的成本更低。无论如何,这种确认是无关紧要的,因为如果其他人更新它们,数据库中的值可能会在您检查它们后立即更改。

如果您对 MySQL 发出 UPDATE 并且值与数据库中已有的值相同,则 UPDATE 将是空操作。也就是说,MySQL 报告零行受影响。 MySQL 知道在 UPDATE 期间不要做不必要的工作。

如果只有一列发生变化,MySQL 确实需要工作。它只会更改不同的列,但仍会创建新的行版本(假设您使用的是 InnoDB)。

当然,将 UPDATE 语句实际发送到 MySQL 服务器还需要做一些少量的工作,以便它可以与现有行进行比较。但在现代服务器上,这通常只需要百分之一毫秒。

【讨论】:

【参考方案4】:

是的,可以更新每个字段。 生成 SET 语句的简单函数:

function dbSet($fields) 
  $set='';
  foreach ($fields as $field) 
    if (isset($_POST[$field])) 
      $set.="`$field`='".mysql_real_escape_string($_POST[$field])."', ";
    
  
  return substr($set, 0, -2); 

及用法:

$fields = explode(" ","name surname lastname address zip fax phone");
$query  = "UPDATE $table SET ".dbSet($fields)." WHERE id=$id";

【讨论】:

这不适用于复选框。如果取消设置复选框,更改将丢失,字段不变。 @Pekka 是的,但是您仍然不需要复选框的变量变量 @Col 这与手头的问题有什么关系? @Pekka 你可以在调用这个函数之前做一些准备工作。从单独的部分组装日期值,填充复选框值等,然后使用它来组装查询。除了超全局变量之外,不需要任何变量 @Col 我在哪里可以做这些准备工作?写入$_POST?这是一个好主意吗?我不知道。该功能很好,但是如果您有复选框,则不适用,这就是我的意思。

以上是关于大量的“If 语句”,还是冗余的 mysql 查询?的主要内容,如果未能解决你的问题,请参考以下文章

问题整理MySQL大量数据去重处理

mysql-冗余和重复索引

在 MySQL SELECT 查询中使用 IF 语句

IF 语句中带有子查询的 MySQL SELECT 语句的语法

Javascript if语句双感叹号运算符冗余[重复]

如何在没有冗余计算的 if 语句中使用 std::valarray?