Postgresql 选择按任意顺序包含子集字符的行

Postgresql 选择按任意顺序包含子集字符的行,postgresql,Postgresql,我有一个包含英语单词列表的表格,我试图从中选择所有可以用给定字符串制作的单词“hand”(如在拼字游戏中) 到目前为止,我的查询只会检查手上的任何字符是否存在于单词中 SELECT * FROM words WHERE word SIMILAR to '%e%|%z%|%h%'; /* returns test, father and zebra as they all contain either e,z or h */ 但是,这并没有考虑一个单词是否比手写体包含更多的字符,我在python

我有一个包含英语单词列表的表格,我试图从中选择所有可以用给定字符串制作的单词
“hand”
(如在拼字游戏中)

到目前为止,我的查询只会检查手上的任何字符是否存在于单词中

SELECT * FROM words WHERE word SIMILAR to '%e%|%z%|%h%';
/* returns test, father and zebra as they all contain either e,z or h */
但是,这并没有考虑一个单词是否比手写体包含更多的字符,我在python中使用的代码用于检查一个单词是否有效

def isValidWord(word, hand):
    """Return true or false can the word be made using the characters in the hand"""
    for i in word: # for each character in word
        if hand.count(i)<word.count(i): # is the character in the hand enough times
            return False
    return True # if every character in the word is present in the hand
def isValidWord(字,手):
“”“Return true或false是否可以使用手中的字符生成单词”“”
对于word中的i:#对于word中的每个字符
坦白说,如果hand.count(i)不是(关系型)数据库的工作

因为英语中的几千个单词,即使你把它们放大到所有可以想象的程度,也不会超过大约10万个单词,我真的不明白你为什么要使用数据库。只需用python编写一个内存中的单词列表,您只需线性浏览即可

有几种方法可以加快搜索大量数据的速度,但关系数据库无法应用其中任何一种方法。此外,考虑到字母是单字节数据,速度增益应该可以忽略不计

如果您担心性能:是的,在python中这样做确实会有很大的运行时开销,因为计算字母非常快,可以进行高度优化,但python本身是一种复杂的语言,执行它会设置一些限制

考虑到要处理的数据量相当小,我的方法是:

  • 准备单词列表:按字母顺序对词典中每个单词的字母进行排序,并使用排序后的字符串作为实际单词的键。您会发现一个排序的字符串可以映射到多个单词
  • 对你手上的字母进行排序
  • 对于单词列表中的每个键,检查它是否是你手上的一个子集。这应该非常快,因为前面的排序允许您避免重复检查(即,如果您在单词列表的开头,第一个单词以
    a
    开头,但您的最下手字母是
    e
    ,请跳到以
    e
    开头的第一个单词)
  • 从算法上讲,任何类型的树结构都可能更快,但在大多数PC风格的处理器上,编写良好的C代码将编译成非常快速的SIMD字符串比较。

    坦率地说,这不是(关系)数据库的工作

    因为英语中的几千个单词,即使你把它们放大到所有可以想象的程度,也不会超过大约10万个单词,我真的不明白你为什么要使用数据库。只需用python编写一个内存中的单词列表,您只需线性浏览即可

    有几种方法可以加快搜索大量数据的速度,但关系数据库无法应用其中任何一种方法。此外,考虑到字母是单字节数据,速度增益应该可以忽略不计

    如果您担心性能:是的,在python中这样做确实会有很大的运行时开销,因为计算字母非常快,可以进行高度优化,但python本身是一种复杂的语言,执行它会设置一些限制

    考虑到要处理的数据量相当小,我的方法是:

  • 准备单词列表:按字母顺序对词典中每个单词的字母进行排序,并使用排序后的字符串作为实际单词的键。您会发现一个排序的字符串可以映射到多个单词
  • 对你手上的字母进行排序
  • 对于单词列表中的每个键,检查它是否是你手上的一个子集。这应该非常快,因为前面的排序允许您避免重复检查(即,如果您在单词列表的开头,第一个单词以
    a
    开头,但您的最下手字母是
    e
    ,请跳到以
    e
    开头的第一个单词)

  • 从算法上讲,任何类型的树结构都可能更快,但在大多数PC风格的处理器上,编写良好的C代码将编译成非常快速的SIMD字符串比较。

    坦白说,这不是(关系)数据库的工作。是的,我想可能是这样的,我是PostgreSQL的新手,我不知道是否有一些内置方法可以让它变得简单,唉。坦率地说,这不是(关系型)数据库的工作。是的,我想可能是这样,我是PostgreSQL的新手,我不知道是否有一些内置方法可以让它变得简单,唉。
    def isValidWord(word, hand):
        """Return true or false can the word be made using the characters in the hand"""
        for i in word: # for each character in word
            if hand.count(i)<word.count(i): # is the character in the hand enough times
                return False
        return True # if every character in the word is present in the hand