Python数据分析及可视化实例之存储方式简介

发布时间:2021-12-03 公开文章

1.简介

 

 

 

 

关于数据存储方式的选择,没有什么可以讨论的。

各有优缺,你熟悉哪个就用哪个。

比如我自己熟悉MongoDB,我就推荐它。

 

2.MongoDB介绍

# 这篇文章是在3年前我刚开始接触MongoDB的时候查看到的,从收藏夹翻出来供大家参考。

在过去的很长一段时间中,关系型数据库(Relational Database Management System)一直是最主流的数据库解决方案,他运用真实世界中事物与关系来解释数据库中抽象的数据架构。然而,在信息技术爆炸式发展的今天,大数据已经成为了继云计算,物联网后新的技术革命,关系型数据库在处理大数据量时已经开始吃力,开发者只能通过不断地优化数据库来解决数据量的问题,但优化毕竟不是一个长期方案,所以人们提出了一种新的数据库解决方案来迎接大数据时代的到来——NoSQL(非关系型数据库)

 

  NoSQL非常年轻,但他拥有的众多优秀的特性已经让众多企业和开发者开始接受,让我们来看一下来自于美国数据库知识网站DB-engines上个月的数据库排名情况。

 

 

 

 

 

 

 

  从排名中可以看到MongoDB数据库从众多的RDBMS(关系型数据库)中脱颖而出,已经成为第五名,并且还在不断上升中。

 

 

 

 

 

 

 

  如果将数据库比喻成人类的话,那么MongoDB完全可以说是神童了,年仅5岁的他单枪匹马挑战一群叔叔级别的人物,并且按照近几年的发展速度来看,他也即将超越PgSQL成为第四名,虽然距离前方三位有着NB爹的富二代还有一定的距离,但在这样一个技术爆炸的年代还有什么不可能的事呢?

 

为什么选择MongoDB?

 

1.性能

  在大数据时代中,大数据量的处理已经成了考量一个数据库最重要的原因之一。而MongoDB的一个主要目标就是尽可能的让数据库保持卓越的性能,这很大程度地决定了MongoDB的设计。在一个以传统机械硬盘为主导的年代,硬盘很可能会成为性能的短板,而MongoDB选择了最大程度而利用内存资源用作缓存来换取卓越的性能,并且会自动选择速度最快的索引来进行查询。MongoDB尽可能精简数据库,将尽可能多的操作交给客户端,这种方式也是MongoDB能够保持卓越性能的原因之一。

 

2.扩展

  现在互联网的数据量已经从过去的MB、GB变为了现在的TB级别,单一的数据库显然已经无法承受,扩展性成为重要的话题,然而现在的开发人员常常在选择扩展方式的时候犯了难,到底是选择横向扩展还是纵向扩展呢?

——————————————————————————————————————————————————————————————

横向扩展(scale out)是以增加分区的方式将数据库拆分成不同的区块来分布到不同的机器中来,这样的优势是扩展成本低但管理困难。

 

纵向扩展(scale up) 纵向扩展与横向扩展不同的是他会将原本的服务器进行升级,让其拥有更强大的计算能力。这样的优势是易于管理无需考虑扩展带来的众多问题,但缺点也显而易见,那就是成本高。一台大型机的价格往往非常昂贵,并且这样的升级在数据达到极限时,可能就找不到计算能力更为强大的机器了。

———————————————————————————————————————————————————————————————

  而MongoDB选择的是更为经济的横向扩展,他可以很容易的将数据拆分至不同的服务器中。而且在获取数据时开发者也无需考虑多服务器带来的问题,MongoDB可以将开发者的请求自动路由到正确的服务器中,让开发者脱离横向扩展带来的弊病,更专注于程序的开发上。

 

3.使用

  MongoDB采用的是NoSQL的设计方式,可以更加灵活的操作数据。在进行传统的RDBMS中你一定遇到过几十行甚至上百行的复杂SQL语句,传统的RDBMS的SQL语句中包含着大量关联,子查询等语句,在增加复杂性的同时还让性能调优变得更加困难。MongoDB的面向文档(document-oriented)设计中采用更为灵活的文档来作为数据模型用来取代RDBMS中的行,面向文档的设计让开发人员获取数据的方式更加灵活,甚至于开发人员仅用一条语句即可查询复杂的嵌套关系,让开发人员不必为了获取数据而绞尽脑汁。

 

 

NoSQL对传统数据库设计思维的影响

 

1.预设计模式与动态模式

传统数据库设计思维中,项目的设计阶段需要对数据库表中的字段名称、字段类型、进行规定,如果尝试插入不符合设计的数据,数据库不会接受这条数据以保证数据的完整性。

--数据库字段:NAME, SONG

INSERT INTO T_INFO VALUES('John','Come Together');  --成功

INSERT INTO T_INFO VALUES('小明', 20, 'xiaoming@111.com');  --失败

 

 NoSQL采用的是对集合(类似"表")中的文档(类似于"行")进行动态追加,在创建集合之初不会对数据类型进行限定,任何文档都可以追加到任何集合中去,例如我们可以将这样两条文档添加到一个集合中去:

{"name" : "John", "song" : "Come Together"}

{"name" : "小明",  "age":"20", "email" : "xiaoming@111.com"}

 

  MongoDB中文档的格式类似于我们常见的JSON,由此可见,我们第一个拥有"name"、"song"两个字段,而第二个拥有"name"、"age"、"email"三个字段,这在预设计模式中的数据库是不可能插入成功的,但在MongoDB的动态模式是可以的,这样做的优势是我们不必为一些数量很少,但种类很多的字段单独设计一张表,可以将他们集中在单独一张表进行存储,但这样做的弊病也是显而易见的,我们在获取数据时需要对同一张表的不同文档进行区分,增加了开发上的代码量。所以在设计之初需要权衡动态模式的优劣来选择表中的数据类型。

 

2.范式化与反范式化

 

范式化(normalization)是关系模型的发明者埃德加·科德于1970年提出这一概念,范式化会将数据分散到不同的表中,利用关系模型进行关联,由此带来的优点是,在后期进行修改时,不会影响到与其关联的数据,仅对自身修改即可完成。

反范式化(denormalization)是针对范式化提出的相反理念,反范式化会将当前文档的数据集中存放在本表中,而不会采用拆分的方式进行存储。

 

  范式化和反范式化之间不存在优劣的问题,范式化的好处是可以在我们写入、修改、删除时的提供更高性能,而反范式化可以提高我们在查询时的性能。当然NoSQL中是不存在关联查询的,以此提高查询性能,但我们依旧可以以在表中存储关联表ID的方式进行范式化。但由此可见,NoSQL的理念中反范式化的地位是大于范式化的。

 

MongoDB还年轻

 

  MongoDB又有众多卓越的设计,但MongoDB依然存在着许多不擅长的问题,其中包括:

 

1. MongoDB不支持事务,现在众多的软件依旧需要事务的管理,所以对于事务一致性要求较高的程序只能在软件层面进行管理,而无法从数据库进行管理。

2. 其他工具的支持范围,MongoDB从发布起到现在还不到5年的时间,所以会面临着许多的语言没有对应的工具包,所以如果你使用的语言没有对应的包,可能是导致你无法使用MongoDB最大的阻碍。

3. 社区的资源量,这个问题同第二个问题一样是因为MongoDB过于年轻导致的,相对于其他大型数据库的社区而言,MongoDB显然是无法与之相比的,然而社区往往也是一个重要考量因素之一,社区资源的匮乏会导致问题解决周期延长,从而拖延工作。

 

  近几年的技术发展之快是激动人心的,每年都会出现让人眼前一亮的产品,然而它都需要经过时间的累积才能成为一个成熟的产品,MongoDB还需要成长,但他优秀的设计,肯定会让越来越多的开发者接受它。

 

补充优点:迁移方便、地理坐标聚合、分布式存储;这货就是为大数据而生的。

 

顺手搜了一下2017年1月全球数据库排名TOP 20:

DB-Engines:2017年1月全球数据库排名TOP 20

 

 

 

 

 

 

 


 

Step1.配置 yum

vim /etc/yum.repos.d/MongoDB-org-3.4.repo

在其中输入

[mongodb-org-3.4]
name=MongoDB _cke_saved_name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/testing/x86_64/
gpgcheck=1
enabled=1 
gpgkey=https://www.mongodb.org/static/pgp/server-3.4.asc

 

然后输入如下命令进行安装

sudo yum install -y mongodb-org

 

如果想要安装其他版本的Mongodb可以点开参考链接里面有更详细的安装指南。

服务管理

service mongod start #启动
service mongod stop #停止
service mongod restart #重启

 

Step2.配置Mongodb

配置文件路径: /etc/mongod.conf。

若要自己指定数据存储位置和日志的存储位置,我们可以修改MongoDB的配置文件。

举个例子:

若要将数据文件存储在 /home/data/mongo

日志文件存储在 /home/data/log/mongodb.log

注意: 这两个存储的位置要给MongoDB足够的权限来操作,否则会报错

则将配置文件对应部分修改,其他不变

# where to write logging data.
systemLog:
destination: file
logAppend: true
path: /home/data/log/mongod.log
# Where and how to store data.
storage:
dbPath: /home/data/mongo
journal:
enabled: true

 

然后,通过指定配置文件启动MongoDB。

mongod -f /etc/mongod.conf

 

默认会在后台运行,出现信息

about to fork child process, waiting until server is ready for connections.

forked process: 10286

child process started successfully, parent exiting

如果没有后台运行,可以检查配置文件中

# how the process runs

processManagement:

fork: true # 这里是不是 true

直接使用命令来后台运行MongoDB

mongod –fork –dbpath [dbpath] –logpath [logpath]

这里 [dbpath] 是数据文件夹的路径,[logpath] 是日志文件的路径。
例如,还是上面的存储位置,
数据文件存储在 /home/data/mongo
日志文件存储在 /home/data/log/mongodb.log
mongod –fork –dbpath /home/data/mongo –logpath /home/data/log/mongodb.log
关闭后台运行

 

Step3.终端运行

mongo
use admin
db.shutdownServer()

提示:

启动服务前,先查看一下端口是否被占用,若被占用可以添加 –port 参数来指定端口。

netstat -ap | grep [port]

 

关闭后台运行的指定了其他端口的MongoDB,连接数据库时也要加端口号。

mongo localhost:port

Step4.消除警告

[root@yeayee.com ~]# mongo

MongoDB shell version v3.4.0

connecting to: mongodb://127.0.0.1:27017

MongoDB server version: 3.4.0

Server has startup warnings:

2016-12-13T15:46:47.201+0800 I STORAGE [initandlisten]

2016-12-13T15:46:47.889+0800 I CONTROL [initandlisten]

2016-12-13T15:46:47.889+0800 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database.

2016-12-13T15:46:47.889+0800 I CONTROL [initandlisten] ** Read
and write access to data and configuration is unrestricted.

2016-12-13T15:46:47.889+0800 I CONTROL [initandlisten] ** WARNING: You
are running this process as the root user, which is not recommended.

2016-12-13T15:46:47.889+0800 I CONTROL [initandlisten]

2016-12-13T15:46:47.889+0800 I CONTROL [initandlisten]

2016-12-13T15:46:47.889+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.

2016-12-13T15:46:47.889+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'

2016-12-13T15:46:47.890+0800 I CONTROL [initandlisten]

2016-12-13T15:46:47.890+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.

2016-12-13T15:46:47.890+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'

2016-12-13T15:46:47.890+0800 I CONTROL [initandlisten]


消除警告

vi /etc/rc.local

if test -f /sys/kernel/mm/transparent_hugepage/enabled; then

echo never > /sys/kernel/mm/transparent_hugepage/enabled

fi

if test -f /sys/kernel/mm/transparent_hugepage/defrag; then

echo never > /sys/kernel/mm/transparent_hugepage/defrag

fi

ulimit -u 65535


[root@yeayee.com ~]# echo never > /sys/kernel/mm/transparent_hugepage/enabled

[root@yeayee.com ~]# echo never > /sys/kernel/mm/transparent_hugepage/defrag

停止服务:

> use admin

switched to db admin

> db.shutdownServer();

server should be down...

2016-12-13T16:22:14.996+0800 I NETWORK [main] trying reconnect to 127.0.0.1:27017 (127.0.0.1) failed

2016-12-13T16:22:14.997+0800 W NETWORK [main] Failed to connect to 127.0.0.1:27017, reason: Connection refused

2016-12-13T16:22:14.997+0800 I NETWORK [main] reconnect 127.0.0.1:27017 (127.0.0.1) failed failed


>

>

>

> quit

function quit() {

[native code]

}

> exit

bye