【问题标题】:Key-Value Database键值数据库
【发布时间】:2011-12-25 08:12:28
【问题描述】:

我需要存储短字符串(50 多个字符),然后快速查找它们。起初我想为此使用 SQLite。我创建了一个带有单个索引 TEXT 列的表。使用各种低级技巧,我可以在 10 秒内用 100 万个字符串填充数据库。

问题在于,如果重新启动 PC,添加额外的 10.000 行需要 30 秒,这与 10 秒内 1M 行不一致。这样做的原因是 SQLite 在添加新行之前必须从磁盘读取现有索引的很大一部分。另一个问题是数据库的大小翻了一番,因为由于 b-tree 机制,所有字符串都存储了两次(一次在常规表中,一次在索引表中)。

有没有简单的替代方案?例如,哪个使用基于哈希的查找?我知道各种 NoSQL 解决方案,但它们专注于去中心化和分布式存储,而我只需要一个简单的嵌入式“平面文件”数据库?

【问题讨论】:

  • 关于索引我不明白?您是否使用与 key 和 value 相同的值?
  • 如果你想要一个嵌入式数据库,你需要指定女巫语言/平台。
  • 如果你使用相同的值作为索引和值,一个索引是完全没用的。
  • 如果索引包含与实际表完全相同的内容,全表扫描会变慢吗?您还需要考虑到表和索引中的所有内容都是重复的。
  • @jgauffin 因为索引中的数据是经过排序的,所以它可以进行快速的二分查找,并跳过大部分行。使用全表搜索,必须检查每一行。

标签: .net database hash hashtable key-value


【解决方案1】:

将最新值保存到磁盘有多重要?

您可以使用诸如 Dictionary 或 List 等内存中的集合,并通过serializing it 定期将其以异步调用的方式保存到本地文件中。

然后,当您的应用程序启动时,您可以将其反序列化回内存。

这将是一种响应速度更快的方式来完成您所追求的目标,因为您不必一直通过读/写努力敲打磁盘。

【讨论】:

  • 在我将数据插入 SQLite 之前,数据已经在字典中,因此实现起来相当容易。但是将它反序列化回内存,仍然需要从磁盘读取整个文件(如果我错了,请纠正我)。它可能比 SQLite 更快,因为它将是一个长的顺序读取,而不是许多小的随机读取。但这仍然不是我想要的:能够在不读取所有先前记录的情况下执行插入。
  • 追加到纯文本文件怎么样?
  • 这会扭转问题:使用文本文件我可以在不读取以前的记录的情况下进行插入,但要查找单个键,我必须平均读取文件的 50%,因为我无法将哈希/键转换为该文件中的某个位置。我可以创建第二个文件,在其中将哈希值映射到文件偏移量,但本质上我正在重新发明轮子:)
  • 嗯..您可以使用我在答案中提到的二进制序列化,除了在启动时您使用新字典开始您的应用程序,直到将序列化数据加载到内存中,然后合并两个字典通过将新的哈希值复制到从磁盘加载的哈希值中。更简单的解决方案,但仅当您不需要将应用程序逻辑基于是否已添加特定结果时才有效。
猜你喜欢
  • 1970-01-01
  • 2021-03-30
  • 2012-01-28
  • 2012-01-26
  • 2020-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多