2

我正在构建一个数据库 (SQLite) 来存储有关我编写的 Mathematica 脚本每次运行的信息。该脚本需要几个输入参数,所以我的数据库有一个表,每个参数都有一个列(在其他列中)。

一些输入参数是数字列表。我存储这些的第一个想法是使用该问题的已接受答案中所述的联结表。但我通常对几个不同的运行使用相同的列表。如何查找任何给定列表是否已在数据库中,以便我可以重用其 ID 而不是再次存储它?

评论中提到的约束:

  • 列表的长度没有明确的上限,但实际上它的范围从 1 到大约 50。
  • 不同列表的数量将很少,大约为 10。
  • 我实际上有 3 个列表参数。其中两个,列表中的值是非负的双精度浮点数;第三,这些值是成对的这样的数字。
  • 没有重复的条目。(这些是更精确的集合,所以没有重复和顺序无关紧要)
  • 我可以轻松地将列表元素排列为排序顺序。

例如:假设我的表是这样设置的

CREATE TABLE jobs (id INTEGER PRIMARY KEY, param1 REAL, param2_id INTEGER);
CREATE TABLE param2 (param2_id INTEGER PRIMARY KEY, value REAL);

当我运行脚本时,它会设置参数,然后调用一个函数来运行计算,如下所示:

param1 = 4;
param2 = {.1, .3, .5};
runTheCalculation[param1, param2]

假设这是脚本的第一次运行,它会将以下内容插入数据库:

jobs:   id      param1     param2_id
         1       4.0        1

param2: param2_id   value
         1           0.1
         1           0.3
         1           0.5

到现在为止还挺好。现在假设我用一个不同的参数再次运行脚本,

param1 = 2;
param2 = {.1, .3, .5};
runTheCalculation[]

在一个简单的实现中,这将导致数据库包含以下内容:

jobs:   id      param1     param2_id
         1       4.0        1
         2       2.0        2

param2: param2_id   value
         1           0.1
         1           0.3
         1           0.5
         2           0.1
         2           0.3
         2           0.5

但我希望它能够查找列表{.1, .3, .5}已经在数据库中的事实,以便在第二次运行后数据库包含以下内容:

jobs:   id      param1     param2_id
         1       4.0        1
         2       2.0        1

param2: param2_id   value
         1           0.1
         1           0.3
         1           0.5

我可以使用哪种查询来查找表中{.1, .3, .5}已存在该列表param2

我不反对在必要时创建额外的表格。或者,如果除了使用更有意义的连接表之外,还有其他模型,那也没关系。

4

3 回答 3

1

如果列表很短,并且列表的数量相对较少,那么您可以简单地对列表中的列表进行排序TBL_Lists,看看您的是否匹配。这是非常低效的,因为它将枚举所有存储的列表以与您的一个存储列表进行比较。

另一种方法,我认为更好的方法是对列表进行散列并将其散列存储在TBL_List_Hashes

散列列表需要枚举一次。

一个示例哈希算法可能是构建一个包含所有排序数值的字符串,均匀填充,然后对连接的字符串运行任何哈希方法。

获取给定列表的哈希然后从数据库中检索匹配的哈希应该相对容易。即使使用具有冲突的相对简单的哈希算法,您也可以显着减少进行比较所需验证的列表数量。

因此,如果您的哈希算法发生冲突,那么您将为每个错误匹配添加枚举(和查询)费用。

编辑:
这是 .net
.net 3.5 List<T> Equality 和 GetHashCode的相关答案

EDIT2:
如果您在匹配中与顺序无关,那么只需在
为具有列表对象的类散列 GetHashCode之前标准化列表顺序

于 2011-12-16T22:49:00.057 回答
1

你问: 我怎样才能查找任何给定的列表是否已经在数据库中?

正常的方式是使用索引,并且索引总是面向行的。因此,标准数据库设计建议您以某种方式需要将整个列表(标准化)排成一行。

由于您使用的是 SQLLite,因此您没有太多选择:

http://www.sqlite.org/datatype3.html

我推荐文本!您也可以索引 BLOB,BLOB 会节省一些空间,但可能 TEXT 可以正常工作,而且 TEXT 通常更便于调试和使用。尝试为您的列表发明某种规范的字符串格式,您可以解析/生成,并始终以一致的方式从数据库中插入/选择(例如,一致的舍入、预排序、删除重复项、尾随和前导零总是一致),你应该没问题。

警告: 这是一种低工程方法,甚至可能是“不正确的方式(TM)”,但如果它完成了工作......

于 2011-12-17T01:15:57.433 回答
0

一般来说,不要使用列表,除非您有一组非常不寻常的要求,并且有足够的实践经验来预测后果。

包含在联结表中的多对多关系以及适当的索引将执行得一样好并且更易于使用。它也更灵活。

于 2011-12-17T16:03:58.803 回答