为什么使用SQL数据库?

我不是很确定stackoverflow是一个这样一个普遍的问题的地方,但让我们试试看。

由于需要将应用程序数据存储在某个地方,我总是使用MySQL或sqlite,只是因为它总是这样做的。 由于整个世界似乎都在使用这些数据库(大部分是软件产品,框架等),像我这样的开始开发者开始考虑这是否是一个好的解决scheme是相当困难的。

好的,比方说,我们在应用程序中有一些面向对象的逻辑,而且对象是以某种方式相互关联的。 我们需要将这个逻辑映射到存储逻辑,因此数据库对象之间的关系也是必需的。 这导致我们使用关系型数据库,并且我确定 – 简单地说,我们的数据库表行有时需要引用其他表的行。 但为什么使用SQL语言与这样的数据库进行交互呢?

SQL查询是一条文本消息。 我可以理解,这对于真正理解它的作用是很酷的,但是对于应用程序的一部分,在部署之后没有人看到使用文本表和列名是不是很愚蠢? 如果您必须从头开始编写数据存储,您将永远不会使用这种解决scheme。 就个人而言,我会使用一些“编译数据库查询”字节码,这将在客户端应用程序内汇编一次,并传递到数据库。 它肯定会通过id号命名表和冒号,而不是ASCIIstring。 在表结构变化的情况下,这些字节查询可以根据新的数据库模式重新编译,存储在XML或类似的东西。

我的想法有什么问题? 我有什么理由不自己写,而是使用SQL数据库呢?

编辑为了让我的问题更清楚。 大多数答案都声称SQL是一个文本查询,可以帮助开发人员更好地理解查询本身并更轻松地进行debugging。 就个人而言,我还没有看到人们用手写SQL查询一段时间。 包括我在内的每个人都在使用ORM。 这种情况下,我们build立了一个新的抽象层来隐藏SQL,导致思考我们是否需要SQL。 我将非常感谢,如果你可以给一些例子,其中SQL没有故意使用ORM,为什么。

EDIT2 SQL是人与数据库之间的接口。 问题是为什么我们必须使用它来进行应用程序/数据库交互? 我仍然要求人类编写/debuggingSQL的例子。

如果你只需要在某个地方存储一些应用程序的数据,那么通用的RDBMS甚至SQLite就可能是过度的。 在某些情况下,序列化对象并将它们写入文件可能会更简单。 SQLite的一个好处是,如果你有很多这样的信息,它都包含在一个文件中。 缺点是阅读起来比较困难。 例如,如果您将数据序列化到YAML,则可以使用任何文本编辑器或shell来读取文件。

就个人而言,我会使用一些“编译数据库查询”字节码,这将在客户端应用程序内汇编一次,并传递到数据库。

这是一些数据库API的工作原理。 检出静态SQL和准备语句。

我有什么理由不自己写,而是使用SQL数据库呢?

如果你需要很多function,在某些时候,使用现有的RDMBS然后从头开始编写你自己的数据库会更容易。 如果你不需要很多function,更简单的解决scheme可能会更明智。

数据库产品的重点是避免为每个新程序编写数据库层。 是的,现代的RDMBS可能并不总是完美适合每个项目。 这是因为它们被devise得非常一般,所以在实践中,你总能得到你不需要的附加function。 这并不意味着最好有一个自定义的解决scheme。 手套并不总是需要一个完美的配合。

更新:

但为什么使用SQL语言与这样的数据库进行交互呢?

好问题。

对于这个问题的答案可以在IBM公司于1970年由EF Codd描述的关于“大型共享数据库的数据关系模型”的原始论文中find。本文描述了现有数据库技术存在的问题,并解释了为什么关系模型是优越的。

使用关系模型的原因,也就是像SQL这样的逻辑查询语言是数据独立的。

数据独立性在本文中定义为:

“…应用程序和terminal活动的独立性来自数据types的增长和数据表示的变化”。

在关系模型之前,数据库的主导技术被称为networking模型。 在这个模型中,程序员必须知道数据的磁盘结构并手动遍历树或图。 关系模型允许用户针对与磁盘上的数据的物理表示无关的概念或逻辑scheme编写查询。 逻辑scheme与物理模式的分离是为什么我们使用关系模型。 有关此问题的更多信息,请参阅数据库类的一些幻灯片。 在关系模型中,我们使用基于逻辑的查询语言(如SQL)来检索数据。 Codd的论文更详细地介绍了关系模型的好处。 给它一个阅读。

SQL是一种查询语言,与在研究论文中通常使用的查询语言形成对比,很容易input到计算机中。 研究论文通常使用关系代数或关系演算来编写查询。

总而言之,我们使用SQL是因为我们碰巧为我们的数据库使用了关系模型。

如果你理解了关系模型,就不难理解为什么SQL是这样的。 所以基本上,你需要更深入地研究关系模型和数据库内部,才能真正理解我们为什么要使用SQL。 否则这可能有点神秘。

更新2:

SQL是人与数据库之间的接口。 问题是为什么我们必须使用它来进行应用程序/数据库交互? 我仍然要求人类编写/debuggingSQL的例子。

因为数据库是一个关系数据库,所以它只能理解关系查询语言。 在内部,它使用关系代数(如语言)来指定查询,然后将其转换为查询计划。 所以,我们用我们可以理解的forms(SQL)编写我们的查询,DB接受我们的SQL查询并将其转换为其内部查询语言。 然后它采取查询,并试图find一个“查询计划”执行查询。 然后执行查询计划并返回结果。

在某些情况下,我们必须以数据库可以理解的格式对查询进行编码。 数据库只知道如何将SQL转换为其内部表示,这就是为什么在链中某处总是存在SQL的原因。 这是无法避免的。

当你使用ORM时,你只需要在SQL的顶部添加一个图层。 SQL仍然存在,它只是隐藏。 如果你有一个更高层的翻译你的请求到SQL,那么你不需要直接写SQL,这在某些情况下是有益的。 有时候我们没有这样一个能够做我们需要的查询的层,所以我们必须使用SQL。

包括我在内的每个人都在使用ORM

奇怪。 我认识的每个人,包括我,仍然手写大部分的SQL。 通常情况下,结果会比生成的解决scheme更紧密,性能更高。 而且,根据您的行业和应用,这个速度重要的。 有时很多。 是的,我有时会使用LINQ来实现一个快速的n-dirty,在那里我并不关心结果SQL是什么样的,但是到目前为止,还没有什么能自动完成手工调整的SQL,负载环境真的很重要。

鉴于你使用MySQL和SQLite的事实,我完全理解你的观点。 大多数数据库pipe理系统都有这样的function,当你从数据库中免费获得这些function时,

  • 索引 – 您可以存储大量数据,并且由于索引而仍然能够非常快速地进行筛选和search。 当然,你可以实现你自己的索引,但为什么重新发明轮子

  • 数据完整性 – 使用级联外键等数据库function可以确保整个系统的数据完整性。 你只需要声明数据之间的关系,系统负责其余的部分。 当然,再一次,你可以在代码中实现约束,但是更多的工作。 例如,考虑删除,在那里你必须在对象的析构函数中编写代码来跟踪所有的依赖对象并相应地进行操作

  • 能够使用不同的编程语言编写多个应用程序,可以在不同的操作系统上工作,有些应用程序甚至可以分布在整个networking上

  • 通过触发器简单地实现了观察者模式 。 有很多情况下,只有一些数据依赖于其他一些数据,并不会影响应用程序的UI方面。 确保一致性可能非常棘手或需要大量编程。 当然,你可以用对象来实现类似触发器的行为,但是它需要比简单的SQL定义更多的编程

这里有一些很好的答案。 我会尝试增加我的两分钱。

我喜欢SQL,我可以很容易地想到它。 数据库顶层的查询(如ORM框架)通常是可怕的。 他们会select多余的东西,join你不需要的东西等。 全部是因为他们不知道你只需要这个代码中的一小部分对象。 当你需要高性能的时候,你最终会在ORM系统中至less使用一些自定义的SQL查询来加速一些瓶颈。

为什么SQL? 正如其他人所说,人类很容易。 它是一个很好的最低公分母。 任何语言都可以在必要时创buildSQL和调用命令行客户端,而且它们几乎总是一个好的库。

parsing出SQL效率低下吗? 有些。 语法是相当结构化的,所以没有太多的歧义,会使parsing器的工作非常困难。 真正的事情是parsing出SQL的开销基本上是没有的。

假设你运行一个类似于“SELECT x FROM table WHERE id = 3”的查询语句,然后用4和5重复执行。 在这种情况下,parsing开销可能存在。 这就是为什么你准备好了陈述(正如其他人所说的那样)。 服务器parsing查询一次,并且可以在3和4和5中交换,而不必重新分析所有内容。

但这是一个微不足道的例子。 在现实生活中,您的系统可能会join6个表格,并且必须提取数十万条logging(如果不是更多)。 这可能是一个查询,你让它在一个数据库集群上运行几个小时,因为这是在你的情况下做事情的最好方法。 即使执行只需要一两分钟的查询,parsing查询的时间也相对于将logging从磁盘中拉出并进行sorting/聚合等等来说基本上是免费的。 与发送特殊编码字节0x3F相比,发送外部“LEFT OUTER JOIN ON”的开销仅为几个字节。 但是当你的结果集为30 MB(更不用说gigs +)时,那些less量的额外字节是没有价值的,而不必惹一些特殊的查询编译器对象。

许多人在小型数据库上使用SQL。 我最大的一个参与者只有几十个演出。 从小文件(如小SQLite数据库可能)到大小为TB的Oracle群集,SQL都被使用。 考虑到它的威力,它实际上是一个令人惊讶的简单而小巧的命令集。

  • 这是一个无处不在的标准。 几乎所有的编程语言都有访问SQL数据库的方法。 尝试使用专有的二进制协议。
  • 大家都知道。 您可以轻松find专家,新开发人员通常会在一定程度上了解它,而无需进行培训
  • SQL与关系模型关系非常密切,关于优化和可伸缩性已经被彻底探索。 但是它仍然经常需要手动调整(索引创build,查询结构等),由于文本界面这相对容易。

但为什么使用SQL语言与这样的数据库进行交互呢?

我认为这是出于同样的原因,你使用人类可读的(源代码)语言与编译器交互。

就个人而言,我会使用一些“编译数据库查询”字节码,这将在客户端应用程序内汇编一次,并传递到数据库。

这是数据库的现有(可选)function,称为“存储过程”。


编辑:

我将非常感谢,如果你可以给一些例子,其中SQL没有故意使用ORM,为什么

当我实现自己的ORM时,我使用ADO.NET实现了ORM框架:使用ADO.NET包括在其实现中使用SQL语句。

是的,编写SQL语句来存储和检索对象是很烦人的。

这就是为什么微软将LINQ(语言集成查询)等东西添加到C#和VB.NET中,以便使用对象和方法而不是string查询数据库成为可能。

大多数其他语言根据语言的能力有不同的成功水平。

另一方面,了解SQL是如何工作是非常有用的,我认为完全屏蔽它是错误的。 如果您不使用数据库,则可能会写入效率极低的查询并错误地为数据库编制索引。 但是,一旦您了解了如何正确使用SQL并调整了您的数据库,您就拥有一个非常强大的久经考验的工具,可以快速准确地find所需的数据。

在所有的编辑和评论之后,你的问题的主要观点似乎是:为什么SQL更接近作为人类/数据库接口而不是作为应用程序/数据库接口?

这个问题的简单回答是:因为这正是它最初的目的。

SQL(QUEL大概是最重要的)的前身是打算完全是这样的:一种QUERY语言,即没有任何INSERT,UPDATE,DELETE的语言。

此外,如果用户知道数据库的逻辑结构,并且显然知道如何使用他正在使用的查询语言来表示逻辑结构,那么它就是一种可供任何用户使用的查询语言。

QUEL / SQL背后的原始思想是,数据库是使用“任何可能的机制”构build的,“真正的”数据库实际上可以是任何东西(例如,一个巨大的XML文件 – allthough'XML'不被认为是一个有效的选项当时),而且会有“某种机器”来理解如何将这个“任何东西”的实际结构转换为SQL用户所感知的逻辑关系结构。

事实上,为了实现这个目标,需要潜在的结构让他们“关注地看待它们”,在那些日子里,和现在一样,他们的理解也不是很好。

我最大的原因是SQL是Ad-hoc报告。 这报告您的业务用户想要的,但不知道他们还需要它。

SQL是DBMS平台使用的通用接口 – 接口的全部要点是可以在不需要补充API调用的情况下在SQL中指定所有数据库操作。 这意味着系统的所有客户端都有一个共同的界面 – 应用程序软件,报告和即席查询工具。

其次,随着查询变得越来越复杂,SQL变得越来越有用。 尝试使用LINQ根据存在谓词和基于子查询中计算的聚合的条件来指定具有三个条件的12路连接a。 这种事情在SQL中是很容易理解的,但在ORM中不太可能。

在许多情况下,一个ORM将执行你想要的95% – 应用程序发出的大多数查询都是简单的CRUD操作,ORM或其他通用数据库接口机制可以轻松处理。 一些操作最好使用自定义SQL代码完成。

但是,ORM并不是数据库接口的全部和terminal。 福勒公司的企业应用架构模式在其他types的数据库访问策略方面有相当多的章节,并对各自的优点进行了一些讨论。

通常有很好的理由不使用ORM作为主数据库接口层。 一个很好的例子就是像ADO.Net这样的平台数据库通常能够完成足够好的工作,并且与其他环境很好地集成。 您可能会发现使用其他界面所带来的收益并不会超过集成的好处。

但是,不能真正忽略SQL的最终原因是,如果您正在执行数据库应用程序,那么您最终将使用数据库。 有很多关于商业应用程序代码搞不清楚数据库的WTF故事。 糟糕的数据库代码可能会在很多方面造成麻烦,并且轻率地认为你不需要了解数据库pipe理系统是如何工作的,这种做法肯定会让你有一天会来咬你的。 更糟糕的是,它会来咬一些inheritance你的代码的可怜的学生。

当我明白你的观点时,SQL的查询语言就有了一席之地,特别是在大量数据的应用程序中。 并指出显而易见的,如果语言不在那里,你不能称之为SQL(结构化查询语言)。 使用SQL而不是你描述的方法的好处是SQL通常是非常可读的,尽pipe一些真正推动了他们查询的限制。

我完全同意马克·拜尔斯的观点,你不应该屏蔽自己的SQL。 任何开发人员都可以编写SQL,但要真正使您的应用程序在SQL交互中运行良好,理解语言是必须的。

如果你所描述的每件事情都是用字节码进行预编译的,那么在原始开发者离开之后(甚至在6个月内没有看到代码)之后,我就不得不debugging应用程序了。

我认为这个问题的前提是不正确的。 该SQL可以表示为文本是不重要的。 大多数现代数据库只会编译一次查询并caching它们,所以你已经有了一个“编译的字节码”。 尽pipe我不确定是否有人做了这件事,但没有理由不这样做。

你说SQL是一个短信,我想他是一个信使,而且,正如我们所知,不要把信使射杀。 真正的问题是,关系不是组织现实世界数据的好方法。 SQL只是猪的口红。

SQL是人与数据库之间的接口。 问题是为什么我们必须使用它来进行应用程序/数据库交互? 我仍然要求人类编写/debuggingSQL的例子。

我使用sqlite从最简单的任务(如将日志logging直接logging到sqlite数据库)转换为日常研究中更复杂的分析和debugging任务。 在表格中放置我的数据并编写SQL查询以有趣的方式将它们embedded到这些情况中似乎是最自然的事情。

关于为什么它仍被用作应用程序/数据库之间的接口,这是我的简单推理:

  1. Codd关于“关系代数”的开创性论文从1970年开始,在那个领域进行了大约3-4年的严肃研究。 关系代数构成了SQL(和其他QL)的math基础,尽pipeSQL并不完全遵循关系模型。

  2. 语言的“文本”forms(除了易于人们理解之外)也可以通过机器(比如使用类似于lex的语法分析器)轻松parsing,并且可以使用任意数量的优化轻松地转换为任何“字节码”。

  3. 我不确定以其他方式做这件事是否会在一般情况下产生令人瞩目的好处。 否则,它可能会在三十年的研究中被发现和采用。 在弥合人类/数据库和应用程序/数据库之间的鸿沟时,SQL可能提供了最佳的折衷。

然后问一个有趣的问题是:“以任何其他”非文本“的方式进行SQL的真正好处是什么? 将谷歌现在这个:)

如果第一部分你似乎指的是什么通常被称为对象 – 关系映射阻抗。 已经有很多框架来缓解这个问题。 还有tradeofs。 有些事情会更容易些,其他的会变得更加复杂,但是在一般情况下,如果你能负担得起额外的层面,他们工作得很好。

在第二部分中,您似乎抱怨SQL是文本(它使用string而不是ids等)… SQL是查询语言 。 任何旨在被人类阅读或书写的语言 (计算机或其他)都是面向文本的。 大会,C,PHP,你的名字。 为什么? 因为,那么……这是有道理的,不是吗?

如果你想要预编译查询,你已经有了存储过程。 编写的声明也是即时编译的,IIRC。 大多数(如果不是全部的话)数据库驱动程序总是使用二进制协议与数据库服务器通信。

是的,文本有点低效。 但实际上获取数据的成本要高得多,所以基于文本的sql是相当不重要的。

创buildSQL是为了提供一个接口来对关系数据库进行即席查询。

一般来说,大多数关系数据库都理解某种forms的SQL。

面向对象的数据库存在,并(可能)使用对象来做他们的查询…但据我所知,面向对象数据库有更多的偷听,关系数据库工作得很好。

关系数据库还允许您在“断开”状态下运行。 一旦获得了所要求的信息,就可以closures数据库连接。 使用面向对象的数据库,您可能需要返回与当前相关的所有对象(以及与之相关的对象…以及…等等),或者重新打开连接以检索新对象,因为它们是访问。

除SQL外,还有ORM(对象关系映射),可将对象映射到SQL并返回。 其中包括LINQ(.NET),MSentity framework(.NET),Hibernate(Java),SQLAlchemy(Python),ActiveRecord(Ruby),Class :: DBI(Perl)等等。 。

数据库语言非常有用,因为它为您的数据提供了独立于使用它的任何应用程序的逻辑模型。 然而,SQL有很多缺点,其中最重要的是它与其他语言的集成很差,types支持比业内其他行业差30年左右,而且从来都不是真正的关系语言。

SQL的存活主要是因为数据库市场一直以来仍然受到三大巨头的支配,这三大巨头有保护投资的既得利益。 这种情况正在发生变化,SQL的日子可能还有很多,但最终会取而代之的模式可能还没有到来 – 尽pipe现在有很多竞争者。

我想大多数人都不明白你的问题,尽pipe我觉得这很清楚。 不幸的是我没有“正确”的答案。 我想这是几件事情的组合:

  1. 当它被devise为半任意的决定,如易用性,不需要SQL编译器(或IDE),可移植性等。
  2. 它发生了碰巧(可能是由于类似的原因)
  3. 而现在由于历史原因(兼容性,众所周知,久经考验等)继续被使用。
  4. 我不认为大多数公司都对另一个解决scheme感到困扰,因为它运行良好,不是一个瓶颈,这是一个标准,等等,等等。

Unixdevise原则之一可以这样说:“编写处理文本stream的程序,因为这是一个通用接口。”

我相信这就是为什么我们通常使用SQL而不是一些只有编译接口的“byte-SQL”。 即使我们有一个字节SQL,有人会写一个“文本SQL”,循环将完成。

另外,MySQL和SQLite的function不如MSSQL和Oracle SQL。 所以你仍然在SQL池的低端。

实际上有一些非SQL数据库(如Objectivity,Oracle Berkeley DB等)产品来了,但没有成功。 将来如果有人发现SQL的直观替代scheme,这将回答你的问题。

有很多非关系数据库系统。 这里只有几个: Memcached 东京内阁

至于find一个不使用SQL作为主接口的关系数据库,我认为你不会find它。 原因:SQL是讨论关系的好方法。 我无法弄清楚为什么这对你来说是个大问题:如果你不喜欢SQL,那就把它抽象一下(比如ORM),这样你就不用担心了。 让抽象担心它。 它让你到同一个地方。

然而,你这里真正提到的问题是对象关系的断开 – 问题在于关系本身。 对象和关系元组并不总是适合1-1关系,这就是为什么开发人员可能对数据库感到沮丧的原因。 解决scheme是使用不同的数据库types。

因为经常,你不能确定(引用你) “部署后没有人见过” 。 知道报告和数据集级别查询有一个简单的界面是您的应用程序进化的好path。
你是对的,还有其他解决scheme可能在某些情况下是有效的:XML,纯文本文件,OODB …
但是拥有一组通用接口(如ODBC)对于数据的生命来说是一个巨大的优势。

我认为原因可能是sql laungage连接到的search/查找/抓取algorithm。 请记住,SQL已经发展了40年 – 而且目标是明智和用户明智的。

问问你自己,寻找2 attibutes的最好方法是什么。 现在为什么要调查每次你想要做什么,包括每次你开发你的应用程序。 假设主要目标是在开发应用程序时开发应用程序。

应用程序与其他应用程序有相似之处,数据库与其他数据库有相似之处。 所以应该有一个“最好的方式”来进行交互,逻辑上。

也问问你自己,你将如何开发一个更好的控制台应用程序,不使用sql laungage。 如果你不能做到这一点,我认为你需要开发一种新的graphics用户界面(GUI),这种graphics用户比使用控制台更容易使用 – 从中​​开发出来。 而这可能实际上是可能的。 但是大多数应用程序的开发仍然基于控制台和打字。

那么当涉及到龙舌兰,我不认为你可以做一个比sql更基本更简单的文字强壮。 请记住,任何事物的每个词都与其含义有很大的关系 – 如果你删除了这个词的含义,那么这个词就不能被使用 – 如果你删除了这个词,你就不能传达这个词的含义。 你没有什么可以用它来形容的(也许你甚至不能认为它不会与你以前想过的其他东西联系起来)。

所以基本上,将最好的数据库操作algorithm分配给单词 – 如果删除这些单词,则必须将这些操作分配给其他单词 – 那会是什么?

我认为你可以使用ORM

当且仅当你知道sql的基础。

否则结果不是最好的