Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PostgreSQL,查找差异为n个字符的字符串_Sql_Postgresql_Indexing_Pattern Matching - Fatal编程技术网

PostgreSQL,查找差异为n个字符的字符串

PostgreSQL,查找差异为n个字符的字符串,sql,postgresql,indexing,pattern-matching,Sql,Postgresql,Indexing,Pattern Matching,假设我有一张这样的桌子 id data 1 0001 2 1000 3 2010 4 0120 5 0020 6 0002 id是主键,data是固定长度的字符串,其中字符可以是0、1、2 有没有一种方法可以建立索引,这样我就可以快速找到与给定字符串相差n个字符的字符串?比如字符串0001和n=1我想得到第6行 谢谢。这是附加模块提供的功能。它完全符合您的要求: SELECT * FROM a WHERE levenshtein(data, '1110') =

假设我有一张这样的桌子

id  data
1   0001
2   1000
3   2010
4   0120
5   0020
6   0002

id
是主键,
data
是固定长度的字符串,其中字符可以是0、1、2

有没有一种方法可以建立索引,这样我就可以快速找到与给定字符串相差n个字符的字符串?比如字符串
0001
n=1
我想得到第6行

谢谢。

这是附加模块提供的功能。它完全符合您的要求:

SELECT *
FROM   a
WHERE  levenshtein(data, '1110') = 1;

但它不是很快。使用大表时速度较慢,因为它不能使用索引

使用附加模块提供的相似性或距离运算符,您可能会有收获。这些可以使用链接手册页面中详细说明的三元索引。我没有取得任何进展,模块使用了不同的“相似性”定义

总的来说,这个问题似乎符合实际情况

如果您的案例与问题中的示例一样简单,您可以将
LIKE
与trigram GIN索引结合使用,这对于大表来说应该相当快:

SELECT *
FROM   a
WHERE  data <> '1110'
AND   (data LIKE '_110' OR
       data LIKE '1_10' OR
       data LIKE '11_0' OR
       data LIKE '111_');
选择*
从
其中数据“1110”
和(数据如“_110”或
数据如“1_10”或
类似“11_0”或
数据如“111"”;
显然,如果字符串较长且差异大于
1
,这种技术很快就变得不可行

但是,由于字符串很短,任何查询都会匹配相当大比例的基表。因此,指数支持几乎不会给你买任何东西。大多数情况下,Postgres按顺序扫描会更快


我测试了10k和100k行,有和没有三角图索引。由于约19%符合给定测试用例的标准,因此顺序扫描速度更快,
levenshtein()
仍然获胜。对于匹配少于约5%行(取决于)的更具选择性的查询,使用索引的查询速度更快。

对于
n=1
您应该只找到第6行。第2行和第5行在两个地方不同。哎呀,更正了,谢谢@Erwinbrandstetter如果n=2,那么ID将是3和4?@Roms应该是5和2是的,我想是关于levenshtein的,但我想它不是很快:(我现在正在检查三联图。)