Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.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
Database 在具有相同域的大型集合上执行子集测试操作的最快方法_Database_Algorithm_Database Design_Set_Set Theory - Fatal编程技术网

Database 在具有相同域的大型集合上执行子集测试操作的最快方法

Database 在具有相同域的大型集合上执行子集测试操作的最快方法,database,algorithm,database-design,set,set-theory,Database,Algorithm,Database Design,Set,Set Theory,假设我们在某处存储了数万亿套。每个集合的域都是相同的。它也是有限的和离散的。因此,每个集合可以存储为长度相对较短(例如1024)的位字段(例如:000010111…)。也就是说,位字段中的位X指示给定集合中是否包含项X(1024个可能的项) 现在,我想设计一种存储结构和算法来有效地回答这个问题:数据存储中的哪些集合将Y作为子集。集合Y本身不在数据存储中,而是在运行时指定的 现在解决这个问题的最简单的方法是,将集合Y的位字段与数据存储中每个集合的位字段一一对应,选择AND结果与Y的位字段匹配的字段

假设我们在某处存储了数万亿套。每个集合的域都是相同的。它也是有限的和离散的。因此,每个集合可以存储为长度相对较短(例如1024)的位字段(例如:000010111…)。也就是说,位字段中的位X指示给定集合中是否包含项X(1024个可能的项)

现在,我想设计一种存储结构和算法来有效地回答这个问题:数据存储中的哪些集合将Y作为子集。集合Y本身不在数据存储中,而是在运行时指定的

现在解决这个问题的最简单的方法是,将集合Y的位字段与数据存储中每个集合的位字段一一对应,选择AND结果与Y的位字段匹配的字段

我怎样才能加快速度?是否有一种树结构(索引)或某种智能算法,允许我执行此查询,而不必检查每个存储集的位字段


是否有数据库已经支持对大型集合的此类操作?

我倾向于说答案是否定的,因为位字段的基数非常低。

这将是对基于卷的传统RDBMS的延伸,您看过基于图形存储模型的RDBMS了吗

如果您可以预处理集合,那么子集关系可以表示为DAG(因为您正在描述偏序集)。如果计算了传递约简,那么我认为您可以通过从最大的集合开始执行DFS,并在Y不再是当前访问集合的子集时停止,从而避免测试所有集合。

取决于从中绘制所有集合的集合的基数,一种选择可能是构建从元素到包含元素的集合的反向索引映射。给定一个集合Y,然后通过分别查找包含每个元素的所有集合并计算它们的交集,可以找到所有以Y作为子集的集合。如果您按排序顺序存储列表(例如,通过使用值0、1等对数据库中的所有集合进行编号),那么您应该能够相当有效地计算此交集,假设没有一个元素包含在过多的集合中

快速看一眼,我就会想到BDD——这在某种程度上与DAG解决方案的思想一致。或者是ZDD。

如果RDBMS是您唯一的选择,我建议您阅读这篇关于在SQL中建模DAG的有趣文章:


如果您负担不起Oracle或MSSQL,可以看看支持递归查询的PostgresQL 9。在相当长的一段时间内,它还支持交叉联接。

您使用的是哪种类型的数据库?专有格式?SQL Server?DB的选择将取决于它是否有效地支持大量集合上的给定集合操作。没有一个SQL数据库可以扩展到所需的大小(无论如何,对于这个问题来说,RDMS数据库是一个糟糕的选择)。因此,我们要么选择专门的数据库,要么选择我将自己实现的数据库。您找到解决方案了吗?奇怪的是,这个任务没有知名的数据库。它能有效地支持处理大型集合吗?据我所知,它更适用于存储图形,而不是集合。你能详细说明一下吗?您基本上是在讨论像下面这样构建DAG,但只使用现有集合中的节点吗?在执行DFS时,如何选择起始节点?是的,基本上是这样。如果a是B的超集,则有一条从a集到B集的边。使用传递约简更好,因为边的数量减少了(因此分支因子也应该减少,以便检查的无用节点更少)。由于该图是非循环的,因此将有一组节点没有进入它们的边,您可以从那里开始(这些节点表示集合中没有超集的集合)。您必须在所有这些集合上启动DFS(或者只从连接到所有这些集合的虚拟节点启动,而不使用超集)。很有趣。我会记住这个算法,尽管数据存储中的集合不太可能有很多子集/超集关系,所以我最终会在很多起始节点上执行DFS。如果有太多的头,那么您可能需要构造一些虚拟节点(例如,相似的头对的并集)。这可能有助于更快地丢弃集合的一部分,尽管这实际上取决于Y是否需要匹配集合中的许多集合——这只是一个随机的想法。这一点很好。数据存储中集合的基数是~我知道,如果您有两个排序的序列,并且希望计算交集,那么可以通过重复以下步骤来实现:虽然两个列表不是空的,但请查看每个序列的第一个值。如果它们不相同,则移除两者中较小的一个。如果它们相同,则表示您在交点中检测到一个值。这在时间O(n+m)中运行,其中n和m是两个序列的长度。如果对序列对运行此过程,则对结果等运行此过程。此过程以O(n lg k)为单位运行,其中k是序列的#,n是序列的最大长度。