何时不应使用关系型数据库?

73

除了Google / Bigtable场景外,何时不适合使用关系数据库?为什么不适合?应该使用什么?(你是否有“吃过亏”的经历?)


1
当你的模式变化很大时,关系型数据库会让你很难处理。这就是 XML 数据库或键值对数据库最擅长的地方。或者你可以使用 IBM DB2,让关系数据和 XML 数据由单个数据库引擎管理。免费获取 - 请访问 http://FreeDB2.com。 - Leon Katsnelson
+1 有趣。我喜欢这样的问题,人们讨论何时必须以不同的方式处理事情,例如“XML何时实际上不是一种合理的数据存储方法?”等等。 - J M
1
SO为什么要关闭这样的问题?我已经看到很多人滥用数据库了。他们认为无论需要做什么应用程序,都需要一个数据库。当你手里只有一把锤子时…… - Gabriel
7个回答

42

根据我的经验,当以下任何一个条件成立时,您不应使用关系型数据库:

  • 您的数据结构呈层次结构或任意深度的图形(网络)
  • 典型的访问模式更强调读取而非写入
  • 没有对特定查询的要求

深度层次结构和图形不适合转换为关系表。即使使用像 Oracle 的 CONNECT BY 这样的专有扩展也很难通过 SQL 追踪树形结构。

对于只读应用程序,关系型数据库在简单读取访问方面添加了很多额外开销。虽然事务处理和参照完整性很强大,但对于某些应用程序来说可能过于臃肿。因此,使用类似文件隐喻的方式已经足够好。

最后,如果没有需要预期之外的查询,您就不需要关系型数据库的完整查询语言。如果没有人问诸如“我们在东海岸售出了多少 5% 折扣的蓝色小部件,并按销售员分组?”,那么您可以自由地不使用数据库。


1
如果层次结构更宽而不是更深,则关系型数据库仍然可能是一个合理的选择。如果最大深度是固定的,那么您总是可以对层次结构进行去规范化和扁平化处理(虽然不太美观)。 - yukondude
2
即使在关系型数据库中,嵌套集模型也能很好地工作,你认为呢?http://en.wikipedia.org/wiki/Nested_set_model - Henrik Paul
27
一个层次结构并没有任何冲突之处。这就是具有1:m关系的JOIN操作。为什么因为更注重阅读而不使用关系型数据库管理系统呢?99%的网站都是如此。同样,"没有即席查询"也是错误的。这个回答的三个观点都是错误的。而且回答者甚至没有按要求提供任何建议的替代方案。它获得了10个赞同票和接受?看起来像是一个预设问题。 - dkretz
4
  1. 层级关系是1:m的自反关系,使用JOIN可以找到下一级别,但对于任意深度的连接就不那么容易了。
  2. 确实,大多数只读网站使用关系型数据库,但是,引用完整性和事务一致性对只读使用并不那么有用。
  3. 临时查询是关系理论存在的原因——请再次审查E.F. Codd。
  4. 很抱歉,这不是设定。事实上,我非常相信关系型数据库的能力,并教授使用它们的课程,但是人们必须认识到任何技术的局限性。
- yukondude
3
“只因为其他网站这样做,并不意味着这是最优的。我敢打赌你提到的那99%中有99%使用关系型数据库,是因为他们不知道其他选择。” - Travis Heseman
显示剩余8条评论

22

关系型数据库范式对数据的使用进行了一些假设。

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

这些假设支持简单性和结构性,但代价是灵活性受到限制。并不是所有的数据管理任务都适合这种结构。例如,具有复杂属性或可变属性的实体就不适合。如果需要在关系型数据库解决方案不支持的领域获得灵活性,则需要使用不同类型的解决方案。

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

总之,应该为每项工作选择正确的工具。

另请参见我回答“Next-gen databases”中的其他答案。


1
+1 针对关系型数据库范式假设的具体内容。我认为大多数初学者到中级开发人员(包括我在内)都会忘记它是基于假设设计的,而且可能不是最好的方式。在哪些类型的系统中,您需要更多的灵活性? - J M
1
如果您需要数据库在给定关系中对所有实体强制执行一致的属性集,则这确实是最佳方法。如果您有一个具有可变属性的实体集合,例如具有许多不同类型产品的产品目录,则需要更多的灵活性。@JM - Bill Karwin
@nawroth:没错!你不会用螺丝刀敲钉子,也不会用锤子拧螺丝。也许如果你有足够的决心和耐心,这些事情都是可能做到的,但如果你使用正确的工具,它将更容易、更高效和更成功。 - Bill Karwin
1
@Bill,嗯...如果我没记错的话,这些“假设”是有意为之的;每个假设都是为了防止数据模型被污染,并朝着实际关系数据库的方向发展(我们没有RDBMS,它们并不真正是关系型的,只是类似于关系型)。今天,在某种程度上,你是对的,即RDBMS没有提供一个干净的数据管理解决方案,而且还有其他有效的方法(特别是在速度、灵活性和完成工作方面);然而,我不会真的想使用任何其他数据模型来进行企业级数据管理(例如为大公司建模ERP)。 - Unreason
这(理论上)是关系系统的最强大的优点(在我看来)- 它们可以扩展和集成。当您将业务流程的部分计算机化时,倾向于尽可能达到同质平台。选择正确的工具是个好主意,但是标准是什么:系统速度?维护/系统成本?简单性? - Unreason
显示剩余2条评论

13

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

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

分层和网状都可以在关系型中表示,而关系型也可以用另外两个来表示。

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

这些优点是有代价的,对于将长期数据以可预见的形式存储的系统(多应用程序)来说,大多数项目都发现这是一个很好的比率。

如果您不是正在构建一个系统,而是一个单一的应用程序,可能只有一个用户,并且您相当确信您不会很快想要多个应用程序使用您的数据,也不会有多个用户,则您可能会发现更快的方法。

此外,如果您不知道要存储哪种类型的数据以及如何对其进行建模,则关系模型的优势就浪费了。

如果您并不太关心数据的完整性(这也可能是可以接受的),那么可以这样做。

所有数据结构都针对特定的使用场景进行了优化,只有关系型数据库如果被正确建模,才能以语义中立的方式尝试呈现“现实”。那些与关系型数据库有不好经历的人通常没有意识到他们如果使用其他类型的数据模型会遇到更糟糕的情况。恶劣的实现是可能的,尤其是在关系型数据库领域,因为相对容易建立复杂模型,所以你可能会遇到棘手的问题。即使如此,当我尝试想象同样的情况在xml中时,我总感觉更好。

在我看来,关系型模型之所以出色的一个例子是它将复杂度与涉及SQL的问题的简短性之比优化得很好。


12

我建议您访问High Scalability博客,该博客几乎每天都会讨论这个主题,并有很多关于选择分布式哈希等替代RDMBS的项目文章。

简单地说(但非常不完整),并非所有数据都能够以高效的方式转换为表格形式。例如,如果您的数据本质上是一个大词典,则可能存在比纯粹的RDBMS更快的替代方案。尽管如此,这主要是关乎性能问题,如果在一个项目中性能并不是主要问题,而稳定性、一致性和可靠性等方面更为重要,那么当RDBMS是一种更成熟、更发展的方案,并且得到了所有语言和平台的支持以及众多可供选择的解决方案时,我认为深入研究这些技术并没有太大意义。


9
15年前,我曾参与一项信用风险系统的开发(基本上是一个大型树形遍历系统)。我们使用的是在HPUX和Solaris上的Sybase数据库,但性能问题一直困扰着我们。我们聘请了Sybase公司的顾问,他们表示无法解决。后来我们转向了面向对象的数据库(这里是Object Store),获得了约100倍的性能提升(而且编写代码也容易了约100倍)。但这样的情况非常少见——关系型数据库是一个不错的首选。

8
当你的模式变化很大时,使用关系型数据库会很困难。这就是XML数据库或键值对数据库最适合的地方。或者你可以使用IBM DB2,通过单个数据库引擎管理关系数据和XML数据。

1
你有没有任何现实世界的例子可以帮助经验较少的开发人员(比如我)了解这种问题可能何时出现? - J M

3
大约7-8年前,我曾经参与一个网站的开发,但其受欢迎程度超乎我们最初的预期,导致在性能方面出现了问题。由于我们都相对缺乏Web项目方面的经验,我们很难决定除了通常的数据库分离、负载均衡等常规方法之外该如何解决这个问题。
有一天,我想到了一个非常简单的方法。由于网站是基于用户的,他们的个人资料以用户ID、大量信息变量等方式存储在数据库表中,并显示为其他用户可以查看的用户资料页面。我将所有这些数据刷新到一个简单的HTML文件中,它已经准备好作为用户资料页面使用,从而获得了显著的提升 - 基本上是一个高速缓存。我甚至制作了一个系统,当用户编辑其个人资料信息时,它会解析原始HTML文件,进行编辑,然后将HTML刷新回文件系统 - 获得更多提升。
我还使用类似的方法处理用户之间发送的消息。基本上,在我可以让系统完全绕过数据库,避免插入或更新操作的任何地方,我都可以获得显著的提升。这听起来可能很常识化,但这是一个启示性的时刻。这并不是对关系型设置本身的回避,而是完全避免使用数据库- KISS原则。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接