使用DynamoDB打造应用,看“好奇号”在火星找到了什么?
ztj100 2025-01-02 20:34 21 浏览 0 评论
DynamoDB是一个高效而灵活的NoSQL数据库服务,它的主要特色就是便于管理,因此使用者不必担心各种管理方面的任务负担,例如操作和扩展数据库等等。使用者可以更关注于应用程序的设计,并且在通过几个简单的步骤后将其发布到DynamoDB服务上。
在本文中,我们将为你展示如何使用Amazon DynamoDB创建一个应用程序。
火星探测器应用程序
我们在本文中所讲述的示例应用将为读者展示DynamoDB数据库的强大功能。这一web应用展现了NASA向公众开放的数据,即好奇号火星探测器(Curiosity Mars Rover)从火星所发回的图像,以及用JSON格式描述的图像元数据。以下是NASA JSON数据的一个小片段,以及该示例应用的一张屏幕截图。
火星探测器示例应用的屏幕截图
你也可以长按扫描二维码,自己尝试一下在线的示例应用!
在这个示例应用上线之前,我们特意收集了NASA的所有数据,所上图所示。并把所有图片的JSON数据都导入到一张DynamoDB表中,为将来查询做准备。在所有数据都导入DynamoDB之后,我们对数据表进行了大量的查询与更新,才最终得到了这个火星探测器应用。
该应用程序的默认视图是来自于好奇号的摄像头、或摄像仪器中所返回的所有图像的时间线,以时间顺序倒序排列。用户可以投票选出他们最喜欢的图片,每张图片的投票数量都是实时维护的。此外,用户可以打开“任务控制”侧边菜单,以改变所使用的摄像仪器、时间范围、或是根据投票数量对图片进行排序。最好,用户也可以在“我的最爱”选项中查看所有投过票的图片。
以上所有这些特性的实现,都是通过对存储了图片数据的DynamoDB表进行查询而实现的。为了创建这样一个应用程序,你通常需要考虑多种功能组件,例如访问控制、用户追踪、数据序列化/反序列化,等等。我们将通过对创建火星控制器这一示例的解释,为你展现用DynamoDB实现以上这些功能是多么简单,并且你也可以使用DynamoDB创建你自己的应用程序!不过,在我们深入讲解这个示例之前,让我们先快速地了解一下DynamoDB。
数据模型
DynamoDB的数据模型概念中包含了表、项目和属性。一张表是一系列项目的集合,而每个项目又是一系列属性的集合。
与关系型数据库不同,DynamoDB是一种无schema的NoSQL数据库。一张DynamoDB表中的每个项目都可以拥有不同数量的属性。每个项目中的属性是一个键-值对。每个属性既可以是单值的,也可以是多值的集合,稍后将讨论数据类型的细节。此外,最近发布的JSON文档支持功能允许JSON对象以项目的形式直接保存在DynamoDB中,最大可达每个项目400KB。举例来说,NASA以JSON对象的方式提供火星探测器传回的每张图片,因此每张图片都能够保存为DynamoDB中的一个独立的项目,而地点和时间等属性则能够被直接导入。
考虑一下将一系列从火星探测器所传回的图片保存在DynamoDB中的情形。你可以创建一张名为marsDemoImages的表,为每一张图片分配一个唯一的imageid属性(这也被称为表的主(哈希)键):marsDemoImages ( imageid,... )
这张表的每个项目都可以包含各种其它的属性,以下是一些属性的示例:
marsDemoImages表中的一些示例项目
请注意:在本例中,“imageid”是唯一一个必需的属性,其它所有属性都能够自动从NANA的JSON图片数据集中进行导入。实际上,在这个示例中,101这个项目并不包含“camera_model”这个属性。"Mission+InstrumentID"则是一个混合属性,在接下来的一节将对此进行解释。
主键
当你创建一张表时,你必须指定该表的主键。DynamoDB支持以下两种类型的主键:
哈希类型主键:
这种类型的主键由一个哈希属性所构成。在之前的示例中,marsDemoImages表中的哈希属性就是“imageid”,正如下图所示。
marsDemoImages中的部分项目示例,其中的主哈希键高亮显示
哈希及范围类型主键:
这种类型的主键由两个属性所构成。第一个属性是哈希属性,而第二个属性是范围属性。在火星探测器这个示例中,假设我们打算首先以“imageid”字段、随后以“votes”字段对项目进行分组。那么哈希属性就是“imageid”,而范围属性则是“votes”。
marsDemoImages中的部分项目示例,其中的主哈希与范围键高亮显示
查询、更新与扫描
除了使用主键对特定的项目进行访问与操作之外,Amazon DynamoDB也提供了多种方式对特定的数据进行搜索:即查询、更新与扫描。
查询:
查询操作仅使用主键属性的值查找某张表中的特定项目。你必须提供一个哈希键的属性-值对,并可选择地提供一个范围键的属性-值对。
举例来说,在火星探测器应用中,我们可以通过“imageid = 201”这样的键-值对来查询某张特定的图片。
更新:
更新操作与查询操作相类似,区分就在于你能够修改项目的属性了。条件式更新允许你在某个特定的条件满足之后,才能够对项目进行修改。稍后我们将看到这方面的一个示例,我们将对火星探测器应用中图片的投票数进行更新。
扫描:
一次扫描操作将对整张表中的每个项目进行分析。在默认情况下,一次扫描操作会返回每个项目中的所有数据属性。
二级索引
对整张表进行扫描在某些情况下会降低效率,为了避免这种情况,我们可以创建二级索引,以辅助查询的处理。表中的二级索引能够帮助优化对非键属性的查询。DynamoDB支持两种类型的二级索引:
本地二级索引:该索引持有一个与表相同的哈希键,但有一个不同的范围键。
全局二级索引:该索引持有一个哈希键与一个范围键,它们的值可以与表中的对应值不同。
可以将二级索引想象为额外的表,它们首先由哈希键进行、再由范围键进行分组。举例来说,在marsDemoImages表中,我们可能需要查找来自于某个特定任务与拍摄仪器的图片,并按照某个时间范围进行过滤。因此我们就可以创建一个二级索引,让它首先按照“Mission+Instrument”属性(哈希键)进行分组,随后按照“TimeStamp”属性(范围键)进行分组。下图是该索引的一个示例,在下一节关于marsDemoImage表的介绍中,我们还将详细分析二级索引的更多细节。
marsDemoImages表中某个二级索引的示例
数据类型与JSON支持
Amazon DynamoDB支持一系列新的数据类型:
标量类型:数字、字符串、二进制、布尔和。
多值类型:字符串集、数字集和二进制集。
文件类型:List和Map。
比方说,在marsDemoImages表中,imageid是数字类型的属性,而camera_model则是字符串类型的属性。
其中最值得注意的是最新发布的数量类型:List和Map,这两种类型非常适合用于JSON文档的保存。List数据类型与JSON数组非常相似,而Map数据类型则类似于一个JSON对象。List或Map元素能够保存的数据类型是没有限制的,只是每个项目最多不能超过400KB,并且最多支持32个级别的内嵌属性。此外,DynamoDB还允许你访问list和数组中的每个元素,即使这些元素的嵌套层数相当多。DynamoDB的这个特性相当令人兴奋,它让开发使用JSON数据的web应用程序变得相当简单直接。
火星探测器应用的后台工作原理
火星探测器应用的实际工作原理是什么?在这一节中,我们将让你了解,DynamoDB中的JSON文档支持功能让这一应用的创建变得非常简便与直接。我们使用了AngularJS来创建这个应用程序,这是一个非常流行的JavaScript web应用框架,不过本文中的概念也适用于其它任何编程语言。如果你希望预览一下该应用的源代码,可以在GitHub上的awslabs帐号下找到完全公开的源代码。
为了理解这个应用程序的运行原理,让我们来看一看下图所示的火星探测器应用程序的整体架构,我们将一步一步地为你讲解每个组件的作用。
火星探测器的设计架构
浏览器客户端从Amazon S3获取应用代码
当用户开始访问火星探测器示例的应用程序网站时,浏览器就会从Amazon S3获取应用程序代码,包括HTML、CSS和JavaScript。通过使用DynamoDB和S3,我们就能够在客户端完整地运行整个应用程序,就样就能够避免自己管理服务器的各种麻烦。
应用程序将通过Amazon Cognito对用户进行验证
在这一步骤中,应用程序将通过Amazon Cognito对用户进行授权,让用户得以访问DynamoDB表。Amazon Cognito是一个简单的用户认证与数据同步服务,它能够在未认证访客与DynamoDB之间建立关联,允许任意用户对该应用程序所对应的DynamoDB数据表进行查询,并且对表中的某些属性进行有限制的更新操作。如果你打算自己部署这个示例,那么你也可以使用DynamoDB Local将整个应用程序运行在你自己的本地机器上,以进行开发或测试工作。在GitHub上的火星探测星应用源代码的README文档中可以找到在本地运行这一应用的操作指南。
让我们回到这个在线示例的认证环节,通过使用Amazon Cognito,我们就能够轻易地管理访问对DynamoDB数据表的访问,并收集访问者的数量等相关的统计信息。
Cognito统计数据界面的截图示例
通过使用Amazon Cognito,你就可以使用各种公开的登录提供者,例如Amazon、Facebook和Google,或是使用自己的用户身份系统为访问用户创建独立的用户身份信息,以访问AWS云服务。用户也可以选择作为未认证的访客身份访问你的应用。我们在这里使用了未认证访客访问特性,为web浏览器提供AWS身份信息,并对每个用户进行唯一识别。我们按照下面所列出的步骤将应用程序部署到生产环境中,你也可以用同样的步骤将你自己的应用程序进行部署:
1,为该应用程序创建一个Amazon Cognito身份池,这一步可以在Amazon Cognito的管理控制台中完成。你可以选择使用默认设置,只需确保“允许非认证身份访问”被选中即可。
2,对AWS身份与访问管理(IAM)进行配置,对于该示例应用运行所需的最小权限进行授权:
3,对marsDemoImages表进行读取
4,使用date-gsi与votes-gsi进行查询
5,GetItem
6,对marsDemoImages进行写入
7,更新votes字段
8,对userVotes表进行读取
9,查询属于用户自己的项目,但不可查询其他人的项目
10,对userVotes表进行写入
11,对属于用户自己的项目进行PutItem操作,但不可操作其他人的项目
12,对应用的配置进行修改,以使用Amazon Cognito服务
对DynamoDB进行查询与更新
用户可以根据日期、投票数和已保存图片等不同选项对图片进行选择。每次选择都是对DynamoDB数据表和索引的一次查询。为了充分理解这个过程的工作原理,我们需要深入了解DynamoDB的某些方面。
表schema和GSI的配置
让我们首先来创建一张DynamoDB数据表!你可以通过AWS管理控制台,或是AWS开发SDK来完成这一任务。我们在这个示例中使用了由CoffeeScript生成的JavaScript文件,可在/viewer/lib/prepare_tables.coffee找到源代码。其中最重要的部分是对DynamoDB 数据表的schema的描述,以及GSI的配置,该数据表用于保存图片数据:
marsDemoImages的表schema
我们决定将“Mission”与“InstrumentID”这两个数据字段进行组合,以允许对多个属性进行同时查询。由于应用程序中的每个视图通常都对应着某个特别任务的一个仪器,因此可以选择专注于“Mission”与“InstrumentID”,使用这个组合属性作为GSI的哈希键,并且另外选择一个属性作为GSI的范围键。举例来说,用户可以在火星探测器的进行探险任务时,从“前端避险摄像头”仪器获取所有的图片,并根据日期进行过滤。GSI就能够提供这种类型的查询,该表中的GSI如下图所示:
marsDemoImages表中的全局二级索引的schema
创建date这个GSI的作用是允许用户根据基于某个特定的仪器和任务,根据图片的创建日期对图片进行过滤。GSI通过索引哈希和范围键对项目进行分组,这意味着date GSI所包含的图片数据首先会根据“Mission+Instrument”属性进行分组,随后再根据“Timestamp”进行分组。这就允许应用程序能够快速地根据特定日期查找图片,例如找到于10/04/2014,通过“Curiosity+Front Hazcam”这个任务-仪器组合所拍摄的图片。
与之类似,创建vote这个GSI的作用是为了火星探测器示例应用的“投票最多”这一视图所用。在这一情景下,索引哈希键依然是“Mission+Instrument”,而范围键则是“votes”。该索引首先通过“Mission+Instrument”对项目进行分组,接下来再使用“votes”进行分组,这意味着它能够优化这样的查询:基于某个特定的任务和仪器,并根据投票数进行排序的图片结果。
接下来,我们需要一张额外对数据表,以追踪用户为哪些图片进行了投票,这样可以避免用户对同样的图片进行多次投票。这张表的schema很简单,也不需要用到GSI:
userVotes表的schema
最后,我们将调用createTable方法,以创建DynamoDB中的所有表和二级索引。这项任务由/viewer/lib/prepare_tables.coffee这个脚本所完成,如果你遵照源代码中的README文件的指令进行操作,就会自动调用这个脚本。
查询执行
火星探测器应用程序使用了目前非常流行的web开发框架AngularJS。从本质上说,该web应用的每个视图都是由对应的controller所创建的:timeline视图对应着一个timeline controller,而favorites视图对应着一个favorites controller,等等。这些controller都会使用一个通用的Amazon DynamoDB服务与DynamoDB中的数据表进行通信。这个MarsPhotoDBAccessservice服务位于viewer/app/scripts/services目录下,其中包含了应用程序中所有的查询与更新操作。queryWithDateIndex函数则用到了文档级别的JavaScript SDK,使得对项目的访问更加简便与直接:
与之类似的是,可以对vote GSI进行查询请求,以允许用户对图片按照投票数量进行倒序排列:
更新执行
对图片进行投票的工作方式与查询非常类似,区别仅在于我们需要对表中的现有项目进行更新操作。不过在那之前,我们首先需要检查一下,该用户之前是否已经为同样的图片投过票了。可以通过对DynamoDB中的第二张表userVotes进行一行条件式写入实现这一功能,创建这张表的目的是对已经为图片投过票的用户信息进行追踪。如下图所示,可以使用Expected参数进行条件设置。
在以上代码片段中,我们设定的期望是在表中不存在这个指定的imageid与userid的组合,因为这应该是该用户首次对某张图片进行投票。之后,在满足了该条件的情况下,我们就尝试将该项目加入userVotes表中。
当检查过程结束之后,我们可以通过JSON文档SDK对“marsDemoImages”表中的投票总数进行更新,该SDK允许用户以一种简便且直接的方法对个别的JSON字段进行更新。让我们来看一下incrementVotesCount这个函数是如何运行的:
请注意:“UpdateExpression”和“ExpressionAttributeValues”这两个参数是由JSON文档SDK所引入的,它们提供了对JSON数据更多的访问方式。要想了解更多细节信息,请参考GitHub上的awslabs帐号下的代码库中与修改项目属性相关的文档。
从Amazon DynamoDB中获取缩略图
对DynamoDB中的数据表进行查询之后,JSON结果就返回给浏览器端,此时可以从Amazon S3中获取图片的缩略图。我们目前在在线的示例网站中采取的就是这种实现方式。不过,我们也可以选择将所有的缩略图二进制数据保存在DynamoDB里,在每个项目的“data”属性中。DynamoDB能够保存各种二进制数据,而无需指定它的类型、限制或schema,只要该数据不作为哈希键或范围键属性,并且满足每个项目最大400KB的限制就可以了。我们之所以在这个公开的在线示例中选择从S3中获取图片,而不是直接从DynamoDB获取,原因是为了减少大量读取所带来的成本。不过DynamoDB Free Tier版本为用户提供了25GB的免费存储空间,并且读取与定入的最大限制为25。如果你能够动手实验一下,创建属性自己的web应用程序和DynamoDB,那是再好不过了。
总结
本文为读者介绍了如何使用Amazon DynamoDB服务创建一个火星探测器应用。你也可以应用本文中所介绍的概念来打造你自己的web应用程序。让我们来回顾一下整个应用开发的过程:
设计你自己的DynamoDB表,包括schema、主哈希键、以及(可选的)范围键,以及二级索引。
使用AWS管理控制台,或使用我们的AWS SDK创建表与索引。在这个示例中,我们所使用的是JavaScript SDK。
选择你打算使用的语言和web开发框架,我们所选择的是JavaScript语言及AngularJS框架。
开始为应用进行编码,编写对DynamoDB数据表进行查询或更新的各种函数。如果你选择使用JSON并使用我们提供的文档级别的SDK,那么这一过程将变得非常容易。
最后,发布你的应用吧!
如果想要评论本篇文章,想看下其他读者都有什么话想说,欢迎点击“阅读原文”参与讨论。
相关推荐
- 其实TensorFlow真的很水无非就这30篇熬夜练
-
好的!以下是TensorFlow需要掌握的核心内容,用列表形式呈现,简洁清晰(含表情符号,<300字):1.基础概念与环境TensorFlow架构(计算图、会话->EagerE...
- 交叉验证和超参数调整:如何优化你的机器学习模型
-
准确预测Fitbit的睡眠得分在本文的前两部分中,我获取了Fitbit的睡眠数据并对其进行预处理,将这些数据分为训练集、验证集和测试集,除此之外,我还训练了三种不同的机器学习模型并比较了它们的性能。在...
- 机器学习交叉验证全指南:原理、类型与实战技巧
-
机器学习模型常常需要大量数据,但它们如何与实时新数据协同工作也同样关键。交叉验证是一种通过将数据集分成若干部分、在部分数据上训练模型、在其余数据上测试模型的方法,用来检验模型的表现。这有助于发现过拟合...
- 深度学习中的类别激活热图可视化
-
作者:ValentinaAlto编译:ronghuaiyang导读使用Keras实现图像分类中的激活热图的可视化,帮助更有针对性...
- 超强,必会的机器学习评估指标
-
大侠幸会,在下全网同名[算法金]0基础转AI上岸,多个算法赛Top[日更万日,让更多人享受智能乐趣]构建机器学习模型的关键步骤是检查其性能,这是通过使用验证指标来完成的。选择正确的验证指...
- 机器学习入门教程-第六课:监督学习与非监督学习
-
1.回顾与引入上节课我们谈到了机器学习的一些实战技巧,比如如何处理数据、选择模型以及调整参数。今天,我们将更深入地探讨机器学习的两大类:监督学习和非监督学习。2.监督学习监督学习就像是有老师的教学...
- Python 模型部署不用愁!容器化实战,5 分钟搞定环境配置
-
你是不是也遇到过这种糟心事:花了好几天训练出的Python模型,在自己电脑上跑得顺顺当当,一放到服务器就各种报错。要么是Python版本不对,要么是依赖库冲突,折腾半天还是用不了。别再喊“我...
- 神经网络与传统统计方法的简单对比
-
传统的统计方法如...
- 自回归滞后模型进行多变量时间序列预测
-
下图显示了关于不同类型葡萄酒销量的月度多元时间序列。每种葡萄酒类型都是时间序列中的一个变量。假设要预测其中一个变量。比如,sparklingwine。如何建立一个模型来进行预测呢?一种常见的方...
- 苹果AI策略:慢哲学——科技行业的“长期主义”试金石
-
苹果AI策略的深度原创分析,结合技术伦理、商业逻辑与行业博弈,揭示其“慢哲学”背后的战略智慧:一、反常之举:AI狂潮中的“逆行者”当科技巨头深陷AI军备竞赛,苹果的克制显得格格不入:功能延期:App...
- 时间序列预测全攻略,6大模型代码实操
-
如果你对数据分析感兴趣,希望学习更多的方法论,希望听听经验分享,欢迎移步宝藏公众号...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)
- vmware17pro最新密钥 (34)
- mysql单表最大数据量 (35)