当前位置:  开发笔记 > 编程语言 > 正文

SQL与NoSQL:除了ACID和可扩展性之外的其他问题呢?

如何解决《SQL与NoSQL:除了ACID和可扩展性之外的其他问题呢?》经验,为你挑选了1个好方法。

我最近阅读了很多文章,从两个方面描述了SQL和NoSQL,例如http://use-the-index-luke.com/blog/2013-04/whats-left-of-nosql.这些文章经常涉及ACID和可伸缩性等主题.但是,我通常在SQL中遇到的一些问题似乎很少在这些文章中提及,我想知道为什么,以及这是否与我不完全理解SQL有关.如果有人能够启发我,至少部分是通过以下一项或多项,我将非常感激.

我的SQL问题:

    SQL本质上是不安全的:SQL是一种用于插入的语言,没有任何方法来阻止代码而不是数据的插入.防止插入的唯一方法是使用它将SQL与应用程序完全隔离.为什么SQL本身还没有解决这个问题?

    SQL似乎是针对其中包含的数据可能的最小存储大小而制作的.虽然这仍然对大量数据有很大意义,但它不再适用于较小的数据库,或者它是什么?

    SQL强制所有内容都适合二维关系模型,特定关系表用于执行其他维度.对我来说,这有两个问题:

    数据的一致性完全依赖于关系表

    在失败的情况下,人类很难理解数据

    SQL没有维护历史记录,因为默认情况下它会进行破坏性更新:当然有各种方法来创建历史记录,但这需要使用额外的表格和使用时间戳来自定义编写的东西,或者为此创建新的记录每一次变化,都会导致表格规模呈指数级增长.

    SQL似乎更倾向于丢失数据丢失:如果发生错误或丢失一致性,将情境恢复到一致状态的唯一方法是使用备份,这意味着最新的更改将被销毁.这部分是因为缺乏历史(见4),而且由于缺乏人类可读性,没有真正的方法让人类尝试纠正错误.

    特别是在Web环境中,SQL的使用通常意味着通常不止一次创建模型.在普通(简单)PHP Web应用程序中两次:一次在PHP中,一次在SQL中.在完整堆栈Web应用程序中三次:一次在客户端应用程序中,一次在中间件中,一次在SQL数据库中(如果没有使用ORM).由于编程语言不同,以及它们之间的类型差异,这意味着这些模型之间存在很多可能的冲突.我知道像ActiveRecord和Django这样的ORM解决了这些问题中的至少一部分,但是由于SQL表包含VARCHAR(25)并且没有使用任何语言(JavaScript,Ruby,PHP),您还需要做额外的工作量. ,Perl,Python等)知道那种构造,是巨大的.

    数据结构更改似乎被视为一致性问题:如果数据结构中的某些内容发生更改,表更改将应用​​于该表中的每个现有记录,即使记录最初没有该字段且是否有意义该记录有该字段.一组这些更改会导致自动迁移,这会增加另一层可能出现的问题,尤其是在一致性方面.

    混合存储逻辑和应用程序逻辑:SQL似乎急于将应用程序逻辑的一部分吞噬为存储过程(CouchDB也通过视图执行此操作).虽然我知道对于某些类型的操作,您需要服务器端和非常严格控制的过程,但我不明白为什么它们存储在数据库中并作为存储引擎的一部分,而不是作为应用程序的一部分(中间件).

我知道(但不是很熟悉)像PostgreSQL Hstore这样的东西,但是我并没有完全看到它如何解决上面提到的问题.感谢您的任何见解!



1> Markus Winan..:

    SQL固有的不安全吗?

    我认为你指的是SQL Injections,它是最危险的安全漏洞之一.

    但是,SQL注入主要是教育问题,因为大多数教科书和课程根本不解释绑定参数.当人类直接使用数据库时,将文字值写入SQL语句本身对于即席查询很方便,但这只是程序中的错误方式.程序应始终使用绑定参数(性能极少的例外)有效地保护程序100%不受SQL注入.问题是SQL教科书没有这么说.

    即便如此,SQL也有健全的安全系统,允许您根据某些规则限制对表,视图甚至选定行的访问("行级安全性").

    "可能的最小存储空间"

    对不起,我没有得到那个问题.

    关于规范化.

    你是对的.规范化解决了一些问题(重复数据删除和防止无意的不一致),但打开了其他一些问题.即:

    如何轻松访问许多表中的数据.

    如何在许多表中保持一致性.

    如何应对故意的"不一致"又名.历史(主数据变更)

    原则上,SQL应提供工具来补偿规范化带来的这些挑战.

    应该使用SQL的连接和类似操作来访问许多表中的数据.SQL不仅仅以1:1的方式存储和检索数据,它还提供工具(连接,子查询,集合操作......),将规范化数据转换为最适合特定任务的形式.这是在运行时故意完成的,因为事先不需要知道任务.另一方面,数据的性质被认为是静态的,因此以标准化的方式存储它是有效的.这是关系模型和SQL的一个非常重要的关键概念:数据的性质不会改变,因此它应该是持久的方式.您如何使用这些数据的方式差别很大,并且经常会随着时间而变化 - 因此必须动态完成.这当然是一项非常常规的任务,因此有一个可靠的工具使其变得容易.我们称这个工具为SQL;)DRY规则可以通过使用视图或CTE来完成,但两者都可能损害性能,因为实现没有很好地优化(我公开批评的东西!).

    在许多表中保持数据一致主要是在约束的帮助下完成的.

    SQL:2011最终涵盖了处理预期的"不一致性"(历史):这将允许"AS OF"查询并提供维护时间一致性的工具(例如,一行的有效性可能与另一行的有效性不重叠).可以说,用40年左右的时间来提出解决方案是非常糟糕的.我甚至都不知道这种情况何时会普遍存在!

    我认为这一部分对于每个系统都是如此:"人们很难在失败的情况下理解数据"(我的重点).但是,我认为您可能意味着很难调查问题,因为所需的数据可能分散在多个表中.SQL的答案是:VIEW基本上只是存储的查询.但是,根据数据库带,VIEW可能会引入性能问题.但是,这是一些数据库带的限制,而不是SQL或关系模型的限制.

    保持历史

    我已经在上面提到过(SQL:2011).

    对于每个希望保留历史记录的系统,情况也是如此:"导致表格规模呈指数级增长".虽然我说它"不断增长"而不是"指数级".

    应对它的工具是触发器或ORM.如果你想确保没有人进行"破坏性更新",你可以撤销该表的UPDATE权限(并且还要保留在保存端).

    "更喜欢数据丢失而失去一致性:"

    我发现这是一个有趣的观点.但是,SQL的答案是,您首先要努力避免将错误的数据输入系统.主要通过使用适当的模式,约束+ ACID.通过这种方式,您的陈述在某种程度上是正确的:拒绝接受不一致的数据(这与丢失的东西不同!).因此,您必须在某人输入被拒绝的数据时处理错误,而不是稍后当您尝试解决不一致时,因为您首先接受了错误的数据.所以是的,这就是关系模型和SQL的哲学!

    人类可读性的缺乏显然取决于你的背景.但是,我会说,使用SQL的正确能力非常好.在这里,我还想引用最初的关于SEQUEL的 IBM论文(当时它是它的真实名称):

    SEQUEL旨在作为专业程序员和较不频繁的数据库用户的数据库子语言.

    在我的观察中,这是绝对正确的:我最近有一个教授SQL来支持员工的任务,以便他们可以直接在数据库中调查案例.他们不是程序员,但很快就理解SQL.我认为这里踢出你的"人类"论点:他们遇到的问题是导航一个由数百个表组成的真实世界关系模型.但是,通过要求开发人员为涉及多个表的一些常见任务提供视图,很快就解决了这个问题.加入这些观点就不再是问题了.

    对于关系思维,你需要一个不同的思维模式,你需要一个不同的中间设置到函数式编程.这不是好事或坏事 - 但对你来说可能并不常见.一旦你经常使用它,你就会习惯它.

    对象/关系阻抗不匹配

    我认为这个话题不需要长时间的讨论:是的,它存在,是的,有一些工具以某种方式应对它.我已经在我的文章中提出了过度使用的观点.

    数据结构变化

    我认为这主要是由于对关系模型的理解不足.比较上面:"数据的性质"

    这也是一个讨论得很好的论点:架构与"架构较少".选择你的味道."Schema less"通常仅仅意味着"不提供模式管理工具",但是你必须应对我们有时想要向现有实体添加更多属性的事实.RDBMS为此提供了工具:新列可以为空或具有默认值.可以使用CREATE AS SELECT进行更激烈的更改,例如将一个属性移动到额外的表(例如1:n).您甚至可以提供仍然提供数据的兼容性视图(就像移动的属性仍将存储在表中一样).一旦更改了模式,您的应用程序就可以依赖它的约束(例如列的存在或约束的有效性).这是数据库可以非常可靠地为您做的很多事情.你不再需要关心你的应用程序了.

    您没有提到的一个论点是,这些架构更改通常涉及停机时间.这对过去来说确实如此,在某种程度上也是如此.例如,MySQL最近在5.6中引入了在线ALTER TABLE.但是,这通常是一个实现限制,而不是与关系模型或SQL本质上相关的问题.即使是一些更复杂的更改(例如将属性移动到另一个表)也可以在线完成并仔细计划(我已经完成了一个昂贵的数据库,提供了所需的所有工具).通常,它是关于将迁移代码保留在应用程序之外并使用它来处理数据库.迁移后,您既不应该在数据库中也不应该在应用程序代码中具有迁移工件.当然,有些情况下停机是不可避免的(我认为;).

    "混合存储逻辑和应用程序逻辑"

    SQL实际上完全相反:SQL完全抽象出存储层.

    没有人强迫您使用存储过程.我个人也认为存储过程被过度使用,主要是因为存储过程存储在数据库中,因此可以由可能无法访问其他源代码的数据库管理员进行更改(优化).换句话说:我认为这通常是出于绝望.

    第二个参数当然是再次过度使用ORM以及不允许在应用程序中使用真正SQL的策略.

推荐阅读
yzh148448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有