Python3Django配合Mongodb打造高性能高扩展
书接上回,之前有一篇文章提到了标签云系统的构建:Python3。7jieba(结巴分词)配合Wordcloud2。js来构造网站标签云(关键词集合),但是这篇只是浅显的说明了一下如何进行切词以及前端如何使用wordcloud2。js进行前端展示,本次主要讨论下标签分词切出来之后,如何进行存储。
假设我们目前文章标签体系的需求是这样:
每篇文章都具有唯一的标题、描述以及URL。
每篇文章都具有一个或多个标签。
每篇文章都具有作者的名称,以及喜欢
每篇文章都有用户的评论,用户名、消息、日期时间以及评论的喜欢度。
每篇文章都可以有0个或多个评论。
那么如果使用关系型数据库来设计,比较简单的设计方案可以是这样:
可以注意到,标签和文章的对应关系还是简单的一对多,如果做成比较灵活的多对多还需要增加一张关系表,这样就是四张表了。
如果使用nosql比如Mongodb来说,只需要一张表(聚合)就可以实现:{id:POSTIDtitle:TITLEOFPOST,description:POSTDESCRIPTION,by:POSTBY,url:URLOFPOST,tags:〔TAG1,TAG2,TAG3〕,likes:TOTALLIKES,comments:〔{user:COMMENTBY,message:TEXT,dateCreated:DATETIME,like:LIKES},{user:COMMENTBY,message:TEXT,dateCreated:DATETIME,like:LIKES}〕}
可以看到标签是由数组实现的,那么关系型数据库mysql和非关系型数据库mongodb在标签实现中本质上有什么区别呢?
关系数据库如mysql中标签云的实现是简单的,标签和文章分别在不同的表中,通过join可以比较简单的查询出标签的统计数据。而MongoDB为快速水平扩张以及极高的性能而优化,在MongoDB中没有join,倾向于使用embedding来代替linking关系。
假设我们的需求又有了变化,普通博客变身成为具有数百万篇文章的小说站。每个小说都有许多布尔属性,大约一万个可能的属性,每篇小说都有十几个章节,假设我希望能够实时(几毫秒)请求给出的前n项任何属性组合的标签。
你会选择推荐什么解决方案?毫无疑问,如果你在寻找极具扩展性的方案,Mongodb无疑更好。
而且从业务角度上来讲,无论是通过标签查文章,还是文章查标签这样的需求,都非常灵活,当然了根据文章查标签一般没问题,一般都是根据标签查文章的时候有性能问题,如果是纯关系数据库比如mysql很难解决性能问题,所以要借助es索引解决。es索引的时候可以将tagid用逗号分隔,可以很快的根据一个tagid,或者多个tagid查询到关联的文章id,一般文章列表都是分页的,有这些文章id了,再去关系数据库里面取文章就行了,但是es又是另外一件事了,回头我们再讨论。
随后使用Django2。0。4来实现,首先安装好python的mongodb操作库pymongopip3installpymongo
值得一提的是,它会有一个相对应bson模块也就是说PyMongo模块的实现是基于和它一起的bson模块的。
bson是一种类json的一种二进制形式的存储格式,简称BinaryJSON,它和JSON一样,支持内嵌的文档对象和数组对象,但是BSON有JSON没有的一些数据类型,如Date和BinData类型;BSON有三个特点:轻量性、可遍历性、高效性,但是空间利用率不是很理想。
基于Django插入标签的视图:importpymongofrombsonimportjsonutilasjsonbmongoclientpymongo。MongoClient(hostlocalhost,port27017)fromdjango。httpimportHttpResponse,HttpResponseRedirect,JsonResponsefromdjango。viewsimportViewclassInsertTagsHandler(View):defget(self,request):dbmongoclient。test12tabledb。test12restable。find({title:123})。count()print(res)ifres0:result重复数据returnHttpResponse(json。dumps({result:result},ensureasciiFalse))else:table。insert({title:123,desc:〔123,123〕})returnHttpResponse(json。dumps({result:添加成功},ensureasciiFalse))
基于django通过文章查询标签classFindArticleHandler(View):defget(self,request):dbmongoclient。test12tabledb。test12restable。findone({title:123},{desc:1})returnHttpResponse(jsonb。dumps(res,ensureasciiFalse))
基于django分组查询获取所有标签以及标签出现次数的统计classTagsStatHandler(View):defget(self,request):dbmongoclient。test12tabledb。test12pipeline〔{unwind:tags},{group:{id:tags,count:{sum:1}}},〕restable。aggregate(pipeline)returnHttpResponse(jsonb。dumps(res,ensureasciiFalse))
基于django通过标签反查文章classTags2ArticleHandler(View):defget(self,request):dbmongoclient。test12tabledb。test12restable。find({tags:{in:〔123〕}})returnHttpResponse(jsonb。dumps(res,ensureasciiFalse))
结语:经此一役,Mongodb的特点跃然纸上:结构灵活,表结构更改相对自由,不用每次alter的时候付出代价,适合业务快速迭代,而且json原生和大多数的语言有天然的契合。还支持数组,嵌套文档等数据类型。
吉祥三宝消失14年后爸爸逝世,妈妈隐退,女儿英格玛模样大变历年的春晚节目上出现了很多优秀的作品,当然还有一个节目,在那一年火遍了大江南北2006年的《吉祥三宝》。相信至今大家都会演唱,且传唱程度十分的广泛。如今已经14年过……
酒店水床有啥好处?为何深受情侣喜爱,前台非常实用旅游业的快速发展,也带动了相关产业的发展,比如说酒店行业,为了满足不同消费者的需求,酒店行业也是不断地在推陈出新,以吸收更多的客源,水床的发明与应用,就是酒店行业的一大创新。……
西方艺术鉴赏克里姆特黄金之吻如果我们用一幅画被复制的数量作为衡量标准的话,那么今天我们就要讲到一幅旷世绝作《吻》,奥地利维也纳美景宫里,这幅《吻》被人群围得水泄不通,《吻》的衍生品丰富多彩,小到钥匙扣,T……
洪水泛滥,美国黄石公园34年来首次关闭当地时间2022年6月13日,美国蒙大拿州,黄石国家公园加德纳河水位上涨,冲垮了一部分道路。美国黄石国家公园13日遭洪水侵袭,路桥毁坏,电力中断,游客撤离,公园所有5个入……
从梦华录里活的宋韵想到的要问近来哪部剧全网最热,《梦华录》无疑能上榜。自开播以来,该剧成为各大社交平台热搜榜的常客,豆瓣评分一度奔8。8,成为年度现象级热剧。虽然随着剧情的发展,围绕该剧的争议不……
港圈女神婚纱神图大赏,个个惊艳四座,她们的美无法复刻港圈女神婚纱神图大赏,个个惊艳四座,她们的美无法复刻!在香港影视蓬勃发展的年代,一批又一批的港圈女神横空出世,赏心悦目,点亮荧幕,当这些女神们穿上婚纱的时候,更是个个堪称……
这六家公司散户正在疯狂出逃,但外资却在大举加仓如果你想在四月打赢一场漂亮的投资翻身仗,那么这六家公司我都真心建议你加入到自选,因为我发现他们散户正在疯狂出逃,但外资却在大举加仓。众所周知,主力在拉升抑制个股之前,通常……
苹果又要放弃老机型,iOS17将不支持3GB内存设备,你的老WWDC即将在6月召开,苹果将正式公布iOS、iPadOS17系统,目前有关iOS17的设计细节已经被大量曝光。新系统将会带来一些重要的变化,例如控制中心和搜索体验会有大……
浙江婺城春日苗农忙行商变坐商盆景变风景天气放晴,村民忙于苗木养护。田双双摄中新网金华4月14日电(董易鑫曹静怡)近日春光好,刚种下去上百株苗木,等待六月嫁接起来,开出来的花可漂亮了。近日,浙江金华婺城区罗店镇……
菏泽凉皮寒了心,老百姓要的不是退15元,是有德的商家最近,菏泽凉皮事件在网上引起了轩然大波。一名游客在牡丹园景区买了一份15元的凉皮,发现味道不对,要求退货,却遭到商家的拒绝和辱骂。据说,菏泽牡丹园耗资十个亿打造,宣……
午子寻茶午子寻茶文王印明每个人都有自己喜欢的味道。多年前,应文友之邀,品尝了一杯午子仙毫,满口生香,直透心底。从此,我便与茶结缘,怎么也忘不了那沁心的香味。闲下来时品一杯香……
又进一步!华为公布量子芯片专利,能节省很多芯片一群孤独创业的中年人团队,欢迎志同道合的同志讨论分享心得近段时间,华为余承东公布了一项量子芯片和量子计算机相关专利,据说这项技术可以大大提高量子芯片的良品率,并降低其制作……