复习总结

文档型数据库——MongoDB

notion image
notion image

用电信息采集

使用MongoDB的原因是写入的数据信息量太大了,更新数据太多了,吞吐量太大,关系型数据库支撑不了。
notion image
用电信息采集系统中采集终端上传用电信息至前置通信平台,前置通信平台负责将原始数据帧最终转换为存入应用系统生产数据库和分析数据库的业务数据
数据采集服务和数据处理单元启动时,从前置通信平台关系数据库加载档案数据,用于数据帧解析和原始数据转存
策略:保证安全性和速度
数据采集服务首先对原始数据进行本地缓存,然后再将文件上传至MongoDB私有云,而没有把原始数据直接以键值对形式写入MongoDB私有云
一方面可以有效的保证原始数据的安全性,在很大程度上避免因网络中断,机房断电等异常造成的数据丢失
另一方面,缓存后的文件写入MongoDB,与键值对写入MongoDB相比,前者速度快的多,能更好适应高速采集数据流的大数据处理
复制集
利用多台机器之间的异步复制达到故障转移和冗余。每三个Mongo服务构成一组复制集,彼此相互进行“心跳”检测,实现数据的高可用性
海量数据的读写分离
通过云存储技术的使用,结合复制集技术的应用,复制的数据库能很好的适用于读扩展
可以将查询路由到更多的副本上,这样查询就会发送到从节点上执行,从而实现将“读写请求”按实际负载情况进行均衡分布的效果、增大吞吐量
海量数据的均衡分布
众多服务器构建的私有云利用自动分片机制,各数据片段均衡写入到各工作节点的存储系统中
对均衡策略进行了优化,通过路由mongos获取分片所在节点负载,在迁移源分片与目标分片选取等环节加入负载因素的考虑,从数据量和负载两方面实现均衡
 

人社大数据平台

notion image
 

文档及评论(类似微信朋友圈文章管理)

MongoDB作为文档型数据库,比关系型数据库更加擅长存放复杂类型的数据。
使用关系数据库管理网络发布的文章时,需要有文件表、评论表、点赞表和附件表,其中评论表、点赞表和附件表都持有文章表主键。
使用MongoDB时,只需要一个文章集合就可以,这个集合包括,文章内容属性,文章发表时间属性,文件状态属性,评论数组属性,点赞数组属性,文章附件数组属性
 
具体实现:
  1. 新增数据:为每条朋友圈设置:_id、内容content、创建时间createTime、使用者userName、附件attachments(嵌套文档,包括url、name等)
    1. notion image
  1. 添加评论:在comments属性中添加嵌套文档(_id、user、 createTime、 content、 status)
    1. notion image
  1. 删除评论:先Query查询到,再用update更新
    1. notion image
  1. 修改评论:同样是先Query查询到,再用update更新
    1. notion image
  1. 查询部分评论和总的赞数:使用聚集函数
    1. notion image
  1. 查询最近三十条的点赞和评论信息
    1. notion image
 
 

列族数据库——Hbase

手机数据

需求:有一张数据表,其中包含手机号码字段
  1. 查询一段时间内固定号码的所有数据
  1. 查询一段时间内所有数据
分析:HBase要想查询快速,只能从rowKey上下手
rowKey=phoneNum+时间 可以实现目标1,但是目标2很难实现rowKey=时间+phoneNum 可以实现目标2,但是目标1很难实现,且数据量越来越大可能导致热点问题
解决思路1:牺牲空间换时间,写数据时同时写入两张表,内容一样,只是一张表rowKey=phoneNum+时间,另一张表rowKey=时间+phoneNum
解决思路2:牺牲部分空间部分时间,两张表,一张全量表,rowKey=phoneNum+时间,另一张索引表只存rowKey=时间+phoneNum,目标1通过scan全量表就可以实现,目标2先scan索引表然后批量get全量表。
 

滴滴

场景:订单查询
这份数据使用过滴滴产品的用户都接触过,就是App上的历史订单 近期订单的查询会落在Redis,超过一定时间范围,或者当Redis不可用时,查询会落在HBase上
 
Rowkey设计:订单状态表
  • Rowkey:reverse(order_id) + (MAX_LONG - TS)
  • Columns:该订单各种状态
Rowkey设计:订单历史表
  • Rowkey:reverse(passenger_id | driver_id) + (MAX_LONG - TS)
  • Columns:用户在时间范围内的订单及其他信息
 

Map Reduce:WordCount

如果想统计过去10年计算机论文中出现次数最多的几个单词,看看大家都在研究些什么,可以大致采用以下几种方法:
  1. 写一个小程序,把所有论文按顺序遍历一遍,统计每一个遇到的单词的出现次数,最后就可以知道哪几个单词最热门了(适合于数据集比较小,且非常有效的、实现最简单)
  1. 写一个多线程程序,并发遍历论文。理论上是可以高度并发的,因为统计一个文件时不会影响统计另一个文件。使用多核机器时比方法一高效。但是,写一个多线程程序要复杂得多
  1. 把作业交给多个计算机去完成。可以使用方法一的程序,部署到N台机器上去,然后把论文集分成N份,一台机器跑一个作业。这个方法跑得足够快,但是部署起来很麻烦,既要人工把论文集分开,复制到各台机器,还把N个运行结果进行整合
  1. 使用MapReduce !MapReduce本质上就是方法三,但如何拆分文件集,如何复制分发程序,如何整合结果这些都是框架定义好的。我们只要定义好这个任务(用户程序),其它都交给MapReduce
 
每个拿到原始数据的机器只要将输入数据切分成单词就可以了,所以可以在map阶段完成单词切分的任务
相同单词的频数计算也可以并行化处理,可以将相同的单词交给一台机器来计算频数,然后输出最终结果,这个过程可以交给reduce阶段完成
将中间结果根据不同单词分组再发送给reduce机器,这正好是MapReduce过程中的shuffle能够完成的
因此,WordCount的整个过程可表示为:
  1. Map阶段完成由输入数据到单词切分的工作
  1. Shuffle阶段完成相同单词的聚集和分发工作(这个过程是MapReduce的默认过程,不用具体配置)
  1. Reduce阶段完成接收所有单词并计算其频数的工作
MapReduce中传递的数据都是<key, value>形式的,并且shuffle排序聚集分发是按照key值进行的,所以,将map的输出设计成由word作为key,1作为value的形式,它表示单词出现了1次(map的输入采用Hadoop默认的输入方式,即文件的一行作为value,行号作为key)
Reduce的输入是map输出聚集后的结果,即<key, value-list>,具体到这个实例就是<word, {1,1,1,1,…}>,reduce的输出会设计成与map输出相同的形式,只是后面的数值不再是固定的1,而是具体算出的word所对应的频数
Map操作的输入是<key, value>形式,其中,key是文档中某行的行号,value是该行的内容。Map操作会将输入文档中每一个单词的出现输出到中间文件中去
notion image
Reduce操作的输入是单词和出现次数的序列,如<“Hello”,[1,1,1]>,< “World”,[1,1] >,< “Bye”,[1,1,1] >,< “Hadoop”,[1,1,1,1] >等。然后根据每个单词,算出总的出现次数。
最后输出排序后的最终结果就会是:< “Bye”,3>,< “Hadoop”,4> ,< “Hello”,3>,< “World”,2>
notion image
整个MapReduce过程实际的执行顺序是:
  1. MapReduce Library将Input分成M份
  1. Master将M份Job分给空闲状态的M个worker来处;
  1. 对于输入中的每一个<key,value> 进行Map操作,将中间结果缓冲在内存里
  1. 定期地(或者根据内存状态)将缓冲区中的中间信息刷写到本地磁盘上,并且把文件信息传回给Master(Master需要把这些信息发送给Reduce worker)
  1. R个Reduce worker开始工作,从不同的Map worker的Partition那里拿到数据,用key进行排序
  1. Reduce worker遍历中间数据,对每一个唯一Key,执行Reduce函数(参数是这个key以及相对应的一系列Value)
  1. 执行完毕后,唤醒用户程序,返回结果(最后应该有R份Output,每个Reduce Worker一个)
对于上面的例子来说,每个文档中都可能会出现成千上万的(“the”,1)这样的中间结果,琐碎的中间文件必然导致传输上的损失
因此,MapReduce还支持用户提供Combiner函数。这个函数通常与Reduce函数有相同的实现,不同点在于Reduce函数的输出是最终结果,而Combiner函数的输出是Reduce函数某一个输入的中间文件
notion image
以Combine输出结果作为输入的Reduce过程示意图
以Combine输出结果作为输入的Reduce过程示意图
notion image

使用MapReduce进行数据分析的例子

挖掘气象数据集:分布在全球各地的气象传感器每隔一小时便收集当地的气象数据,从而积累了大量的日志数据。它们是适合用MapReduce进行分析的最佳候选数据,因为它们是半结构化且面向记录的数据
在本例中,map函数所做的工作只是进行数据的准备,用来找出年份和气温的数据,通过这种方式来建立数据,使得reducer函数能在此基础上进行工作:找出每年的最高气温
在本例中,map函数通过对数据的检查,筛选掉缺失的、不可靠的或错误的气温数据
map函数的输出先由MapReduce框架处理,进行shuffle的过程,然后再被发送到reduce函数。shuffle过程根据键来对键/值对进行排序和分组
在本例中:
map的输入为这些键/值对 (0, 0067011990999991950051507004...9999999N9+00001+99999999999...)   (106, 0043011990999991950051512004...9999999N9+00221+99999999999...)   (212, 0043011990999991950051518004...9999999N9-00111+99999999999...)   (318, 0043012650999991949032412004...0500001N9+01111+99999999999...)   (424, 0043012650999991949032418004...0500001N9+00781+99999999999...)
map的输出为: (1950, 0)   (1950, 22)   (1950, -11)   (1949, 111)   (1949, 78)
shuffle过程的输出为reduce函数的输入,在本例中为: (1949, [111, 78])   (1950, [0, 22, -11])
reduce函数读取每个列表并从中找出最大的读数
reduce 函数的输出为 (1949, 111)   (1950, 22)
这也是最后的输出:全球气温记录中每年的最高气温
整个MapReduce的逻辑数据流
整个MapReduce的逻辑数据流
 

键值对数据库——Redis

notion image
 

文章投票网站后端

文章基本信息:对于网站里的每篇文章,程序都使用一个散列来存储文章的标题、指向文章的网址、发布文章的用户、文章的发布时间、文章得到的投票数量等信息
notion image
文章排序信息:用两个有序集合来有序地存储文章
  • 1成员为文章 ID,分值为文章的发布时间
  • 2成员为文章 ID,分值则为文章的评分
  • 通过这两个有序集合,网站既可根据文章发布的先后顺序来展示文章,又可根据文章评分的高低来展示文章
notion image
投票历史记录
为了防止用户对同一篇文章进行多次投票,网站需要为每篇文章记录一个已投票用户名单
  • 程序将为每篇文章创建一个集合,并使用这个集合来存储所有已投票用户的ID
  • 为了尽量节约内存,约定当一篇文章发布期满一周之后,用户将不能再对它进行投票,文章的评分将被固定下来,而记录文章已投票用户名单的集合也会被删除
notion image
 
 
 
 

图数据库——Neo4j

notion image

社会化网络图

notion image

文件系统

notion image

⭐数据模型的转换

notion image
notion image
notion image
 
 

Hello World

notion image
notion image

歌曲信息管理

实体包括歌手、歌曲和专辑
关系则包括歌手与专辑之间的发布关系,以及专辑与歌曲之间的包含关系
notion image
notion image
查找一个歌手所发行的所有歌曲
查找一个歌手所发行的所有歌曲

社交网络

notion image
一个社交网络的数据模型是简单漂亮的
Person
friend: 连接两个不同 Person 实例的关系 (不能连接自己)
status: 连接到最近的 StatusUpdate
StatusUpdate
next: 指向在主线上的下一个 StatusUpdate ,是在当前这个状态更新之前发生的
 
一个 Person 的 StatusUpdate 列表是一个链表
  • 表头(最近动态)可以通过下一个 status 找到
  • 每一个随后的 StatusUpdate 都通过关系 next 相连
使用遍历查询来读取状态更新情况
 
如何读取朋友的消息动态
1.抓取所有的好友动态放入一个列表 — 最新的排前面
2.对列表进行排序
3.返回列表中的第一个记录
4.如果第一个迭代器为空,则把它从列表移除;否则,在这个迭代器中获取下一个记录
5.跳转到步骤2直到在列表中没有任何记录
 

用户角色

notion image
 

黑客帝国

notion image
 
 
 

论文

notion image
 

国家

往年题:将Neo4j转换为MongoDB
往年题:将Neo4j转换为MongoDB
 

地图

notion image
 

做题总结

数据库模式schema描述

hbase:描述清楚行键和列族
redis:描述key是什么,value是什么类型,放什么数据
mongodb:描述每个集合放什么,文档各部分是什么
neo4j:可以画图,也可以文字描述实体包括那些,关系包括哪些

RDB到nosql转换

notion image

1. RDB → MongoDB

RDB有几个表mongodb就创建几个集合,然后把表中的内容都放进去。(记得写_id)
需不需要优化,比如关系表只有两个元素的话,可以转换为key+列表 可以选择优化
notion image
 

2. RDB → Redis

对于实体表,将各表的主键作为key,value可以用hash或者list等。
对于关系表,将主键组合起来作为key,value为string或者hash等等
如果有多种类型的value都需要使用id作为key的话,可以将id加上前缀。
若关系表只有两个属性,value怎么办? 可以简化为key:list表,比如关系表只有系名和教师名这两个主键,就用系名:教师名list来记录
notion image
 

3. RDB → Hbase

实体表和关系表可以提取公共的主键作为行键row-key然后实体表的列族可以为info关系表的列族可以为关系表的第二个主键
一对多关系多的那一端没有必要单独列一个列族,多对多关系都要有相应的列族。
跟redis一样,要是关系表只有两个主键怎么办(下面国家城市的例题) 可以再把名字作为value存入,因为一般不会用名字作为行键,会用id
notion image
 

4. RDB → Neo4j

类似ER图,实体类作为Node,关系类作为relationship
 

nosql之间的转换

通用思路是先转为RDB再转其他的nosql
通常题型为neo4j转其他,就先转为RDB再转其他
 

往年题

【15级】ER转为Hbase和Redis
notion image
Hbase
 
Redis
key
value
value_type
country: xxx
{area: “xxx”, polpulation: xxx}
hash
city: xxx
{area: “xxx”, polpulation: xxx, “纬度”: “xxx”, country: “xxx”, isCapital: xx}
hash
 
【2017-2018】关系型数据库的某几张表分别转换为Redis和HBase数据库存储,写出表结构。(给的sql非常简单,类似下图)
【2018-2019根据ER图设计MongoDB表的逻辑结构
notion image
转化为MongoDB
 
转化为Redis
key
value
value类型
运动员编号:xxx
{姓名:”xxx”, 年龄:”xxx”, 性别:”xxx”, 代表团编号:”xxx”}
hash
团编号:xxx
{地区:”xxx”, 住所:”xxx”}
hash
contain_athlete: 团编号
{’xxx’, ‘xxx’, ‘xxx’} (团内含有的运动员的编号)
set
比赛项目编号:xxx
{项目名:”xxx”, 级别:”xxx”, 比赛类别编号:”xxx”}
hash
比赛类别编号:xxx
{类别编号:”xxx”, 类别名:”xxx”, 主管:”xxx” }
hash
contain_match: 类别编号
{’xxx’, ‘xxx’, ‘xxx’} (这个比赛类别中的所有比赛项目编号)
set
运动员编号_比赛项目编号
{比赛时间:”xxx”, 得分:”xxx”}
hash
 
转为HBase
notion image
 
【2017-2018】自选数据库,设计一个微信朋友圈,用户可以给自己的朋友点赞和评论。写出当用户刷新时,朋友圈展示内容的算法。(不用具体代码,描述流程即可)
使用MongoDB+Redis
Redis部分:
key: info: id value: hash {name:”...”, sex: “....”, ...}
key: friend: id value: set用于存储用户的好友id
key: publish: id value: list用于存储用户自己发的朋友圈,用户每发布一个朋友圈就将新的朋友圈_id插入到链表头部
key: read: id value:list 用于存储用户获取的朋友的朋友圈,具体更新方法见下面朋友圈更新算法
MongoDB部分:
朋友圈内容展示:
  1. 每次刷新朋友圈,后台先去找到该用户的所有好友
  1. 再获取每位朋友某个时间点前的文章id,去mongodb中取得具体信息,将所有文章放到一个列表里
  1. 排序
  1. 将排好序的文章实体数据返回给客户端展示出来
  1. 若用户再请求更早的文章,则修改时间点,重复上面操作。
 
描述:
使用redis+mongodb来实现微信朋友圈,实体包括用户和朋友圈文章关系包括用户和用户间的好友关系和用户和发布的文章的关系。文章实体的属性为mongodb的_id,文章的具体内容由mongodb存储,包括文章内容、文章发表时间、文章状态、评论数组、点赞数组、文章附件数组
某位用户的文章列表是一个链表最新发布的文章与用户节点相连其他文章通过next关系相连,用户每发表一篇文章就会有一个文章节点插入到链表最接近用户的位置上
 
 
【2017-2018】将图存数据库Neo4j(下图)转换为MongoDB存储,要求写出schema和具体的数据内容
notion image
Redis
用户看自身信息: key: user:用户id value:用户姓名
用户看自己属于哪个角色: key: user_mem:用户id value: (set) 存储用户属于的角色id
角色看自身信息 key: role:角色id value:(hash){name:角色名, part_of:..., root: ...}
角色看自己包含哪些成员 key:role_mem:角色id value: (set) 存储属于该角色的用户id
 
MongoDB
 
HBase
notion image
 
 
【2018-2019】自选数据库实现QQ空间的基本功能(相册照片、说说、日志和好友互访记录),并设计用户刷新空间的算法
 
更新QQ空间的算法:
  1. 每次刷新朋友圈,后台先去找到该用户的所有好友
  1. 再获取每位朋友某个时间点前的发布内容,将所有发布内容放到一个列表里
  1. 排序
  1. 将排好序的发布内容实体数据返回给客户端展示出来(对应评论按时间顺序显示)
  1. 若用户再请求更早的发布内容,则修改时间点,重复上面操作。
 
 
使用一种你认为最合适的Nosql数据库设计微博后台,实现功能包括发布微博(大V发微博如何通知粉丝),评论、点赞,以及微博粉丝管理等功能
法一:使用MongoDB
粉丝管理: 用户每关注一个对象,就在这个对象的fans部分将该用户的id填写进去
发布微博: 新建一个vblog,设置各个属性,并且把id放在发布微博用户的blogs数组中,此处应该插入到数组最头部
点赞或者评论: 在微博对应的good、comments数组中添加嵌套文档
大V发微博通知粉丝: 大V发布微博后,遍历用户的粉丝数组,通知每一个粉丝
关注: 在关注者的follow数组中添加被关注者的ObjectId,在被关注者的fans数组中添加关注者的ObjectId
取关: 在关注者的follow数组中删除被关注者的ObjectId,在被关注者的fans数组中删除关注者的ObjectId
用户更新微博读取最近推荐: 选取一个时间节点,遍历用户的关注列表,从关注列表中抽取该时间节点之后的全部微博插入到用户的推荐列表中。将用户的推荐列表排序,并推荐给用户。如果用户想要获取更前一段时间的微博,修改时间节点,重复上述操作。
 
法二:Redis
Key
Value 类型
描述
User:userid
hash
存储用户信息,包括用户的 id、用户名、注册时间等基本信息。
follow:userid
zset
存储用户的关注关系,按照关注时间排序。取关时从该列表中删除对应 userid,并在被关注用户的粉丝列表中删除当前用户的 id。
followed:userid
zset
存储用户的粉丝关系,按照被关注时间排序。管理粉丝时,比如删除粉丝,只需从此 zset 中删除粉丝 userid,并在粉丝的关注列表中删除当前用户的 id。
passageid
hash
存储微博信息,包含属性如微博内容、发布时间、作者 id 等。
like:passageid
set
保存微博的点赞信息,确保同一个用户不会重复点赞两次。
comment:passageid
list
存储微博的评论,内容为 userid + 评论内容。
usertimeline
zset
存储每个用户的微博时间线,内容为微博的 id,按照发布时间排序。
当用户发送一条微博时,遍历用户的粉丝zset,将该微博id插入到每个粉丝的usertimeline中,如果是大V发微博还会通知粉丝,用户刷新微博后会根据每个用户的微博时间线去获取对应微博信息并显示给用户。
  • 关注:若A关注B,在A的userid_follow中加入B的userid,在B的userid_followed中加入A的userid
  • 取关:若A取关B,在A的userid_follow中删除B的userid,在B的userid_followed中删除A的userid
  • 管理粉丝:移除关注,若A移除B,在A的userid_followed中移除B的userid,在B的userid_follow中移除A的userid
  • 评论:评论后将内容加入passageid_comment中
  • 点赞:将用户id加入passageid_like中,同时passageid对应hash信息中点赞数加一
zset是一种有序的集合,每个元素都有唯一的分数,redis会根据分数大小自动排序,zset中元素是唯一的,但是分数可以重复
 
 
【2018-2019】将Neo4j转换成HBASE,给出模式和示例数据
notion image
Redis
Key
Value 类型
描述
User:用户id
hash
存储该用户的基本信息,例如 name 等属性。
friend_of:用户id
set
存储该用户的好友列表,集合元素为好友的用户 ID,例如 {friend1, friend2, ...}。
boss_of:用户id
set
存储该用户的上司列表,集合元素为上司的用户 ID,例如 {boss1, boss2, ...}。
loves:用户id
set
存储该用户喜欢的对象,集合元素为喜欢的用户 ID,例如 {loves1}。
colleague_of:用户id
set
存储该用户的同事列表,集合元素为同事的用户 ID,例如 {colleague1, colleague2, ...}。
married_to:用户id
set
存储该用户的配偶信息,集合元素为配偶的用户 ID,例如 {married1}。
dislikes:用户id
set
存储该用户不喜欢的对象,集合元素为不喜欢的用户id,例如{dislikes1, …}
MongoDB
 
 
HBase
notion image
这里采用以下的方式会好看很多:
notion image
 
 
【2020-2021】将下图所示关系(ER图)用Redis数据库存储,写出逻辑结构,每个实体集和联系集至少三条数据。
notion image
 
notion image
 
notion image
 
department实体,属性有dept_name,building,budget instructor 实体,属性有ID,name,salary student 实体,属性有ID,name,tot_cred department对instructor是dept_inst一对多,且instructor全部参与 instructor对student是一对多 department对student是一对多
Redis
Key
Value 类型
字段
department:department_name
hash
{'building' : “xxx”, 'budget’: “xxx”}
instructor:ID
hash
{'name': “xxx”, 'salary': “xxx”, “department”: “xxx”}
student:ID
hash
{”name”: “xxx”, “tot_credit”: “xxx”, “department”: “xxx”, “instructor”: “xxx”}
dept_instructors:dept_name
set
存储部门与其教师的关联,值为教师的 ID。例:{”C1001”, “C1002”}
inst_students:instructor_id
set
存储教师与其指导学生的关联,值为学生的 ID例:{”S1001”, “S1002”}
dept_students:dept_name
set
存储部门与其学生的关联,值为学生的 ID{”S1001”, “S1002”}
HBase
department表:
rowkey
time stampt
columnFamily:info
columnFamily:student
columnFamily:teacher
dept1
column:dept_name
column:building
column:budget
column: studentID:id, value: id
column: teacherID:id value: id
rowkey
time stampt
columnFamily:info
columnFamily:student
instructor1
column:ID
column:name
column:salary
column:dept_name
column: student ID:id value: id
rowkey
time stampt
columnFamily:info
student1
column:ID
column:name
column:tot_credit
column:dept_name
column:advisor
 
【2020-2021】自选一种NoSQL数据库,设计实现QQ中 二度好友,三度好友,简要说明算法。(二度好友就是好友的好友,三度就是好友的好友的好友)
为每个用户构建一个节点,在用户和用户的朋友之间创建联系(该联系没有方向)。
获取二度好友:以一个用户为根节点,进行广度优先遍历,遍历两层,忽略重复节点
获取三度好友:以一个用户为根节点,进行广度优先遍历,遍历三层,忽略重复节点
 
其它文档中给出的解答:
使用neo4j这种图关系型数据库,实体为用户,关系为用户之间的好友关系
二度好友算法:从要查询的用户节点开始,执行深度优先搜索,搜索过程不允许经过重复的节点,当遍历两个节点后保存第二个节点并返回,继续遍历剩余的路径,直到遍历完成。返回所有的第二个节点,即为二度好友。三度好友就是遍历到第三个节点。
(应为广度吧)
【2020-2021】将下图展示的数据分别用HBase 和MongoDB存储,给出模式并填入所有数据。 节点有:国家,中国,日本,英国,美国,北京,东京,西雅图 边有: 1.“属于”边 中国指向国家,日本指向国家,英国指向国家,美国指向国家 2.中国,日本 有“人口”“面积”边指向节点,节点里是数据 中国的“首都”边指向北京节点;日本的 首都 边指向东京节点
notion image
HBase
notion image
 
Redis
key
value
value类型
国家
{’中国’, ’日本’, ’英国’, ’美国’}
set
国家:中国
{面积: ..., 人口:..., 首都: ..., 属于:国家}
hash
城市:北京
{面积: ..., 人口: ..., 经度: ..., 纬度: ...,所属国:中国}
hash
国家:日本
{面积: ..., 人口:..., 首都: ...,属于:国家}
hash
城市:东京
{人口: ..., 经度: ..., 纬度: ...,所属国:日本}
hash
国家:美国
{属于:国家}
hash
城市:西雅图
{所属国:美国}
hash
国家:英国
{属于:国家}
hash
 
MongoDB
 
【2022-2023线上开卷】一部电影中的各个演员常常有主角配角之分。还要有导演、特效等人员的参与。同时一位导演本身也可以是其它电影/电视剧的演员。也可能是歌手。甚至是电影的投资者。这种关联关系纷繁复杂。在两个实体间可能存在多种不同关联关系。如图1示例。
notion image
notion image
影视领域中的实体包括人、电影/电视剧、歌曲、剧本等等。这些实体之间的关联可以记录一个人参演过哪些电影/电视剧、唱过哪些歌、又是哪些电影/电视剧的投资方、或者仅仅是影视产品的读者/影迷。甚至参演的关联还可以分成主角、配角、特效等等。图2表示了Neo4j中影视领域的部分数据实例,包括人(Alice,Bob,Carol)、剧本(Alice Day)、电影(Film:AliceDay)之间的关联关系以及各种属性。
针对以上影视领域需求背景及数据示例。回答以下问题:
1、如果使用Neo4j来存储影视领域数据。请设计出其逻辑结构,主要说明有几种不同的节点,各种节点之间存在什么样的边。并列出节点和边的属性。(6分)
2、如果使用Hbase来存储影视领域数据。请设计出其逻辑结构。主要说明有几张表。表的key是什么,表内包含几个列族,分别存放什么数据。(6分)
3、如果将图2数据转存至Hbase中,请写出Hbase中的数据实例。(6分)
4、如果将图1数据转存至Mongodb中,请写出Mongo中的数据实例。(6分)
5、如果将图2数据转存至Redis中。请写出Redis中的数据实例。(6分)
6、每一部电影都拥有一个综合评分,该评分是评价电影受欢迎程度的主要指标。得分在前200名的电影被定义为“热门电影"。请选择适合的NoSQL数据库。使用伪代码实现热门电影信息展示功能。假设一页可以展示20条电影信息,要求展示给定页数(page)上的20条电影的"“片名”、“上映日期"、“票房总数"“、“综合评分”等属性。(9分)
7、有一个功能需求“给定两个电影。找到它们的共同观众。返回这些观众及他们的全部好友”。请选择适合的 Nosql数据库,写出实现此功能的算法思想。(9分)
8、如果使用MongoDB来存储影视领域数据,部署时一般会采用数据3副本机制。这种机制可以带来什么好处﹖需要解决哪些问题?(10分)
9、针对影视领域需求,试比较Neo4j、Hbase、MongoDB和Redis 四种方案的优劣。并说明理由。(12分)
 
 
 
【2023-2024】将ER图分别转换为Hbase和Redis,说明设计思路、逻辑结构和示例数据(实体集不少于2行数据,联系集不少于5行)
notion image
HBase:实现一
  1. student 表
    1. Row Key
      info:name
      info:dept_name
      info:tot_cred
      1001
      Alice
      CS
      120
      1002
      Bob
      EE
      110
  1. course 表
    1. Row Key
      info:title
      info:credit
      CSE101
      Data Structures
      3
      CSE102
      Algorithms
      4
  1. exam 表
    1. Row Key
      info:name
      info:place
      info:time
      EXAM001
      Midterm
      Room 101
      2024-12-01
      EXAM002
      Final
      Room 202
      2024-12-15
  1. exam_marks 表
    1. Row Key
      marks:mark
      1001_CSE101_EXAM001
      85
      1001_CSE102_EXAM002
      90
      1002_CSE101_EXAM001
      80
      1002_CSE102_EXAM002
      88
HBase:实现二
notion image
Redis
key
value
value的类别
Student:S1
{”name”:”Alice”, “dept_name”:”软件”, “tot_cred”: 6}
hash
Student:S2
{”name”:”Bob”, “dept_name”:”软件”, “tot_cred”: 6}
hash
Course:C1
{”title”:””, “credit”:””}
hash
Course:C2
{”title”:””, “credit”:””}
hash
Exam:E1
{”name”:””, “place”:””, “time”:””}
hash
Exam:E2
{”name”:””, “place”:””, “time”:””}
hash
S1_C1_E1
‘87’
string
S1_C2_E2
‘82’
string
S2_C1_E1
‘98’
string
S2_C2_E2
‘89’
string
 
 
【2023-2024】选用一种数据库管理电商购物平台(淘宝、京东)数据,包含商家信息、买家信息、商品信息以及交易信息,说明设计思路、逻辑结构,数据库可选择关系型数据库、NOSQL数据库、关系非关系混合型存储方式。
方法一:关系非关系混合型存储
关系型数据库(MySQL/PolarDB 逻辑设计)
  1. 商家表(Seller)
    1. 买家表(Buyer)
      1. 交易表(Transaction)
        1. 订单明细表(OrderItem)
          NoSQL 数据库(MongoDB 逻辑设计)
          1. 商品集合(Products)
            1. 用户评论集合(Reviews)
              1. 推荐系统集合(Recommendations)

                实现细节
                • 关系型数据库的实现逻辑
                  • 商家、买家、交易信息需要 ACID(事务一致性),通过关系型数据库的外键约束,确保商家和买家的 ID 与交易记录关联。
                  • 订单信息存储商品数量和价格,用于计算交易金额,支持事务性更新。
                • NoSQL 数据库的实现逻辑
                  • 商品信息按商品编号存储,每个商品是一个文档,支持高并发访问。
                  • 用户评论嵌套存储在商品下,按时间戳排序,支持评论查询。
                  • 推荐系统按用户编号存储,实时动态更新推荐列表。
                 
                方法二:使用非关系型数据库(MongoDB)
                 
                 
                【2023-2024】将Neo4j转换到MongoDB数据库中,写明设计思路和逻辑结构,以及两种数据库如何进行图书平均评分Top k的查找。
                notion image
                在 Neo4j 中,图数据以节点和关系的形式存储。为了查找书籍的平均评分 Top k,可以通过以下步骤:
                1. 遍历所有书籍节点,并找到与其相关的评分关系。
                1. 聚合所有评分值,计算每本书的平均评分。
                1. 按照平均评分从高到低排序,并限制结果数量为 k。
                1. 返回书籍的名称及其平均评分。
                 
                在 MongoDB 中,数据以文档形式存储,书籍文档中嵌套了所有与之相关的评分信息。为了查找书籍的平均评分 Top k,可以通过以下步骤:
                1. 展开每本书的嵌套评分数组,将每个评分单独处理。
                1. 对每本书的评分进行分组,计算出每本书的平均评分。
                1. 按照平均评分从高到低排序,取前 k 条数据。
                1. 返回书籍的名称及其平均评分。
                 
                 
                 
                Loading...