你什么时候不该用关系数据库?

除了 google/bigtable 这种情况,什么时候你不应该使用关系数据库?为什么不,你应该用什么?(你学会“艰难的道路”了吗?)

22620 次浏览

我建议您访问 高可伸缩性博客,它几乎每天都讨论这个主题,并且有许多关于在 RDMBS 上选择分布式散列等的项目的文章。

快速(但非常不完整的答案)是,并非所有数据都能以有效的方式很好地转换为表。例如,如果您的数据本质上是一个大字典,那么可能有比普通的旧 RDBMS 更快的替代方案。尽管如此,这主要是一个性能问题,如果性能在项目中不是一个大问题,而稳定性、一致性和可靠性,例如,是,那么当 RDBMS 是一个更加成熟和开发良好的方案,支持所有语言和平台,并且有大量的解决方案可供选择时,我认为深入研究这些技术没有多大意义。

15年前,我在研究一个信用风险系统(基本上就是一个大型的树木行走系统)。我们在 HPUX 和 solaris 上使用 Sybase,而性能正在扼杀我们。我们从 Sybase 直接聘请了顾问,他们说这是不可能的。然后我们切换到一个 OO 数据库(本例中是对象存储) ,获得了大约100倍的性能提升(代码编写起来也容易了大约100倍)

但这种情况相当罕见——关系数据库是一个不错的首选。

关系数据库范式对数据的使用做出了一些假设。

  • 关系由一组无序的行组成。
  • 关系中的所有行都具有相同的列集。
  • 每个列在所有行上都有固定的名称和数据类型以及语义含义。
  • 关系中的行由主键列中的唯一值标识。
  • 等等。

这些假设支持简单性和结构性,但牺牲了一些灵活性。并非所有数据管理任务都适合这种结构。例如,具有复杂属性或变量属性的实体就不需要。如果你需要在关系数据库解决方案不支持的领域保持灵活性,你需要使用不同的解决方案。

对于管理具有不同需求的数据,还有其他解决方案。例如,语义 Web 技术允许每个实体定义自己的属性,并通过将元数据视为与数据一样的属性来进行自我描述。这比关系数据库强加的结构更具灵活性,但这种灵活性是有代价的。

总的来说,您应该为每个作业使用正确的工具。

请看我对“ 下一代数据库”的另一个回答

根据我的经验,当以下任何一个标准成立时,你都不应该使用关系数据库:

  • 你的数据被构造成任意深度的层次结构或图形(网络) ,
  • 典型的访问模式强调阅读而不是写作,或者
  • 没有特别查询的要求。

深层次结构和图不能很好地转换为关系表。即使有像 Oracle 的 CONNECT BY这样的专有扩展的帮助,使用 SQL 查找树也是一件非常痛苦的事情。

关系数据库为简单的读访问增加了大量开销。事务和参照完整性功能强大,但对于某些应用程序来说有些过头了。因此,对于以读为主的应用程序,文件隐喻就足够了。

最后,如果没有意想不到的查询,你就不需要一个拥有成熟查询语言的关系数据库。如果没有西装革履的人问这样的问题: “我们在东海岸按销售人员分组销售了多少打了5% 折扣的蓝色小工具?”以后也不会有了,那么你,先生,就可以不用死尸了。

大约7-8年前,我在一个网站上工作,这个网站的流行程度超出了我们最初的预期,这让我们在性能方面遇到了麻烦。由于我们在基于 Web 的项目中都相对缺乏经验,这给我们带来了很大的压力,除了通常的数据库分离到单独的服务器上,负载平衡等等。

有一天我想到了一件很简单的事。由于网站是基于用户的,他们的个人资料存储在一个数据库表中,通常有人会这样做-用户 ID,许多信息变量和类似的东西-这将显示为一个用户个人资料页面,其他用户可以查找。我已经将所有数据刷新到一个简单的 html 文件中,该文件已经准备好作为用户配置文件页面,并得到了显著的提升——基本上是一个缓存。我甚至做了一个系统,当用户编辑他们的配置文件信息,它会解析原始的 html 文件,把它进行编辑,然后刷新 html 回到文件系统-得到了更多的提升。

我对用户之间发送的消息做了类似的处理。基本上,只要我能让系统完全绕过数据库,避免 INSERT 或 UPDATE,我就获得了显著的提升。这可能听起来像是常识,但这是一个启发性的时刻。这并不是回避关系设置本身,而是完全回避数据库—— KISS。

当模式变化很大时,关系数据库将很难处理。这就是 XML 数据库或键-值对数据库最好的工作方式。或者您可以使用 IBMDB2,并由单个数据库引擎管理关系数据和 XML 数据。

有三个主要的数据模型(C.J.Date,E.F.Codd) ,我在这里添加一个平面文件:

  • 平面文件(结构各不相同——从“愚蠢的”平面文本到符合语法的文件,再加上聪明的工具,可以做非常聪明的事情,想想编译器和它们可以做什么,在建模新事物方面的狭窄应用)
  • 分层的 (树,嵌套的集合-例子: xml 和其他标记语言,注册表,组织图表等等; 任何东西都可以建模,但是完整性规则不容易表达,检索难以自动优化,有些检索很快,有些很慢)
  • Network (网络,图表-例子: 导航数据库,超链接,语义网,几乎任何东西都可以建模,但检索的自动优化是一个问题)
  • 关系 (一阶谓词逻辑示例: 关系数据库,检索的自动优化)

层次结构和网络结构都可以用关系表示,关系结构也可以用其他两种结构表示。

关系被认为是“更好”的原因是声明性和标准化,不仅在数据检索语言,而且在数据定义语言,包括强大的声明性数据完整性,支持 稳定,可扩展,多用户管理系统。

收益是有代价的,大多数项目发现,对于将长期数据存储在可预见的未来可用的系统(多应用程序)来说,这是一个很好的比例。

如果您不是在构建一个系统,而是一个应用程序,可能是为一个用户,并且您相当肯定不希望多个应用程序使用您的数据,也不希望多个用户,那么您可能很快就会找到更快的方法。

同样,如果你不知道你想要存储什么样的数据以及如何建模,那么关系模型的优势就被浪费在这上面了。

或者,如果您只是不太关心数据的完整性(这也可以)。

所有的数据结构都针对特定的用途进行了优化,只有当适当的建模试图以语义无偏见的方式表示“现实”时,才会使用关系结构。那些在关系数据库方面经验不足的人通常不会意识到他们在其他类型的数据模型方面的经验会更糟糕。可能会出现糟糕的实现,尤其是在关系数据库中,构建复杂模型相对容易,但最终可能会遇到相当大的问题。不过,当我试图在 xml 中想象同样的怪物时,我总是感觉更好。

举个例子来说明这个关系模型有多好,IMO,就是你会发现涉及 SQL 的问题的复杂度与简短度的比率。