mysql一次更新多条记录

使用case when then(具体语法参考:mysql when case 语法 | 52的小窝 (52dixiaowo.com)

case <where字段> when <where字段值> then <更新字段新值>

比如:

UPDATE mytable 
    SET myfield = CASE id 
        WHEN 1 THEN 'value'
        WHEN 2 THEN 'value'
        WHEN 3 THEN 'value'
    END
WHERE id IN (1,2,3)

一次更新多个值,稍作修改:

UPDATE categories 
    SET display_order = CASE id 
        WHEN 1 THEN 3 
        WHEN 2 THEN 4 
        WHEN 3 THEN 5 
    END, 
    title = CASE id 
        WHEN 1 THEN 'New Title 1'
        WHEN 2 THEN 'New Title 2'
        WHEN 3 THEN 'New Title 3'
    END
WHERE id IN (1,2,3)

php include_once几种实现方式

include_once是php自带的一个方法

通过改造 include 方法,也可以实现。

方法一:include and define

包含一个文件后,定义一个常量标识(可以使用绝对路径)

if(!defined(XXX)){
   include xxx.php;
   define(XXX,path);
}

方法二:include and regist

包含一个文件后,在一个注册变量中添加(比如定义一个数组,作为包含列表,包含时,则在该数组中添加一个键(比如绝对路径),如果该键存在则说明已经包含)

和上面的实现几乎一致,只是上面是常量,这里是变量(比如数组)。

PHP 自动加载类 __autoload() 方法

一个类中有多个方法。

多个方法中,可能用到多个外部class。

如果在每个方法中引入,则需要手写很多次引入,如果在构造方法中引入则有可能造成浪费(比如a方法只需要类c,b方法只需要类d,如果把c和d同时引入则有些浪费)

但是有了 __autoload() 方法,以后就不必为此大伤脑筋了,这个类会在你实例化对象之前自动加载制定的文件。

首次调用某个类时,如果发现不存在,则会自动引入(类名作为参数),并且只会引入一次。

/** 

 * 文件autoload_demo.php 

 */

function  __autoload($className) {  

    $filePath = “project/class/{$className}.php”;  

    if (is_readable($filePath)) {  

        require($filePath);  

    }  

}  

    

if (条件A) {  

    $a = new A();  

    $b = new B();  

    $c = new C();  

    // … 业务逻辑  

} else if (条件B) {  

    $a = newA();  

    $b = new B();  

    // … 业务逻辑  

}

多字段应该在一个表还是多个表?

如果考虑扩展性,应该尽可能按范式,设计在多个表中。

如果需求改动较小,或几乎不改动,则只要能实现需求,都无所谓。

多表查询通常是会更麻烦一些。一个复杂的对象查询,可能要连接近10张表。

数据字段,mysql是无限制的,多字段冗余存储不会有问题,mysql 最大支持61个表连接,通常也不会超过这个数量。

对于完成工作,通常不用考虑太多,一般人在工作中都考虑冗余存储,因为字段存在多个表则要写的代码通常会多。

在学习,或设计时,合理的划分就像是代码的去重(分离到多个表后,就可以实现共用,从而可以轻松满足复杂的设计),对个人能力有很大的提升,只有不断的思考与设计,才能不断提高自己的水平,如果能冗余则冗余,个人的进步空间很小,限制了思维。

php字符串转int数组

$string = “1,2,3”
$ids = explode(‘,’, $string);
var_dump($ids);

结果:

array(3) {
  [0]=>
  string(1) "1"
  [1]=>
  string(1) "2"
  [2]=>
  string(1) "3"
}

默认得到的是 string 类型,除了循环外,可以使用:

$integerIDs = array_map('intval', explode(',', $string));

也可以使用 json 方法:

$integerIDs = json_decode('[' . $string . ']', true);

对于一个数组,如果可能是多维,则:

public function arrayValuesToInt(&$array){
  if(is_array($array)){
    foreach($array as &$arrayPiece){
      arrayValuesToInt($arrayPiece);
    }
  }else{
    $array = intval($array);
  }
}

然后,就这样做:

arrayValuesToInt($multiDimentionalArray);

这将生成如下数组:

[["1","2"]["3","4"]]

看起来像这样:

[[1,2][3,4]

(这适用于任何深度)

后端接口返回统一的数据格式

前后端分离时,要尽量保证后端返回的数据格式是一致的。

数据格式不一致的情况,比如:如果存在子元素,则返回children列表

{
code : 200,
title : xxx,
children : [
    {a},
    {b}
  ]
}

那么在不存在 children 时,将只返回:

{
code : 200,
title : xxx
}

此时,前端需要判断,是否存在 children 子元素,然后再判断它的值。(虽然js可以直接判空,但 children 中的每一项,也可能复杂结构元素,或直接在 vue 中绑定了)

如果数据不存在时,返回空数组,或许会更好处理,另外看 起来也更规范。

{
code : 200,
title : xxx,
children : []
}

接口的多状态。

比如返回一个page对象时,当数据为空,此时应该返回一个状态码,而不仅仅是空数组

{
  pageInfo:{...},
  list:[]
}

如果仅仅返回空数组,则需要判断 list 长度 或 pageInfo 里的数据,没有数据是一种特殊情况,可以给一个特殊状态码

{
  pageInfo:{...},
  list:[],
  state : 2001
}

sql字符串转义防注入

在使用未预编译的sql时,如果不进行转义,则容易出现sql注入

例如:

$sql = "select * from user where username='$username' and password='$password'";

此时,如果账户名是一个字符串:zhangsan’#

select * from user where username='zhangsan'#' and password='$password

由于在mysql中,#表示注释,则真实sql:

select * from user where username='zhangsan'

此时就跳过密码,登录到系统中了。如果zhangsan是管理员,若后台有数据库连接,执行、导出等功能,最终整个数据库都直接被盗取。

一个严重的问题,就是sql参数赋值时,可以使用 ‘ ,从而抵消了前面 的 ‘ ,于是传递的值可以造成sql侵入。

可以使用  get_magic_quotes_gpc() 检测一个字符串是否已经转义,如果未转义,则使用 addslashes() 函数进行转义。

php中的GET、POST、COOKIE自动转义:

PHP中,有一个魔术引号的概念,如何打开?答:在PHP.ini中,magic_quotes_gpc=On;重启apache即可

魔术引号被打开后,系统会自动对$_GET,$_POST,$_COOKIE数据进行转义,在不知情的情况下,再次进行手动转义的话,就转多了,要想合理的进行转义,就要首先判断,魔术符号是否已经打开了,用magic_quotes_gpc()进行判断,不需要传值,关闭返回0,关闭返回1

mysql之replace into导致的id自增问题

replace into是mysql特有的语法。

如果数据存在(id重复或其他唯一约束冲突),则会执行更新操作。

但是很显然,这个更新,实际是先删除,再更新,从而导致更新后的数据id不一致。

在主从数据库时,则更容易产生bug,因为在binlog中,记录的是update,导致从库数据的id不变,而主库的id实际已经改变。

insert into … on duplication key update 语法:

insert into…on duplicate key update…

需要注意的是,如果有多个 duplication key,则不可使用。因为只要有一个 duplication key 就会触发。

另外,它默认也会导致 id 自增(和前面的有些不同,它只是单纯的浪费id自增值,容易导致超过最大自增)

简单点来看,不使用特有语法:

  • 先 select 出记录id,如果存在 id,则说明记录存在,此时直接根据 id 进行 update,否则直接 insert。
  • 直接 insert ignore into … ,如果不成功,则 update。
  • 直接 update (使用了 where 的情况),如果update不成功,则 insert 。

在插入频繁时,使用 insert ignore into性能更好。

在修改频繁时,直接 update 性能更好。

如果是 select ,然后判断并选择 insert 或 update,性能最低,最简单(在一些特殊情况下,就非选不可了,当你必须select相关信息时)。