具有“开放模式”的数据库 - 好主意还是坏主意?

Posted

技术标签:

【中文标题】具有“开放模式”的数据库 - 好主意还是坏主意?【英文标题】:Database with "Open Schema" - Good or Bad Idea? 【发布时间】:2011-02-20 17:03:19 【问题描述】:

Reddit 的联合创始人介绍了他们在扩展到数百万用户时遇到的问题。可通过here 获取摘要。

让我惊讶的是第 3 点:

相反,他们保留了一个事物表和一个数据表。 Reddit 中的一切都是事物:用户、链接、cmets、subreddits、奖项等。事物保持共同的属性,如赞成/反对票、类型和创建日期。 Data 表有三列:事物 id、key、value。每个属性都有一行。标题、网址、作者、垃圾邮件投票等有一行。当他们添加新功能时,他们不必再担心数据库了。他们不必为新事物添加新表或担心升级。

这对我来说似乎是一个糟糕的主意,但它似乎对 Reddit 来说已经奏效了。不过,总的来说这是个好主意吗?或者是 Reddit 的一个特性恰好对他们有用?

【问题讨论】:

【参考方案1】:

这是一个名为EAV 的数据模型,用于entity-attribute-value。它有它的用途。一个典型的例子是患者测试数据,它自然是稀疏的,因为可能会运行数十万个测试,但通常只有少数几个可供患者使用。包含数十万列的表很愚蠢,但带有 EAV 的表很有意义。

【讨论】:

【参考方案2】:

我注意到他们没有提及根据这些数据创建报告的难易程度。当在少数情况下使用时,EAV 可能是有益的。作为大多数系统的核心部分,当您点击报告时,它将成为一场噩梦。 EAV 的问题在于,大部分好处是在项目开始时,而大部分痛苦是在分析和报告的后期,特别是由于严重缺乏数据完整性。 “不必担心外键”对我来说听起来像是孤儿行的噩梦。为所有内容添加代理键的使用,您将陷入纠结的泥潭,通常以完全重写而告终

【讨论】:

实际上在谈话中,霍夫曼确实谈到了创建报告以及他们如何通过将一堆数据导出到文本文件并在其他地方进行分析来做到这一点vimeo.com/10506751m24:50 Reddit 几乎没有数据完整性要求。这不像他们存储必须在特定范围之间或具有复杂业务规则的日期或整数值。即,数据的正确性对于像 reddit 这样的网站并不重要;它只需要大部分是正确的。但是,LOB 应用程序不能容忍不准确。 Reddit 的设计重点是捕获数据而不是正确性。然而,关于正确性的问题在于,当您确实关心它时,不提前解决它的成本非常高。【参考方案3】:

大多数真正的大型网站最终都在数据库方面使用了某种令人难以置信的简单方法。这具有快速且可扩展的优点。它的缺点是,您让数据库自动执行的所有关系(通过触发器等)您需要在您的客户端代码中强制执行。保持一致性是一件令人头疼的事,而且您的数据几乎总是有一定的可能会不一致,至少在短时间内是这样。

对于社交网站来说,这是一个值得妥协的方案。大多数时候正确的数据就足够了(例如,谁真正关心您收到的对某项项目的赞成票数量在发送时是否真的过时了 20 毫秒),并且在扩展以支持大量数据的同时保持合理的成本用户很重要。

【讨论】:

【参考方案4】:

不久前我们也遇到过类似的问题,我可以说一开始并不容易和有趣,但是当你习惯了它之后,它有它自己的好处,就像用你的开发另一个数据库一样表格,在某些领域,这是一项矫枉过正的任务,但是当您通过这些级别时,它会为您提供很多功能,基本上在某一点之后,我们没有创建任何新表格,我们只是为所有内容创建动态表格,即使是我们自己的编程任务。 至于性能,系统没有得到数百万行进行公平比较,但对于日常使用,我从未注意到任何差异。 我想分享一些问题。

    我们没有删除任何行,我们只是将它们隐藏并设置了一个标志,并且每晚(每周)服务会清理物理行 孤行,我们基本上不关心清理子行,我们只是在父亲上设置“IsDeleted”,夜间服务会清理所有孤行或不再需要的行。

3.你应该保持你的索引是最新的,但你应该尽可能地跳过构建它们(再次夜间服务保持索引是最新的)

    我们提前准备了报告数据 (AOT),这意味着我们落后于实际数据 :))

我们努力不跳入行的海洋以根据用户需求计算一些值。如果我们准备好了,你可以使用它,如果没有,那么你不能

最后,这种方法有很多独特的挑战,您应该找到解决方法,在日常工作中从未遇到过的问题,但在所有这些之后,您可以获得更多可以使用的灵活性。

【讨论】:

以上是关于具有“开放模式”的数据库 - 好主意还是坏主意?的主要内容,如果未能解决你的问题,请参考以下文章

在 PHP 中模拟命名函数参数,好主意还是坏主意?

将数据存储为具有空/空值的 HashMap 中的键是一个好主意吗?

软删除是个好主意吗? [复制]

Mono 和 C# IOCP:这是个好主意吗?

以 UTC 存储时间总是一个好主意,还是以本地时间存储更好?

在现有 AspNetUser 表中手动创建列是个好主意吗?