将键值对存储在数据库列中

sc_*_*ray 3 database dictionary scalability key-value

在我的代码库中,我最近遇到了团队做出的一项设计决策,其中键值对以格式化的方式存储在数据库 (Relational-mysql) 列中。有一个通用的元数据集,并且对于特定记录可能存在此元数据的子集。对于给定的记录,其元数据子集及其值以如下格式化方式存储在列中:

Key1:Value1\n\nKey2:Value2\n\nKey3:Value3\n\n.....
Run Code Online (Sandbox Code Playgroud)

要获取给定记录 ID 的元数据,可以归结为只运行一个简单的选择,然后解析结果以填充内存中的字典。

这样做的理由如下:

  1. 比维护由 recordId/Key/Value 列组成的非归一化表更好的性能。
  2. 可扩展性
  3. 在数据库服务器上的空间上要保守。

我可以看到将这些配对存储在数据库列中的逻辑,但有些东西告诉我,从长远来看,这可能会导致问题,并且可能不是解决“可扩展性”问题的灵丹妙药。

有人可以就这种方法可能有什么问题提供一些反馈,以及在重负载的系统上存储和检索此类信息的最佳实践是什么。

谢谢

Ale*_*sky 5

显然,这取决于特定情况,但这种违反 1NF 的方法通常是一种糟糕的方法。一个重要的问题是您永远无法查询元数据。(例如,“SELECT WHERE key2 = 'value3'”)另一个是如果不解析、调整、取消解析和重写整个大集合,你永远无法更新单个键/值。要单独处理索赔:

  1. 此声明是否真的针对您的数据进行了测试?如果您只需要记录中的一个键/值,您目前必须支付读取整个集合的数据库开销、将其传输到客户端的网络开销以及解析您需要的一个片段的 CPU 开销。做这项工作本质上正是数据库的设计目的,因此您实际上是在禁用擅长此类工作的组件,并用不必要的客户端编程对其进行不良模拟。

  2. 他们是怎么想出来的?将所有键/值对存储在单个字段中会随着对数量的增加而降低。

  3. 几乎可以肯定无关紧要。磁盘空间比糟糕的设计便宜。

PS 如果你有一个包含两个换行符的值会发生什么?