前言:
现在小伙伴们对“字符串模糊查询”大约比较重视,兄弟们都需要剖析一些“字符串模糊查询”的相关内容。那么小编也在网上搜集了一些关于“字符串模糊查询””的相关内容,希望小伙伴们能喜欢,朋友们一起来学习一下吧!上篇文章中我们提到了对于数据中的特殊字段进行加密的处理,但是我们也知道,加密后的数据对于模糊查询其实是非常不友好的,那么下面我们就来讨论一下,如何对加密之后的数据进行模糊查询。
为什么要加密?
加密一般都是为了解决数据安全问题,在开发过程中我们经常会遇到需要对数据进行加密存储的操作,例如对于密码加密、对于手机号加密、对于电话号码、身份证号等内容的加密。而对于这些数据的加密存储,要求是不一样的。
一般而言对于密码的加密,通常会采用一些不可逆的算法。也就是说密码只能从明文转换成密文,而无法从密文转换成明文。在查找的时候,我们可以直接通过密文对比来进行查找就可以了。但是对于手机号、身份证号等信息我们就不能通过这种方式来进行加密了。因为手机号需要支持模糊查找,并且查找之后需要进行解密然后展示其明文信息。
所以很显然直接使用密钥查找的方式是行不通的。那么我们应该如何去实现加密模糊搜索呢?
如何对加密后的数据进行模糊查询呢?
对加密后的数据进行模糊查询的方式大概可以分为如下的几种
将所有的数据解密之后,加载到内存中再从内存中进行查找通过在数据库中通过加密算法进行操作可以通过高级算法来实现模糊搜索
下面我们就来看看如何来实现呢?
普通查询
普通的做法就是将所要查询的所有数据都通过解密之后,加载到内存中,然后进行模糊搜索。这种方式在数据量较小的情况下可以来使用,既简单又实惠。但是数据量如果太大的话,就会影响系统使用。
按照一个字母占用1个字节的空间,一个汉字占用2个字节的空间来计算,如下图所示。
会看到一个字段所占用的空间就已经这么大了,一个表按照15个平均字段来算的话,这样做很容易就会发生内存溢出的异常。
进阶查询
在数据库中实现与代码程序中一致的加解密算法,并且通过ORM插件来修改模糊查询的条件,使用数据库中的加解密函数先进行解密查找,这样做的优势就在于可以降低开发的资源消耗。比起上面那种做法要实惠很多。
但是缺点也是非常明显的,因为是加密之后的数据,所以无法依赖数据库索引来进行查询的优化。并且要保证程序与数据库使用相同的加解密算法也是非常难,而且,在开发过程中需要匹配加解密算法对于开发人员也是一种考验。
而第二种常规实现则是提前对于一些数据进行分词组合,并且进行加密,将加密的结果进行存储,然后在查询的时候可以通过like关键字组合加密的方式来进行匹配,这是一种比较简单的实现,
但是其缺点就是需要考虑到各种分词的组合,并且对分词组合数据进行分别的加密存储,当然在字段简单的情况下可以采用这种方式,但是如果字段较为复杂的时候,这种方式就会显现出各种弊端。当然这种方式的存储底层可能就不再使用关系型数据库进行存储了,而是采用非关系型数据库进行存储。
高级查询
通过一种新的算法来实现模糊匹配查询,这也是很算法工程师所研究的领域,但是想要实现一个既不可逆、又可以控制密文长度并且还可以支持模糊查询的算法真的非常困难。因为一般的算法思路都是通过编解码的方式来实现加解密。所以想要通过加密的方式来保留原文的一些模糊搜索的性质其实有点困难。有兴趣的读者可以参考如下的一些思路来做研究
通过数据库中加密字符串的模糊匹配算法来进行处理通过上面提到的非关系型数据库进行分词组合的方式来实现利用云存储解决方案中的验证模糊查询加密算法来实现总结
上面对于高级查询方式的分析,最可行的就是利用非关系型数据库来实现,例如可以通过ES存储分词加密,然后进行分词加密匹配。或者可以使用ORM框架中提供的Filter拦截器来实现数据的二次处理。不过总体来讲,为了保证数据的安全,也为了匹配成本,一般的方案都是通过ES进行分词加密来进行模糊搜索的。