在数据库列中存储键值对

时间:2012-02-17 15:34:45

标签: database dictionary scalability key-value

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

Key1:Value1\n\nKey2:Value2\n\nKey3:Value3\n\n.....

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

这样做的理由如下:

  
      
  1. 比维护由列recordId / Key / Value。
  2. 组成的不合格表更好的性能   
  3. 可扩展性
  4.   
  5. 保守数据库服务器上的空间。
  6.   

我可以看到将这些parings存储在数据库列中的逻辑,但是有些东西告诉我这可能会导致长时间的问题,并且可能不是我们“可扩展性”困境的灵丹妙药。

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

由于

4 个答案:

答案 0 :(得分:4)

显然这取决于具体情况,但这种1NF违规通常是一种不好的方法。一个重要问题是您无法查询元数据。 (例如,“SELECT WHERE key2 ='value3'”)另一个原因是,如果不解析,调整,解析和重写整个大集,就无法更新单个键/值。单独解决索赔:

  1. 此声明是否已根据您的数据进行了测试?如果您只需要记录中的一个键/值,则您当前必须支付数据库开销以读取整个集合,将网络开销传输到客户端,以及用于解析您需要的一个部分的CPU开销。固有地完成这项工作正是数据库的设计目标,因此您实际上禁用了那种擅长此类工作的组件,并且通过不必要的客户端编程很难模拟它。

  2. 他们如何计算?将所有键/值对存储在单个字段中将随着对数的增加而降低。

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

  4. P.S。如果你有一个包含两个换行符的值,会发生什么?

答案 1 :(得分:2)

最大的问题是它们是孤立有意义的/你需要多久选择一对。

如果它主要是存储为name = value的属性包,并且这些对是相关的,则存储在一个块中可以节省空间和时间。

如果您希望快速轻松访问各个对,那么只要名称和值列具有唯一的名称,就可以使用名称和值列表。这将消耗更多的空间,如果你需要在一个点击中访问多个,你将失去一些优势。

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

答案 2 :(得分:1)

根据它们的频率,键/值对可以更好地存储在Memcache之类的内容中,因此任何人都可以即时访问和更新它们。

对于不太重要的东西,一个简单的键/值数据库表可以很好地工作,特别是在正确的引擎支持它的情况下(例如,一个更适合快速阅读而不是写作)。

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

这完全取决于它的用途,真的。

答案 3 :(得分:1)

这实际上是一种使您的关系数据库有效地成为NoSQL database的方法。我之前在系统中使用过这种技术,我们试图在系统中发出惊人的性能,而且效果非常好。在一种情况下,信息实际上是在调用REST API时使用的,需要在查询字符串中传递,因此信息存储为查询字符串(例如:“var1 = val1& var2 = val2”)所以整个string可以按原样传递给API。解析这种格式非常容易。但是你的问题是使用这种存储数据的方法有什么问题。我认为问题与normalizing your database as proposed by E.F. Codd解决的问题相同。但实际情况是,由于需要在当今系统中处理大量数据,数据库通常会被非规范化以实现所需的性能结果,并且NoSQL方法正在取得进展。