我最近阅读了很多文章,其中描述了两个方面的SQL和NoSQL,例如http://use-the-index-luke.com/blog/2013-04/whats-left-of-nosql。这些文章经常涉及ACID和可伸缩性等主题。但是,我通常在SQL中遇到的一些问题似乎很少在这些文章中提及,我想知道为什么,以及这是否与我不完全理解SQL有关。如果有人能够启发我,至少部分是基于以下一项或多项,我将非常感激。
我的SQL问题:
我知道(但不是很熟悉)像PostgreSQL Hstore这样的东西,但我并没有完全看到它如何解决上面提到的问题。 感谢您的任何见解!
答案 0 :(得分:19)
SQL固有的不安全吗?
我认为你指的是SQL Injections,这是最危险的安全漏洞之一。
然而,SQL注入主要是教育问题,因为大多数教科书和课程根本不解释bind parameters。将文字值写入SQL语句本身对于人类直接使用数据库时的即席查询非常方便,但这只是程序中的错误方法。程序应始终使用绑定参数(性能极少的例外)有效地保护程序100%不受SQL注入。问题是SQL教科书不能这么说。
即便如此,SQL也有健全的安全系统,允许您根据某些规则限制对表,视图,有时甚至是选定行的访问("行级安全性")。
"可能的最小存储空间"
抱歉,我不明白这个问题。
关于规范化。
你是对的。规范化解决了一些问题(重复数据删除和防止无意的不一致),但打开了其他一些问题。即:
原则上,SQL应提供工具来补偿规范化带来的这些挑战。
应使用SQL的连接和类似操作来访问许多表中的数据。 SQL不仅仅以1:1的方式存储和检索数据,它还提供工具(连接,子查询,集合操作......),将规范化数据转换为最适合特定任务的形式。这是在运行时故意完成的,因为事先不需要知道任务。另一方面,数据的性质被认为是静态的,因此以标准化的方式存储它是有效的。这是关系模型和SQL的一个非常重要的关键概念:数据的 nature 不会发生变化,因此它应该是持久性的。您如何使用这些数据的方式差异很大,并且经常会随着时间而变化 - 因此必须动态完成。这当然是一项非常常规的任务,因此有一个可靠的工具使其变得容易。我们将此工具称为SQL;)DRY规则可以通过使用视图或CTEs来完成,但两者都可能会损害性能,因为实现已经针对该优化进行了优化(我公开批评的事情!)。
在许多表中保持数据一致主要是在约束的帮助下完成的。
处理预期的"不一致" (历史)终于由SQL:2011覆盖:这将允许" AS OF"查询并提供维护时间一致性的工具(例如,一行的有效性可能与另一行的有效性不重叠)。可以说,用40年左右的时间来提出解决方案是非常糟糕的。我甚至都不知道这种情况何时会普遍存在!
我认为这部分对于每个系统都是如此:"人们很难在失败的情况下理解 " (我的重点)。但是,我认为您可能意味着很难调查问题,因为所需的数据可能分散在多个表中。 SQL的答案是:VIEW基本上只是存储的查询。但是,根据数据库带,VIEW可能会引入性能问题。但是,这是一些数据库频段的限制,而不是SQL或关系模型的限制。
保持历史
我已经在上面提到过(SQL:2011)。
对于每个希望保留历史记录的系统,情况也是如此:"导致表格规模呈指数级增长。"虽然我说它不断增长"不是"以指数方式"。
应对它的工具是触发器或ORM。如果你想确保没有人进行过破坏性的更新"你可以撤销该表的UPDATE权限(并且DELETE也在保存方面)。
"更喜欢数据丢失而导致失去一致性:"
我发现这是一个有趣的观点。但是,SQL的答案是,您首先要努力避免将错误的数据输入系统。主要通过使用适当的模式,约束+ ACID。通过这种方式,您的陈述在某种程度上是正确的:而不是接受不一致的数据被拒绝(这与丢失的东西不同!)。因此,您必须在某人输入被拒绝的数据时处理错误,而不是稍后当您尝试解决不一致时,因为您首先接受了错误的数据。是的,这是关系模型和SQL的哲学!
缺乏人类可读性显然取决于您的背景。但是,我说,使用SQL的正确能力非常好。在这里,我还想引用最初的IBM论文SEQUEL(当时它是它的真实名称):
SEQUEL旨在为专业程序员和不常见的数据库用户提供数据库子语言。
在我的观察中,这是绝对正确的:我最近有一个教授SQL来支持员工的任务,以便他们可以直接在数据库中调查案例。他们不是程序员,但很快就理解SQL。而且我认为在这里踢你的"人类"参数:他们遇到的问题是导航一个由数百个表组成的真实世界关系模型。但是,通过要求开发人员为涉及多个表的一些常见任务提供视图,很快就解决了这个问题。加入这些观点就不再有问题了。
对于关系思维,你需要一个不同的思维模式,你需要一个不同的中间集来进行函数式编程。这不是好事或坏事 - 但对你来说可能并不常见。一旦你经常使用它,你就会习惯它。
对象/关系阻抗不匹配
我认为这个话题不需要长时间的讨论:是的它存在,是的,有些工具可以用某种方式处理它。我已经在我的文章中提出了过度使用的观点。
数据结构更改
我认为这主要是由于对关系模型的理解不足。比较上面:"数据的性质"
这也是一个讨论得很好的论点:架构与"架构较少"。选择你的味道。 " Schema less"通常只是意味着"没有提供架构管理工具"然而,你必须应对这样一个事实,即我们有时想要为现有实体添加更多属性。 RDBMS为此提供了工具:新列可以为空或具有默认值。可以使用CREATE AS SELECT进行更激烈的更改,例如将一个属性移动到额外的表(例如1:n)。您甚至可以提供仍然提供数据的兼容性视图(就像移动的属性仍将存储在表中一样)。一旦您更改了架构,您的应用程序就可以依赖它的约束(例如列的存在或约束的有效性)。数据库可以以非常可靠的方式为您做很多事情。你不再需要关心你的应用程序了。
您没有提到的一个论点是,这些架构更改通常涉及停机时间。这对过去来说确实如此,在某种程度上也是如此。例如。 MySQL最近在5.6中引入了在线ALTER TABLE。但是,这通常是一个实现限制,而不是与关系模型或SQL本身相关的问题。即使是一些更复杂的更改(例如将属性移动到另一个表)也可以在线完成并仔细规划(我已经完成了一个昂贵的数据库,提供了所需的所有工具)。通常,它是关于将迁移代码保留在应用程序之外并使用它来处理数据库。迁移后,您既不应该在数据库中也不应该在应用程序代码中具有迁移工件。当然,有些情况下停机是不可避免的(我认为;)。
"混合存储逻辑和应用程序逻辑"
SQL实际上完全相反:SQL完全取消了存储层。
没有人强迫您使用存储过程。我个人也认为存储过程被过度使用,主要是因为存储过程存储在数据库中,因此可以由可能无法访问其他源代码的数据库管理员进行更改(优化)。换句话说:我认为这通常是出于绝望。
第二个论点当然是再次过度使用ORM以及禁止在应用程序中使用真实SQL的策略。
答案 1 :(得分:3)