【发布时间】:2012-10-03 01:16:23
【问题描述】:
我正在尝试验证一个属性数据库(实际上是一个文件系统,但对于本次讨论,我想保持简单)。该数据库具有以下属性:
它可以有 1 个或 2 个主键,它们必须是整数。 列可以是字符串(不允许使用 ascii)、整数、长整数或日期时间
我想验证我要求此数据库存储的值是否与大量记录(> 500k 记录)一起正确存储。因此,为此,我想扩展一个生成数据的工具,以便以后轻松验证。
所以基本上,说这是示例架构:
pk1 (int - primary key)
pk2 (int - primary key)
s1 (string)
l1 (long)
i1 (int)
我想用这个工具生成 50 万条记录。然后,在任何给定时间,我都希望能够对给定记录进行健全性检查。我可能会执行一系列操作(比如备份,然后恢复数据库),然后“抽查”一些记录。所以我希望能够快速验证主键(pk1 = 100,pk2 = 1)的记录条目是否有效。
为每列生成值以便以后轻松验证的最佳方法是什么。这些值不必是完全随机的,但它们也不应该经常重复,因此一些压缩逻辑也可能会受到影响。
例如,说“不知何故”该工具为一行生成了以下值:
pk1 = 1000
pk2 = 1
s1 = "foobar"
l1 = 12345
i1 = 17
现在我执行了几个操作,并且我想在这结束时验证该行没有损坏。在给定 pk1=1000 和 pk2=1 的情况下,我必须能够快速生成 s1、l1 和 i1 的预期值,这样才能非常快速地对其进行验证。
想法?
(由于我是新手,所以无法发布我自己的问题的答案,所以添加这个:) 好的,所以我必须采取可能的方法:
方法#1: 使用 HASH(tablename) ^ HASH(fieldname) ^ pk1 ^ pk2 作为种子。这样,我可以在验证时轻松计算每列的种子。另一方面,在为大量行生成数据时,这可能会很昂贵,因为种子需要每列计算一次。所以对于上述模式,我将有 500k*3 个种子(生成 500k 条记录)。
方法#2(由 Philipp Wendler 提出): 每行生成一个种子,并将种子存储在该行的第一列中。如果第一列是 int 或 long,则按原样存储值。如果第一列是字符串,则将种子存储在前 x 个字节中,然后使用使用该种子生成的字符将其填充到所需的字符串长度。
我更喜欢方法 #2,因为每行只有一个种子 - 使得数据生成比方法 #1 更快。
【问题讨论】:
-
所以我正在考虑更有创意的解决方案...如果我以这种方式生成种子会怎样: Seed = HASH(tablename) ^ HASH (columnname) ^ pk1 ^ pk2 现在我可以轻松计算种子给定 pk1 和 pk2,同时仍然保持表之间的随机性。列名可以在表中重复相同的 pk1 和 pk2 值。但这没关系,因为从功能上讲,它们应该具有相同的值。。
-
另一种选择是遵循 Philipp Wendler 建议的以下内容:使用表格的第一列来存储使用的种子。如果这是一个 int 或 long,只需将种子原样存储到其中。如果这是一个字符串,则使用前 n 个字节来存储种子,并使用使用该种子生成的字符将字段填充到所需的长度。
-
你也生成主键吗?如果是,您可以使用它们来存储其他列的哈希。当然,这可能会在插入时给您一些冲突(但如果您随机生成 pk,这也可能发生)
-
@wmz 是的,我使用不同的种子来生成 PK。关于如何生成 PK 有不同的业务逻辑,所以我有一个很好的传播。例如,其中一个要求是 35% 的条目具有相同的 PK1 值,但唯一的 PK2 值。每个表都有不同的业务要求 - 但我想通过省略这些细节来简化问题,因为我可以自己弄清楚那部分。