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



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

Key1:Value1nnKey2:Value2nnKey3:Value3nn.....

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

这样做的理由如下:

  1. 与维护由列recordId/Key/Value组成的denromalized表相比,性能更好
  2. 可扩展性
  3. 为了节省数据库服务器上的空间

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

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

感谢

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

  1. 这一说法是否真的根据您的数据进行了测试?如果您只需要记录中的一个键/值,那么您目前必须支付读取整个集合的数据库开销、将其传输到客户端的网络开销,以及解析出所需的一部分的cpu开销。从本质上讲,做这项工作正是数据库的设计目的,所以你本质上是在禁用擅长这类工作的组件,并用不必要的客户端编程来糟糕地模拟它。

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

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

附言:如果一个值中有两个换行符,会发生什么?

最大的问题是它们在隔离中是否有意义/您需要多久选择一对。

如果它主要是一个存储为name=value的财产包,并且这些对是相关的,那么一次性存储可以节省空间和时间。

若您想快速方便地访问单个对,那个么带有名称和值列的表是有意义的,当然,只要它们有唯一的名称。这会占用更多的空间,如果你需要在一次命中中访问多个,你就会失去一些优势。

这件事没有对错之分。可能会有最好的,但这种情况很容易改变。我们根据具体情况使用这两种方法。

根据需要的频率,键/值对最好存储在Memcache之类的东西中,这样任何人都可以立即访问和更新它们。

对于不那么关键的东西,一个简单的键/值数据库表会很好地工作,尤其是有合适的引擎支持(例如,一个更适合快速读取而不是写入)。

如果它更像是一个存档,那么您所拥有的格式在服务器上的数据文件中可以很好地工作,而不是在数据库中。

实际上,这完全取决于它的用途。

这实际上是一种将关系数据库有效地转变为NoSQL数据库的方法。我以前在系统中使用过这种技术,我们试图从系统中获得每一点性能,而且效果非常好。在一种情况下,信息实际上是在对RESTneneneba API的调用中使用的,并且需要在查询字符串中传递,因此信息被存储为查询字符串(例如:"var1=val1&var2=val2"),因此整个字符串可以照原样传递给API。解析这种格式非常容易。但你的问题是,使用这种存储数据的方法有什么问题。我认为这些问题与E.F.Codd提出的通过规范化数据库来解决的问题相同。但现实情况是,为了获得所需的性能结果,数据库往往会被去标准化,而NoSQL方法正在取得进展,因为在当今的系统中需要处理大量数据。

最新更新