代码之家  ›  专栏  ›  技术社区  ›  maxp

如何有效地比较和搜索整数列表?

  •  4
  • maxp  · 技术社区  · 17 年前

    我有一个数据库,里面有一百万个对象。每个对象都有一个由整数组成的“标记”字段集。

    例如:

    object1: tags(1,3,4)
    object2: tags(2)
    object3: tags(3,4)
    object4: tags(5)
    

    object1 does not match ('1' not in '3,4,5')
    object2 does not match ('2' not in '3,4,5')
    object3 matches ('3 and 4' in '3,4,5' )
    object4 matches ('5' in '3,4,5' )
    

    如何有效地选择匹配对象?

    7 回复  |  直到 17 年前
        1
  •  3
  •   Vinko Vrsalovic    17 年前

    array 数据类型及其包含/重叠运算符。

    尽管如此,在Python中,您有 set datatype 对于这一组操作,使用PostgreSQL可能有点过分(取决于性能要求)

    >>> a = set([1,2,3])
    >>> a
    set([1, 2, 3])
    >>> 1 in a
    True
    >>> set([1,2]) in a
    False
    >>> set([2,3]) & a
    set([2, 3])
    >>> set([8,9]) & a
    set([])
    >>> set([1,3]) & a
    set([1, 3])
    >>>
    
        2
  •  3
  •   Bill Karwin    17 年前

    您需要的是在一个单独的表中为对象和标记之间的映射建模。

    CREATE TABLE Tagged (
      object_id  INT NOT NULL,
      tag_id     INT NOT NULL,
      PRIMARY KEY (object_id, tag_id),
      FOREIGN KEY (object_id) REFERENCES Objects(object_id),
      FOREIGN KEY (tag_id) REFERENCES Tags(tag_id)
    );
    

    为每个对象/标记对插入一行。当然,这意味着每一行有几行 object_id ,但没关系。

    SELECT DISTINCT object_id
    FROM Tagged
    WHERE tag_id IN (3, 4, 5);
    

    但这与object1匹配,这是您不想要的。您希望排除具有不在3、4、5中的其他标记的对象。

    SELECT DISTINCT t1.object_id
    FROM Tagged t1 
     LEFT OUTER JOIN Tagged t2
     ON (t1.object_id = t2.object_id AND t2.tag_id NOT IN (3, 4, 5))
    WHERE t1.tag_id IN (3, 4, 5)
     AND t2.object_id IS NULL;
    
        3
  •  1
  •   JV.    17 年前

    如果我理解正确的话,它就像一个:

    Post-> posttags <-tags

    一种模式。

    我想知道你为什么这样做?

    这是否是您遇到的问题,因为您正在使用ORM检索对象和其他延迟加载的关联对象中的数据。

    同样,如果从一个查询中加载的对象数量很大(请记住您的100万),那么您需要一台拥有大量资源(或者根本没有资源)的机器- 纯净的 不建议使用ORM)。

    posttags

        4
  •  0
  •   Razor    17 年前

    您还没有说明是否要使用SQL,或者在使用SQL之前是否要将数据读入应用程序。从事物的声音来看,您在寻找基于代码的解决方案吗?

    在.NET中,您可以让一个类实现ICompare接口,并编写自己的方法来比较两个返回0或1的值。

        5
  •  0
  •   OJ.    17 年前

    您可以使用多种语言应用此原则。大多数都有用于处理集合的库。您甚至可以使用SQL来实现这一点。

        6
  •  0
  •   unbeknown unbeknown    17 年前

    在我看来就像 issubset() 方法 sets 这是您正在寻找的:

    tags(1, 2, 3).issubset(q(1, 2, 3, 4))
    

    如果两者都有 tags q set 班 但我同意其他答案,在数据库中解决这个问题将是一个更好的解决方案。

        7
  •  0
  •   maxp    17 年前

    我很抱歉。看起来我很难很好地解释这个问题:)

    这里的“postgresql”标记比“python”更有意义。

    谢谢大家。