【问题标题】:SQLITE: Single table with 20 columns vs 20 key-value tablesSQLITE:具有 20 列的单表与 20 个键值表
【发布时间】:2015-03-07 10:29:42
【问题描述】:

我正在开发管理由组件组成的对象的系统。 从性能的角度来看,将它们存储在 SQLITE 数据库中的最佳方法是什么?如果有 20 种组件类型 每个组件都是一个 1-10Kb 大小的 blob。通常每个对象由 4-6 个不同的组件组成。

我可以看到两个选项:

  1. 将其实现为一个具有键和 20 个 blob 列的表
  2. 使用 20 个带有键和单个 blob 列的表

我将对数据库进行的唯一查询是:通过 id 获取组件数据、写入数据和删除数据。

PS:对象类看起来像这样:

class Entity
{
    Component *components[20];
}

通常组件数组有 4-6 个非空指针

【问题讨论】:

  • 1) 最简单的找出方法是针对您的工作负载对两者进行基准测试。 2)在进行基准测试时,请确保您知道您对延迟与吞吐量的关心程度。 3) 性能问题几乎总是特定于工作负载。
  • 是的,但我认为我的问题更多是关于 sqlite 以及它在内部存储多个字段的方式。如果列中 75% 的值是空的,是否有效?
  • 在这种情况下,您可能应该 a) 重新表述您的问题以询问有关 sqlite 存储结构的问题,也许 b) 通过指向源代码中您查看但不理解的地方来展示您的努力。
  • 我认为答案显然仅取决于 sqlite 内部结构。我问这个问题是因为要回答这个问题要么需要付出巨大的努力来分析 sqlite 资源,要么需要大量使用 sqlite 数据库的经验
  • 让我试着解释一下,对吗?您有每个包含一组组件的对象。 恰好有 20 种不同的可能 ComponentType。 (当您说“ComponentType”时,是否意味着有多个不同的组件都是 ComponentType1?如果是这样,每个 Object 的 ComponentType1 版本是否与每个其他 Object 的 ComponentType1 版本不同?) 每个 Object可以选择在 20 个 ComponentTypes 中的每一个中使用零或一个,并且这个数字 20 是固定的并且永远不会改变?如果您可以将其表达为类并举例说明,那会有所帮助。

标签: sql sqlite key-value-store


【解决方案1】:

您可能需要一个实体属性值结构来存储 BLOB。

CREATE TABLE myObjectComponents (
   objectID          INTEGER,    -- Entity
   componentTypeID   INTEGER,    -- Attribute
   componentBLOB     BLOB,       -- Value
   PRIMARY KEY objectID, componentTypeID
)

然后您还可以添加一个带有其他非 blob 值的传统“myObject”表(例如它的身份列、所有者、名称、创建和修改的时间戳等),并强制执行与外键约束的完整性。


EAV 表非常灵活,适合快速查找 Value 列。

他们在另一个方向上很穷; “给定一个值(或值的组合),哪些实体有它?”但您似乎不太可能搜索 BLOB 字段。

您可能想详细了解 EAV 的优缺点,网上有很多参考资料。


在您的情况下,这种结构的好处是每一行只有一个 BLOB,并且 (可能更重要) 它不是稀疏的;您不会拥有可容纳 20 个 BLOB 的行,而只能使用其中的 4 个。这将更容易在内存中传输相关行。

【讨论】:

  • 感谢您的回答。但是您认为 EAV 是否​​比每种类型的单独表格更好?使用单独的表,我将拥有更快和更小的索引,因此它们应该运行得更快。
  • 我需要了解更多关于您的应用程序的信息,但通常这会被认为是过早的优化。 20 个表降低了灵活性,并且对索引的好处非常有限。简单来说,您的建议可能导致需要针对 20 个不同的表执行 20 条语句(需要 20 条略有不同的语句),而单个表将在一个查询中完成此操作 - 一次索引查找。在超过 10 年的数据库工作中,我一直发现更少的表(在合理范围内)会导致代码更短、更易于维护/更灵活,并且通常更快。
  • 写出所有用例以了解您将要执行的 sql 语句可能会有所帮助。与针对 EAV 表的单个查询相比,您可能会发现您经常针对 20 表结构运行多个查询(或者更糟的是,将它们全部连接在一起)。然后,您可以估计每个单独查询所需的性能优势,以减轻运行更多查询的开销。很难想象在任何情况下您的收益将超过您的额外开销。
  • 真正唯一重要的用例是通过其类型和 id 获取组件数据——因为组件数据是按需随机加载的。我所有的结构都在内存中(不在数据库中),并且只根据需要从数据库中加载巨大的组件
  • 我仍然会推荐 EAV。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-09
相关资源
最近更新 更多