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 的元数据,可以归结为只运行一个简单的选择,然后解析结果以填充内存中的字典。
这样做的理由如下:
- 比维护由 recordId/Key/Value 列组成的非归一化表更好的性能。
- 可扩展性
- 在数据库服务器上的空间上要保守。
我可以看到将这些配对存储在数据库列中的逻辑,但有些东西告诉我,从长远来看,这可能会导致问题,并且可能不是解决“可扩展性”问题的灵丹妙药。
有人可以就这种方法可能有什么问题提供一些反馈,以及在重负载的系统上存储和检索此类信息的最佳实践是什么。
谢谢
显然,这取决于特定情况,但这种违反 1NF 的方法通常是一种糟糕的方法。一个重要的问题是您永远无法查询元数据。(例如,“SELECT WHERE key2 = 'value3'”)另一个是如果不解析、调整、取消解析和重写整个大集合,你永远无法更新单个键/值。要单独处理索赔:
此声明是否真的针对您的数据进行了测试?如果您只需要记录中的一个键/值,您目前必须支付读取整个集合的数据库开销、将其传输到客户端的网络开销以及解析您需要的一个片段的 CPU 开销。做这项工作本质上正是数据库的设计目的,因此您实际上是在禁用擅长此类工作的组件,并用不必要的客户端编程对其进行不良模拟。
他们是怎么想出来的?将所有键/值对存储在单个字段中会随着对数量的增加而降低。
几乎可以肯定无关紧要。磁盘空间比糟糕的设计便宜。
PS 如果你有一个包含两个换行符的值会发生什么?