Sails 附带一个强大的 ORM/ODM,名为 Waterline,这是一个与数据存储无关的工具,它极大地简化了与一个或多个数据库的交互。它在底层数据库之上提供了一个抽象层,使您可以轻松地查询和操作数据,而无需编写特定于供应商的集成代码。
在像 Postgres、Oracle 和 MySQL 这样的模式数据库中,模型由表表示。在 MongoDB 中,它们由 Mongo "集合" 表示。在 Redis 中,它们使用键值对表示。每个数据库都有其独特的查询语法,在某些情况下甚至需要安装和编译特定的本地模块才能连接到服务器。这涉及大量的开销,并产生了一种令人不安的 供应商锁定 到特定数据库;例如,如果您的应用程序使用大量 SQL 查询,那么以后很难切换到 Mongo,或者 Redis,反之亦然。
Waterline 查询语法浮动在所有这些之上,专注于业务逻辑,例如创建新记录、获取/搜索现有记录、更新记录或销毁记录。无论您联系的是什么数据库,使用方式都是完全相同的。此外,Waterline 允许您 .populate()
模型之间的关联,即使每个模型的数据都位于不同的数据库中。这意味着您可以将应用程序的模型从 Mongo 切换到 PostgreSQL,再切换到 MySQL,然后再切换回来,只需进行最小的代码更改。对于需要低级、特定于数据库的功能的情况,Waterline 提供了一个查询接口,允许您直接与模型的底层数据库驱动程序对话(请参阅 .query() 和 .native())。
假设您正在构建一个电子商务网站,以及一个配套的移动应用程序。用户按类别浏览产品或按关键词搜索产品,然后购买它们。就是这样!应用程序的某些部分非常普通:您有一个基于 API 的流程用于登录、注册、订单/支付处理、重置密码等。但是,您知道路线图中潜伏着一些平凡的功能,这些功能可能会变得更加复杂。果不其然
您询问业务方他们想使用哪个数据库
"数据... 什么?不要操之过急,不想做出错误的选择。我会让运维/IT 部门来处理。尽管开始吧."
为 Web 应用程序/API 选择单个数据库的传统方法实际上对于某些生产用例来说是禁止的。虽然大多数应用程序可以使用一种类型的数据库,但有些应用程序需要与现有数据集保持兼容,或者(如果您正在开发一个高流量的生产应用程序)出于性能原因使用不止一种类型的数据库。
由于 Sails 默认情况下使用 sails-disk
,因此您可以从零配置开始构建应用程序,使用本地临时文件作为存储。当您准备好切换到真实的东西(以及当每个人都知道那是什么时),只需更改应用程序的 数据存储配置。
产品负责人/利益相关者走到你身边说
"哦,顺便说一下,该产品实际上已经在我们的销售点系统中上线了。我猜是某种 ERP 系统,类似于 "DB2"?无论如何,我相信你会搞定的。听起来很容易吧?"
许多企业应用程序必须与现有数据库集成。如果您幸运的话,可能只需进行一次数据迁移即可,但更常见的情况是,现有数据集仍在由其他应用程序修改。为了构建您的应用程序,您可能需要将来自多个遗留系统的数据,或与存储在其他地方的单独数据集结合起来。这些数据集可能位于分散在世界各地的五台不同的服务器上!一台托管的数据库服务器可能包含一个带有关系数据的 SQL 数据库,而另一台云服务器可能包含几个 Mongo 或 Redis 集合。
Sails/Waterline 允许您将不同的模型连接到不同的数据存储,无论是在本地还是互联网上的任何地方。您可以构建一个映射到遗留数据库中自定义 MySQL 表的 User 模型(具有奇怪的疯狂列名)。同样,对于映射到 DB2 中表的 Product 模型,或映射到 MongoDB 集合的 Order 模型也是如此。最棒的是,您可以在这些不同的数据存储和适配器之间进行 .populate()
,因此如果您将模型配置为驻留在不同的数据库中,您的控制器/模型代码不需要更改(请注意,您需要手动迁移任何重要的生产数据)。
您深夜坐在笔记本电脑前,突然意识到
"我该怎么进行关键词搜索?产品数据没有任何关键词,而业务方希望搜索结果根据 n-gram 词序列进行排名。此外,我不知道这个推荐引擎将如何运作。此外,如果我今晚再听到一次 "大数据" 这个词,我就辞职回到咖啡馆工作."
那么 "大数据" 呢?通常,当您听到博主和分析师使用这个流行语时,您会想到数据挖掘和商业智能。您可能会想象一个从多个来源提取数据的过程,对其进行处理/索引/分析,然后将提取的信息写入其他地方,要么保留原始数据,要么将其丢弃。
但是,还有一些更常见的挑战适合使用相同的索引/分析需求:例如,像 "驾驶方向距离" 搜索这样的功能,或与相关产品的推荐引擎。幸运的是,许多数据库简化了特定的大数据用例。例如,MongoDB 提供了地理空间索引,而 ElasticSearch 为索引数据以进行全文搜索提供了极好的支持。
以预期的方式使用数据库会带来巨大的性能优势,特别是在复杂报表查询、搜索(实际上只是定制排序)以及 NLP/机器学习方面。某些数据库非常擅长回答传统的关联业务查询,而另一些数据库更适合用于数据的地图/简化式处理,并且针对超快的读写操作进行优化和权衡。随着应用程序用户群的扩展,这种考虑尤其重要。
像大多数 MVC 框架一样,Sails 支持 多个数据库。这意味着查询和操作数据的语法始终相同,无论我们使用的是 MongoDB、MySQL 还是任何其他支持的数据库。
Waterline 基于这种灵活性,提出了其适配器概念。适配器是一段代码,它将像 find()
和 create()
这样的方法映射到更低级的语法,例如 SELECT * FROM
和 INSERT INTO
。Sails 核心团队维护着针对 最流行的数据库 的开源适配器,以及大量 社区适配器 也可用。
自定义 Waterline 适配器实际上 非常容易构建,并且可以实现更可维护的集成:从专有的企业帐户系统到缓存,再到传统的数据库。
数据存储代表特定的数据库配置。此配置对象包含要使用的适配器,以及主机、端口、用户名、密码等信息。数据存储在 Sails 配置 config/datastores.js
中定义。
// in config/datastores.js
// ...
{
adapter: 'sails-mysql',
host: 'localhost',
port: 3306,
user: 'root',
password: 'g3tInCr4zee&stUfF',
database: 'database-name'
}
// ...
想象一个装满已完成的笔迹表格的文件柜。所有表格都具有相同的字段(例如 "姓名"、"出生日期"、"婚姻状况"),但对于每个表格,字段中填写的值都不同。例如,一个表格可能包含 "Lara"、"2000-03-16T21:16:15.127Z"、"单身",而另一个表格可能包含 "Larry"、"1974-01-16T21:16:15.127Z"、"已婚"。
现在想象您经营着一个热狗生意。如果您非常有条理,您可以按以下方式设置您的文件柜
fullName
hourlyWage
phoneNumber
streetAddress
city
state
zipcode
purchases
manager
madeAtLocation
productsPurchased
createdAt
nameOnMenu
price
numCalories
percentRealMeat
availableAt
在您的 Sails 应用程序中,模型就像一个文件柜。它包含记录,这些记录就像表格一样。属性
就像每个表格中的字段。