不论一个网站还是一个APP,优化很大的地方还是数据库,要想加快数据库查询的速度,有很多种方式。
添加索引
索引是一种单独的、物理的数对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容。但是索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。使用语法如下:
ALTER TABLE <表名> ADD INDEX (<字段>);
使用where等条件语句
一个表要是数据量足够大的情况下,全表扫描必定降低查询速度,应考虑在 where 及 order by 涉及的列上建立索引敏感信息的查询
在进行敏感信息查询之前,我们先介绍下加密的方式及类型,现在的加密方式分位两种,一种是可逆的,一种的不可逆的,如Rsa 和 Des就是可逆的,而MD5和Sha256等等就是不可逆的,可逆和不可逆的区别就是加密完成后还能不能解出来,虽然现在Md5很多md5在线解密之类的,但是那些都是暴力破解,他们的数据库有很庞大的数据,但是要是md5稍微做些操作,如加盐md5和加盐hash等等,他们的破解就没这么容易了。
回到主题:不可逆的加密一般都应用于密码上,而那些查询会相对比较简单,如我们查询一个用户登录密码是否正确,首先是根据用户名查询对应的记录,然后对用户上传的密码进行对比,此处是加盐md5。
`md5(md5(password) + salt) == mysql_password`
这样就能轻易的做出查询了,速度也在0.01s之内就能完成!
而可逆的加密算法是应用于那些加密之后,自己还能够解出来的,如银行卡,身份证等等敏感信息,这些信息保存数据库,我们一般会采用Rsa来加密,那这时候我们要对这些银行卡,身份证信息作查询得怎么办呢?因为mysql中没有内置的rsa加密函数,如何是好呢?
我们可对这些数据再加一个字段,做加盐hash或者是加盐md5
对应的查询语句就会变成如下(此处列举加盐hash),加盐hash的算法是
hash('sha256',hash('sha256','加密字符串').'salt')
此处的salt是一段随机字符串
$bank = hash('sha256', "6221558812340000");//hash sha256加密
//数据库查询
SELECT * FROM 表名 WHERE BANK_SHA256 = SHA2(CONCAT('$bank' , 'salt'));
其中的BANK_SHA256代表的就是数据库种加盐hash过后的字段,’salt’代表的就是加盐hash的那个盐,存在列表种的一个随机字符串,而CONCAT是mysql数据库中链接两个字符串的内置函数。
这种查询虽然能一句就查询出来,但是带来的问题也是很大,首先我们看数据库语句就知道,数据库在做查询的时候要对每一条数据进行CONCAT,对hash后的字符串和对应列表中的salt做拼串,然后再做一层hash,一条数据要做这样的操作,那假如是一千条,一万条,一百万条数据呢,这速度可能我们都以为数据库卡死了,那这时候我们又该如何是好? 这次的敏感信息我们先已银行卡来做分析!
首先我们来10条数据(数据纯模拟):
建行:6221 5588 1234 0000 建行 :6221 5588 1234 0001
建行:6221 5588 1234 0002 招行:6223 5864 4561 2321
招行:6223 5864 4561 2334 招行:6223 5864 4561 2325
中信:6220 1589 7412 2001 中信:6220 1589 7412 2202
中信:6220 1589 7412 2303 中信:6220 1589 7412 2404
看到这些数据的时候,有没有什么想法,有咩有什么特点?
直观的我们都会看到他们分为了一组一组,建行和招行和中信,那我们做查询的时候是不是也可以先对他们进行分组,然后做查询呢,假如我是100万条数据,我里面有50家银行,那我先分组再查询,是不是速度会比之前快将近50倍?或者是更多?那如何做分组呢,那我们就得找出他们的特点,然后对他们进行分组!
聪明的小伙伴都知道,每家发卡行的开头都是不一样的,如上面数据建行是以6221 5588,而招行是以6223 5864开头,而中信是以6220 1589开头,特点被我们找到了,那我们如何利用呢,很简单!我们就把这些特点给存起来,当成是一个分组标识。
类似我们要存- -建行:6221 5588 1234 0000 时,我们取出其前八位 6221 5588做hash加密,存到数据库中的一个字段中,像招行:6223 5864 4561 2321,我们取6223 5864做hash加密存到数据库中,依次类推,这样就把我们的10条数据分了三组。
有人说,这不是敏感信息吗,别担心,我们可没泄露这些敏感信息,我们只是取了其中一部分,这部分就算泄露了也无伤大雅。
那我们查询的时候就怎么利用这个分组标识来做查询呢?很简单,如下:
$bank = hash('sha256', "6221558812340000");//hash sha256加密
$bankSpec = hash('sha256', "62215588"); //分组标识
//做数据库查询
SELECT * FROM 表名 WHERE BANK_SHA256 = SHA2(CONCAT('$bank' , 'salt')) AND bank_spec = bankSpec;
此处的bank_spec代表的是存入数据中的分组标识!
按照如上方法所示,果不其然,速度提升了非常多,几乎是有几十倍的上涨!
以上简单讲速了一种敏感信息的查询方式,其他类型的敏感信息类似,这里只是提供一种思路,希望能给大家带来帮助!有什么不对的地方,欢迎大家指正!