java系统找不到指定文件怎么解决
375
2022-09-19
AWS DynamoDB运用技巧
前言
本文将会介绍AWS DynamoDB(后续统称DDB)的基础概念以及一些设计原则。若公司的业务运行在AWS上,则DDB往往会作为NoSQL数据库的首选。虽然对于NoSQL数据库来说,表结构的设计不再是最主要设计项(因为其灵活的表结构)。但若合理的利用DDB的相关概念去设计表结构,是可以实现“在NoSQL数据库中实现关系型数据库的经典实践”这一理念。这种设计理念可以帮助我们减轻对于多种类型数据库的使用。即原本需求可能需要同时使用关系型数据库(或多张表格)和NoSQL数据库来实现,而通过上述理念就可以只使用NoSQL数据库来满足业务需求,这极大减轻了开发与运维的工作量。对于上述观点,笔者有一点想提前说明一下。对于“为NoSQL数据库设计表结构”这件事,如果按照NoSQL数据库的设计理念来说,确实是一件多余的事情。但本文后续章节中所介绍的DDB表结构设计,是为了能够更好使DDB支持更多的需求。因为现实中还是有很大一部分的需求是关系型的,因此如果能够使用DDB来实现出关系型的相关功能,那么有可能会就节省掉一部分的设计细节、组件引用和开发细节等。如果作为读者的你不认同上述理念,那么可以选择不再继续阅读后续内容;请不要在评论区针对这个观念和其他人开杠,这是一件毫无意义的事情。笔者也会将自己的理解在文中进行阐述,这也算是在和大家交流心得的一个过程。若文中有错误的理解和概念,请大家及时纠正;吸纳大家的建议,对于我来说也是很重要的学习过程之一。
1. 基础概念
1.1 Table
DDB的Table特性与一般的NoSQL数据库是相同的。Table的结构是可变的,动态的。即Table中字段的类型可以是多种的,不像关系型数据库一样每一列的数据类型是固定的。
1.2 Item
Table中的每一行数据称为一个Item。即范例表格当中使用蓝色框体强调的部分。
1.3 Attribute
Item是由一组Attribute构成的。即范例表格当中使用黑色框体强调的部分。Attribute可以直接理解成其字面思议,就是每一行数据的属性。一行数据可以有多个属性,每一个属性都对应有其名称和属性值。即Attribute的表达形式为key: value。Attribute支持的数据类型有以下10种:基础类型:
string number 注意: 在编写查询和写入查询语句时,需要使用字符串形式来描述需要保存的number类型数据。在解析查询结果时,即需要将number类型的数据强制类型转换为相应的类型,才能在编码中正常使用。这样做的原因为:所有number类型都作为字符串通过网络发送到DDB,是为了以最大限度地提高跨语言和库的兼容性。但DDB将它们视为数学运算的数字类型属性。 binary boolean null
复合/容器类型:
lists maps
集合类型:
string sets number sets binary sets
详情请参考: 官方文档1 官方文档2
1.4 Primary Key
Tips: 如果新增行中的Primary Key已经存在,则新增的Item会直接覆盖掉有同Primary Key的旧Item。
Primary Key有两种类型:
只有单独的Primary Key一般用于查询单条Item。即只能过滤查找出有用相同Primary Key的Item,而不能在针对其他的Attribute来进行更详细的过滤查找。 Primary Key + Sort Key用于批量过滤查询Item时。可以通过对Sort Key进行过滤来实现在同Primary Key的Item中进行过滤查找。 设计Primary Key是一个非常关键的步骤。因为Partition key(Partition Key=Primary Key + Sort Key)会影响数据的分散程度是否平均、合理,从而会影响数据的写入与读取性能。
1.5 Secondary Index
如果Primary Key还不能满足查询需求,则可以考虑在Table上建立Secondary Index。
注意:建立Secondary Index实际上会将当前Table全部数据复制到一张新的Table中,并将需要添加的Secondary Index作为新Table的Primary Key。因此,新建Secondary Index会带来额外的费用开销,不要因为某些需求而盲目的新建的Secondary Index。
Secondary Index实际上是新Table的Primary Key + Sort Key。因此在设计和创建时,实际上是在针对一张新Table进行Primary Key和Sort Key进行设计。
Secondary Index有两种类型:
Local Secondary Index本地二级索引实际上是将原Table中的Sort Key进行了更换,Primary Key保持不变。相当于是给原Table增加了一种过滤查找数据的方式。本地二级索引可以实现强一致性,也可以实现最终一致性。默认是实现最终一致性。 注意: Local Secondary Index必须在创建Table的时候指定。 Global Secondary Index全局二级索引实际上是将原Table中的Primary Key和Sort Key全部进行了更换。Global Secondary Index对应的新Table的RCU和WCU是和原表单独分开计算的,即Global Secondary Index会增加更多的读写资源消费。如果使用了全局二级索引,则ddb此时只能实现最终一致性,一致性模型会影响DDB的RCU和WCU,即会影响DDB实例的相关费用。
1.6 Item Collection
Item Collection的主要用处有两点:
影响DDB的分区,数据分散程度在同一个Item Collection中的数据会被分配到DDB的一个存储节点上,这会使DDB有更高的读写性能。 用于数据建模
Tips: 对于Item Collection,笔者这里想强调的是,这个概念是DDB表结构设计好坏的一个重要判定因素。在同一个查询需求前提下,返回Item Collection中的数据越多,即表明这个表的Partition Key设计的就更加合理。即Item Collection是可以反映Partition Key的查询命中率。
2. 表结构设计
在本章节中会介绍一些DDB的表结构设计理念和思路。希望这些想法可以帮助大家更好的利用DDB去实现需求。
2.1 核心设计理念
结合章节1中所介绍的DDB相关概念,这里提出设计DDB表结构时最应关注的几个点:
尽可能的使用一次Query Request完成数据查询需求。即通过设计合理Primary Key和Sort Key,使得让大部分相关数据尽可能的落到同一个Item Collection中。 设计的思路主要是围绕着Primary Key和Sort Key的内容结构进行设计。
2.2 设计思路
2.1 将业务应用字段和索引字段区分开
用于查询的信息就放到相关的索引字段中,即Primary Key和Sort Key;而需要保存的详细信息放到相关的应用字段中,即Attribute。如果出现有的信息即需要用作查询,也需要用作落地的情况;则应该为其建立一个索引字段和一个应用字段。最好不要因为两者保存的是同一份数据就指使用一个字段保存。因为如果只使用一个字段保存,则后续如果对Table的结构进行调整,则有可能会导致数据丢失或数据无法快速查询的问题。
2.2 尽量缩短Attribute Name(key)的长度
这样做主要是为了减少DDB的存储费用。可以通过在封装DDB写入API时,将各个字段的名称都使用缩写存入Item;然后在封装DDB查询API时,使用缩写获取数据并将其映射到对象中相应的全名称类属性中。即在DDB中使用缩写描述数据,在代码中使用全称来描述数据。这样既可以保证DDB中的Attribute Name是简短的,同时还可以保证在代码中数据有着良好的可读性。
2.3 实现一对多关系
这里提供3个实现思路共大家参考。
2.3.1 使用容器类型的数据来作为Attribute的Value
在关系型数据库中,使用一对多(o2m)的目的是在于,通过外键查询不在本表中的其他相关数据(实际上就是关系型数据库的第一范式)。在DDB中为了满足这种需求,可以将该数据相关的其他数据保存在一个容器类型的数据中,然后将这个容器类型数据保存在当前表中的某一个Attribute中。这样,就可以使用类似于外键的Primary Key或Sort Key查询到该数据后,直接读取相应的Attribute即可。 适用场景:
经常用于查找的值不会出现在容器类型的Attribute中即不会经常用到Attribute中的数据。因为Primary Key和Local Secondary Index/Global Secondary Index的数据类型不能为容器类型,因此经常查找的数据不能出现在容器类型的Attribute中。 关联的数据增量是有限的因为一个Item最多可以保存400kb的数据。即如果一条数据关联的其他多条数据是无限增常的,则不适合使用该种方式来实现一对多关系。
2.3.2 通过保存重复数据的方式
在关系型数据库中,为了避免存储重复数据,可以通过将一行数据拆分保存在不同的表中,然后通过引入外键来解决数据关联查询的问题(实际上就是关系型数据库的第二范式)。在DDB中,可以通过将每一行数据都完整的保存在一个Item中。即可能会有多个Item的某些Attribute值是重复数据,但这样做就可以解决1对多的需求。适用场景:
重复的数据Attribute值不会经常改变或不可变如果存在重复的Attribute值基本上不会改变或很少会有变动时,则可以使用此方式来解决一对多的需求。因为如果重复数据需要变动,则会牵扯到大量Item都需要改动数据。这将会是一个巨大的工作量。
2.3.3 使用特定格式的PK与SK并配合DDB Query API
Primary Key有两种类型,一种是只有Primary Key,另一种是Primary Key + Sort Key的复合形式。可以利用复合形式的Primary Key来实现一对多的需求。在一对多模型中,“一”使用Primary Key来表示,而”多”使用Sort Key来表示。同时,通过在Sort Key的Value中“做文章”,可以实现多个“1对多”关系保存在同一个Table中。
Tips: 这里所说的做文章,其想表达的意思为Sort Key的值是有特殊格式的。例如有着统一前缀,统一后缀或统一的分隔符等。
通过上述设计,在查询时结合DDB Query API中提供的各类查询方法,对Sort Key的value进行特征匹配,可以实现一对多的查询需求。适用场景:适用于父实体和相关实体的多种访问模式。
Tips: 笔者个人比较推荐使用这种方法来实现一对多的关系。因为这种方式实现出的一对多关系基本上会被一个Item Collection所包含。一个对象(Item)所对应的多个关系对象(Item)的Primary Key是相同的,且能够体现出他们过关联的对象是谁。而这些对象的Sort Key能够体现出他们做为同类对象中的唯一标识(例如将对象ID嵌入到Sort Key中)。同时,通过使用DDB Query API的特征匹配查询,就可以实现在一个Item Collection中体现出一个一对多关系。
2.3.4 使用复合形式的Sort Key
这种方式的原理实际上也是在Sort Key的Value中”做文章”,即Sort Key的Value以一种特殊格式来记录数据。例如:
需要实现的“一对多”的关系数量大时可以使用该方式即适用于深度嵌套的层次结构,需要在层次结构的多个级别中进行搜索。 越浅层次维度的数据,越需要全部获取这种方式是依据维度从浅到深来进行查询的。因此,对于浅层次的维度,很难对其中的深层次维度再进行过滤查询。即越是浅层次的维度,查询出来的数据就越有可能会包含大量的无关数据。
2.4 实现多对多关系
这里提供3个实现思路共大家参考。
2.4.1 浅复制
该方式实际上是将多对多关系拆分城两个1对多关系来处理。结合章节2.3.1中所介绍的“使用容器类型的数据来作为Attribute的Value”方式来实现多对多关系中的一侧关系。即最终需要实现两个一对多关系才能达到多对多的需求。
适用场景: 与“使用容器类型的数据来作为Attribute的Value”适用场景类似。
2.4.2 临接表
实现原理为将多对多关系使用Item来实现(记录)。实际上就是在模仿关系型数据库中的多对多关系实现方式(通过中间表来关联其他两张表)。通过将多对多关系中的两侧实体以及关系本身都作为Item保存在Table中来实现多对多关系。不同的Item有着不同的Primary Key和Sort Key,例如关系Item中的Primary Key和Sort Key实际上就是在体现多对多关系。之后再配合DDB Query API,Primary Key和Sort Key进行过滤查询即可实现多对多关系。
适用场景:
适用于多对多关系不会经常改变或不改变的场景即针对保存多对多关系的Item不会经常做修改操作,修改操作都会集中在多对多关系中的两侧实体对应的Item上。
2.4.3 规范化和多个请求
原理为通过规范化Item的格式和配合多次Query Request来实现多对多查询的需求。对于规范化,主要是在Primary Key和Sort Key上下功夫。由于可以结合多次请求来做,那么初次查询一般是根据基础查询条件获得和当前实体相关的所有关系Item。后续多次查询可通过初次查询中获取的所有相关实体的关键信息再进行详细查询。适用场景: 关系中包含高度可变数据时的后备选项,适用于具有各种关系的高度互连数据
总结
如果相关业务是运行在AWS之上,同时又有数据结构灵活度高且有数据落地的需求。那么首选的数据库一般都为DDB,因为其在读写性能、数据安全以及价格上都有很大优势。因此学习一些DDB相关知识以及设计概念能够使我们更好的发挥其优势。上述介绍这些运用技巧,有些笔者已经在实际的工作需求中进行了实践。例如将本来设计使用关系型数据库的方案改造为使用DDB来处理数据落地问题。新方案使得在数据存储的费用上有了很大的缩减(这也是老板最关注的一点~);同时通过合理的表结构设计,新方案依旧还能够满足原方案中大部分的数据关系设计。当然,这里也不是鼓励大家一定要使用DDB,因为引入新的组件也未必都是好事。例如不同团队之间,对于新技术的学习和接受能力是不一样的。如果你所处的团队对于不崇尚拥抱新技术或团队的整体学习能力不足,那此时引入DDB的话有可能还会加大团队的工作压力和增多技术债。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~