这篇博客文章解释了使用传统文件系统和数据库进行Web开发的问题,并展示了一种更好的方法。
传统文件系统和数据库具有非常不同的属性。传统文件系统最适合存储大型对象,而用于结构化数据的数据库则最适合。传统文件系统具有层次结构(文件夹),数据库具有事务。
这使得Web开发方式比应有的方式复杂。让我们只看一个问题。
当我们谈论图像文件时,将其存储在传统文件系统中是很自然的。不幸的是,传统文件系统不支持事务。正确解决安全问题非常困难。鉴于您不能止步不前,因此要进行一致的备份是一个挑战。不可避免地,在进行备份时,将修改传统文件系统。迟早会导致问题。
数据库可以解决以上所有问题。他们有交易。如果进行备份,则默认情况下可能会保持一致。问题是,数据库对大型对象不利。如果您想为很多用户提供服务,那么它们是一个不好的选择。
这真令人沮丧。为什么我们不能拥有结合了两全其美的存储系统?
让我们退后一步,看看大局。当前如何划分存储数据的问题空间:
例如,存储冰淇淋和水果有冲突的要求。冰淇淋必须冷冻,而冷冻直接损害水果。冰淇淋需要低于零温度,而水果需要高于零温度。那是一场艰苦的冲突。他们需要不同的存储解决方案。
事实是,传统的文件系统和数据库功能没有冲突。或告诉我一个需要以下功能的功能:
网站的某些数据必须受到控制,即只能由网站所有者更改。这包括代码库,页面结构,博客文章内容,一些资产(例如图像和视频),甚至是高度结构化的数据(例如产品功能)。此类数据在生产环境1中不得更改,因为这将意味着您的访问者看到正在进行的更改,甚至可能暂时中断网站。
受控数据应在开发环境中进行编辑,该开发环境应可从生产环境中克隆。它通常需要版本控制和非线性开发(分支和合并)。在将新版本的代码库交付到生产环境后,新状态应替换旧状态。
另一方面,有些变化是无法控制的。这包括评论和网上商店订单之类的用户贡献。它包括自动执行的脚本所做的更改,例如,在午夜重置计数器的脚本。它应包括在处理请求时生成的日志。
不受控制的数据由线性的顺序变化组成,因此需要线性快照而不是非线性特征分支。当出于开发目的而克隆生产环境时,通常还需要克隆不受控制的数据,从而使您可以完全自由地尝试任何事情,而无需复杂的设置过程。这也有助于在最短的时间内重现错误。在将新版本的代码库交付到生产环境后,通常应删除不受控制的数据的新状态,以防止意外覆盖生产中所做的更改。
大多数网站和Web应用程序都需要受控区域和不受控制区域。由于功能不同,传统文件系统和数据库都用于存储两者。
Boomla通过沿着实际冲突的需求削减问题空间,从而提供了从根本上更简单的Web开发体验,从而消除了意外的复杂性:
Boomla根据不同的存储需求提供了单独的文件系统,一个用于受控更改,另一个用于非受控更改。
Boomla文件系统具有类似于具有文件的传统文件系统的树形结构。正如预期的那样,Boomla文件可以存储较大的对象,例如图像和视频。为了存储结构化数据,Boomla文件具有文件属性,可以按键值格式存储自定义的任何内容,类似于具有字段的数据库行。最后,Boomla文件系统是事务性的。
我们已经解决了如何在任何地方都具有对象层次结构,即使在动态文件系统上也是如此,但是如果将其存储为单独的文件系统树,我们将回到平方:全局共享名称空间。相反,我们需要的是能够在静态文件系统上的任意位置附加动态卷的能力,如下所示:
这些动态卷的存在必须受版本控制,但它们的内容不能保持不变,因为它们在不断变化。它们必须以某种方式存储在动态文件系统中。
让我们来看一个例子。想象一下嵌入页面的注释元素。它应具有自己的具有自己模式的动态卷。评论元素的存在必须是版本控制的,而不是实际的评论。它们不可能是:它们会引起持续的合并问题。
删除comment元素本身(或什至是其嵌入的页面)必须删除带有所有相关用户注释的comment元素本身。在传统设置中,您必须自己编写许多代码才能确定需要删除哪些数据。这需要花费时间(金钱),并且在安装了多个第三方插件时可能并不简单。使用正确的封装,系统可以自动为您完成此操作。
这就是它的工作原理。 Boomla文件具有链接属性。您只需将文件的link属性设置为dynamic即可在网站文件系统上的任何位置附加动态卷。
这样,系统将在隐藏的动态文件系统上创建一个新卷并将其映射到链接文件。 (使用链接文件的文件ID。)从那时起,您将能够照常编写动态子树。它看起来就像是您网站的文件系统树的一部分。
这样,在Boomla中,删除包含评论的页面也将删除实际评论。
动态文件系统的根卷在设计上是隐藏的,无法直接访问。如果您有兴趣,请参阅动态链接文档以获取更多详细信息。
Boomla文件系统真正强大的功能之一是整个网站都可以撤消/重做。这让我们尝试。我们可以尝试,我们可以失败,我们可以永远撤销。敢于尝试的巨大动力。
不过有一点警告。在生产环境中,您可能有多个用户进行更改。您绝对不想意外撤消其他人的评论或命令。在生产中加上静态文件系统是只读的,因为您可能不希望访问者看到正在进行的工作。因此,撤消/重做在生产环境(主分支)中不可用。
克隆生产环境并创建开发分支后,撤消/重做将可用于整个网站。对静态和动态文件系统所做的更改捆绑在单个原子事务中,从而创建单个撤消点。这样,无论您进行什么更改,您都可以使用撤消/重做。
换个说法,您根本没有撤消/重做(主分支),或者整个网站都具有撤消/重做(二级分支)。
访问控制只能在可以访问用户和数据的层中实施。否则是不可能的。网站和Web应用程序介绍了自己的用户概念。因此,他们应该承担所有访问控制职责。数据访问应仅通过单个定义良好的层进行。
不幸的是,那没有发生。数据库和底层OS都有自己的用户概念,以及自己的访问控制方法。另外,您选择的CMS或框架也有其自己的用户概念和访问控制机制。应用程序开发人员可以访问所有这些程序。他们必须自己调用所有正确的函数以确保所有内容都是安全的。每个应用程序开发人员都必须是安全专家,并且不能犯错误。
如果您想知道这怎么可能是安全的-不用担心,事实并非如此。这是一场彻底的灾难。 (专业提示:让您的竞争对手使用它。)
通过与网站用户一起在单层中提供单个存储解决方案,Boomla可以集中进行访问控制。最重要的是,它可以强制执行,因此应用程序开发人员无需做额外的工作就可以正确实现。他们不需要成为安全专家。
此外,这种将数据分为静态和动态文件系统的新方法为我们提供了执行安全性的新机会。静态文件系统在生产中可以是只读的,从而可以防止恶意软件注入任何代码。同时,由于动态文件系统是不可信的存储区域,因此可以防止代码在动态文件系统上执行。由于我们使用的是文件系统而不是数据库,因此也消除了SQL注入类型的攻击。
静态工作流不允许协作,您不能将动态卷附加到静态文件系统。
另一方面,您网站的主分支(生产环境)将是可写的,并且撤消/重做将可用。那是旧的工作流程,因此我们将保持它不会破坏现有的用户/网站。
要使用动态文件系统,您将必须启用协作工作流程。让我们看看它有何不同。
假设您要实施新功能或添加新博客文章。您不能在master分支(生产环境)上执行此操作,因此您将创建一个新的开发分支。为此,您可以克隆包含静态文件系统和动态文件系统的master分支。这样,您就可以完全自由地尝试任何东西。如果您在实时网站上发现错误,那么在创建功能分支后该错误仍然存在。唯一的变化是您现在在安全的操场上。
完成修改并满意之后,您可以发布开发分支的静态文件系统。动态文件系统将不会被发布,而是将被删除。这样,您可以自由地实施新的购物车系统,甚至可以试驾几次,而不必担心更改会影响实时库存。
如今,许多开发人员最终都遇到了最糟糕的设置:仅拥有生产数据库并直接在其上运行迁移脚本。这是因为我们必须使用的当前工具使建立完整克隆环境的方式比应该的复杂得多。
动态文件系统目前处于公开测试阶段。我们仍然需要弄清楚如何定价,因为使用它会导致更多的资源匮乏的网站。
传统的文件系统和数据库在错误的维度上缩减了问题空间,带来了许多意外的复杂性,破坏了安全性,并使Web开发变得比原本困难得多。
问题空间应沿着相互矛盾的需求进行切割。对于Web开发,这并不意味着存储系统具有功能,而是对受控更改的要求:必须控制某些数据,而不能完全控制其他数据。
我正在编写一个教程,其中包含几个示例,说明如何使用这种方法来创建简单的协作应用程序。例如,如何存储评论,用户投票和会话数据。
如果您想收到通知,请订阅此页面底部的新闻通讯。
Boomla是一个稳定的,可立即投入生产的Web开发平台,即服务。您可以在Twitter上关注该项目,也可以订阅本页底部的新闻通讯。您也可以注册并浏览它。有很多文档,包括入门视频。我也很乐意提供帮助,随时与您联系!
1)生产环境:您网站的公共版本,也称为master分支。通常,可以在诸如example.com或www.example.com之类的域上访问它。其他环境称为辅助分支或开发分支。