MongoDB 入門篇
在了解MongoDB之前需要先了解先資料庫管理系統
資料(英語:data),是指未經過處理的原始記錄。
一般而言,資料缺乏組織及分類,無法明确的表達事物代表的意義,它可能是一堆的雜志、一大疊的報紙、數種的開會記錄或是整本病人的病曆紀錄。資料描述事物的符号記錄,是可定義為意義的實體,涉及事物的存在形式。是關于事件之一組離散且客觀的事實描述,是構成訊息和知識的原始材料。
資料庫管理系統(英語:database management system,縮寫:DBMS) 是一種針對對象資料庫,為管理資料庫而設計的大型電腦軟體管理系統。
具有代表性的資料管理系統有:Oracle、Microsoft SQL Server、Access、MySQL及PostgreSQL等。通常資料庫管理師會使用資料庫管理系統來建立資料庫系統。
現代DBMS使用不同的資料庫模型追蹤實體、屬性和關系。在個人電腦、大型計算機和主機上應用最廣泛的資料庫管理系統是關系型DBMS(relational DBMS)。在關系型資料模型中,用二維表格表示資料庫中的資料。這些表格稱為關系。
資料庫管理系統主要分為倆大類:RDBMS、NOSQL
關于RDBMS的更多資訊參考:http://www.cnblogs.com/clsn/category/1131345.html
常見的資料庫管理系統,及其排名情況如下:
圖 - 資料庫管理系統使用情況世界排名
資料來源:https://db-engines.com/en/ranking
NoSQL是對不同于傳統的關系資料庫的資料庫管理系統的統稱。
兩者存在許多顯著的不同點,其中最重要的是NoSQL不使用SQL作為查詢語言。其資料存儲可以不需要固定的表格模式,也經常會避免使用SQL的JOIN操作,一般有水準可擴充性的特征。
NoSQL一詞最早出現于1998年,是Carlo Strozzi開發的一個輕量、開源、不提供SQL功能的關系資料庫。
2009年,Last.fm的Johan Oskarsson發起了一次關于分布式開源資料庫的讨論,來自Rackspace的Eric Evans再次提出了NoSQL的概念,這時的NoSQL主要指非關系型、分布式、不提供ACID的資料庫設計模式。
2009年在亞特蘭大舉行的"no:sql(east)"讨論會是一個裡程碑,其口号是"select fun, profit from real_world where relational=false;"。是以,對NoSQL最普遍的解釋是“非關聯型的”,強調Key-Value Stores和文檔資料庫的優點,而不是單純的反對RDBMS。
基于2014年的收入,NoSQL市場領先企業是MarkLogic,MongoDB和Datastax。基于2015年的人氣排名,最受歡迎的NoSQL資料庫是MongoDB,Apache Cassandra和Redis.
NoSQL中的四大家族主要是:列存儲、鍵值、圖像存儲、文檔存儲,其類型産品主要有以下這些。
存儲類型
NoSQL
鍵值存儲
最終一緻性鍵值存儲
Cassandra、Dynamo、Riak、Hibari、Virtuoso、Voldemort
記憶體鍵值存儲
Memcached、Redis、Oracle Coherence、NCache、 Hazelcast、Tuple space、Velocity
持久化鍵值存儲
BigTable、LevelDB、Tokyo Cabinet、Tarantool、TreapDB、Tuple space
文檔存儲
MongoDB、CouchDB、SimpleDB、 Terrastore 、 BaseX 、Clusterpoint 、 Riak、No2DB
圖存儲
FlockDB、DEX、Neo4J、AllegroGraph、InfiniteGraph、OrientDB、Pregel
列存儲
Hbase、Cassandra、Hypertable
高可擴充性、分布式計算、沒有複雜的關系、低成本
架構靈活、半結構化資料
RDBMS
代表着不僅僅是SQL
沒有聲明性查詢語言
沒有預定義的模式
鍵 - 值對存儲,列存儲,文檔存儲,圖形資料庫
最終一緻性,而非ACID屬性
非結構化和不可預知的資料
CAP定理
高性能,高可用性和可伸縮性
高度組織化結構化資料
結構化查詢語言(SQL) (SQL)
資料和關系都存儲在單獨的表中。
資料操縱語言,資料定義語言
嚴格的一緻性
基礎事務
MongoDB并非芒果的意思,而是源于 Humongous(巨大)一詞。
MongoDB的3大技術特色如下所示:
除了上圖所示的還支援:
二級索引、動态查詢、全文搜尋 、聚合架構、MapReduce、GridFS、地理位置索引、記憶體引擎 、地理分布等一系列的強大功能。
但是其也有些許的缺點,例如:
多表關聯: 僅僅支援Left Outer Join SQL 語句支援: 查詢為主,部分支援 多表原子事務: 不支援 多文檔原子事務:不支援 16MB 文檔大小限制,不支援中文排序 ,服務端 Javascript 性能欠佳
存儲方式對比
在傳統的關系型資料庫中,存儲方式是以表的形式存放,而在MongoDB中,以文檔的形式存在。
資料庫中的對應關系,及存儲形式的說明
MongoDB與SQL的結構對比詳解
SQL Terms/Concepts
MongoDB Terms/Concepts
database
table
collection
row
document or BSON document
column
field
index
table joins
embedded documents and linking
primary key
Specify any unique column or
column combination as
primary key.
In MongoDB, the primary key is
automatically set to the _id field.
aggregation (e.g. group by)
aggregation pipeline
See the SQL to Aggregation Mapping
Chart.
JSON格式
JSON 資料格式與語言無關,脫胎于 JavaScript,但目前很多程式設計語言都支援 JSON 格式資料的生成和解析。JSON 的官方 MIME 類型是 application/json,檔案擴充名是 .json。
MongoDB 使用JSON(JavaScript ObjectNotation)文檔存儲記錄。
JSON資料庫語句可以容易被解析。
Web 應用大量使用,NAME-VALUE 配對
BSON格式
BSON是由10gen開發的一個資料格式,目前主要用于MongoDB中,是MongoDB的資料存儲格式。BSON基于JSON格式,選擇JSON進行改造的原因主要是JSON的通用性及JSON的schemaless的特性。
二進制的JSON,JSON文檔的二進制編碼存儲格式
BSON有JSON沒有的Date和BinData
MongoDB中document以BSON形式存放
例如:
? MongoDB是開源産品
? On GitHub Url:https://github.com/mongodb
? Licensed under the AGPL,有開源的社群版本
? 起源& 贊助by MongoDB公司,提供商業版licenses 許可
這些優勢造就了mongodb的豐富的功能:
JSON 文檔模型、動态的資料模式、二級索引強大、查詢功能、自動分片、水準擴充、自動複制、高可用、文本搜尋、企業級安全、聚合架構MapReduce、大檔案存儲GridFS
自動複制和故障切換
多資料中心支援滾動維護無需關機支援最多50個成員
這種方式是目前構架上的主流形式,指的是通過增加伺服器數量來對系統擴容。在這樣的構架下,單台伺服器的配置并不會很高,可能是配置比較低、很廉價的 PC,每台機器承載着系統的一個子集,所有機器伺服器組成的叢集會比單體伺服器提供更強大、高效的系統容載量。
這樣的問題是系統構架會比單體伺服器複雜,搭建、維護都要求更高的技術背景。分片叢集架構如下圖所示:
MySQL InnoDB
MySQL NDB
Oracle
MongoDB MAPI
MongoDB WiredTiger
事務
YES
ES
NO
鎖粒度
ROW-level
Collection-level
Document-level
Geospatial
MVCC
Replication
外鍵
YES(From 7.3)
資料庫叢集
B-TREE索引
全文檢索
資料壓縮
存儲限制
64TB
384EB
表分區
YES (分片)
由下圖可以看出MongoDB資料庫的性能擴充能力及功能都較好,都能夠在資料庫中,站立一足之地。
網站資料、緩存等大尺寸、低價值的資料
在高伸縮性的場景,用于對象及JSON資料的存儲。
慎用場景
原因
PB 資料持久存儲大資料分析資料湖
Hadoop、Spark提供更多分析運算功能和工具,并行計算能力更強
MongoDB + Hadoop/Spark
搜尋場景:文檔有幾十個字段,需要按照任意字段搜尋并排序限制等
不建索引查詢太慢,索引太多影響寫入及更新操作
ERP、CRM或者類似複雜應用,幾十上百個對象互相關聯
關聯支援較弱,事務較弱
需要參與遠端事務,或者需要跨表,跨文檔原子性更新的
MongoDB 事務支援僅限于本機的單文檔事務
100% 寫可用:任何時間寫入不能停
MongoDB換主節點時候會有短暫的不可寫設計所限
應用特征
Yes/No?
我的資料量是有億萬級或者需要不斷擴容
需要2000-3000以上的讀寫每秒
新應用,需求會變,資料模型無法确定
我需要整合多個外部資料源
我的系統需要99.999%高可用
我的系統需要大量的地理位置查詢
我的系統需要提供最小的latency
我要管理的主要資料對象<10
在上面的表格中進行選擇,但有1個yes的時候:可以考慮MongoDB;當有2個以上yes的時候:不會後悔的選擇!
MongoDB官網:https://www.mongodb.com/
CentOS6.X版本軟體下載下傳位址:https://www.mongodb.org/dl/linux/x86_64-rhel62
其他版本請到進行官網下載下傳。
在安裝之前首先确認該版本軟體是否支援你的作業系統。
更多詳情檢視:https://docs.mongodb.com/manual/installation/
Platform
3.6 Community & Enterprise
3.4 Community & Enterprise
3.2 Community & Enterprise
3.0 Community & Enterprise
RHEL/CentOS 6.2 and later
✓
RHEL/CentOS 7.0 and later
系統環境說明:
軟體版本說明
在root使用者下操作
該方法僅限與CentOS系統使用,其他系統關閉參照官方文檔: https://docs.mongodb.com/manual/tutorial/transparent-huge-pages/
Transparent Huge Pages (THP),通過使用更大的記憶體頁面,可以減少具有大量記憶體的機器上的緩沖區(TLB)查找的開銷。
但是,資料庫工作負載通常對THP表現不佳,因為它們往往具有稀疏而不是連續的記憶體通路模式。您應該在Linux機器上禁用THP,以確定MongoDB的最佳性能。
建立使用者
修改使用者密碼
建立程式目錄
下載下傳程式
解壓程式
修改程式屬主
切換到mongod使用者,設定使用者環境變量
至此,MongoDB資料庫部署完成
資料庫的啟動與關閉
參數說明:
參數
參數說明
--dbpath
資料存放路徑
--logpath
日志檔案路徑
--logappend
日志輸出方式
--port
啟用端口号
--fork
在背景運作
--auth
是否需要驗證權限登入(使用者名和密碼)
--bind_ip
限制通路的ip
--shutdown
關閉資料庫
登入資料庫
使用配置檔案的方式管理資料庫:
普通格式配置檔案:
使用配置檔案時的啟動與關閉:
YAML格式配置檔案(3.X 版本官方推薦使用)
在資料庫中關閉資料庫的方法
注:
mongod程序收到SIGINT信号或者SIGTERM信号,會做一些處理 > 關閉所有打開的連接配接 > 将記憶體資料強制重新整理到磁盤 > 目前的操作執行完畢 > 安全停止 切忌kill -9 資料庫直接關閉,資料丢失,資料檔案損失,修複資料庫(成本高,有風險)
使用kill指令關閉程序
使用腳本管理mongodb服務
注:該腳本可以直接在root使用者下運作
View Code 腳本管理mongodb服務
Mongodb中關鍵字種類:
db(資料庫執行個體級别) db本身 db.connection 資料庫下的集合資訊 db.collection.xxx( rs(複制集級别) sh(分片級别)
在用戶端指定資料庫進行連接配接:(預設連接配接本機test資料庫)
檢視目前資料庫版本
切換資料庫
顯示目前資料庫
查詢所有資料庫
檢視clsn資料庫目前狀态
檢視目前資料庫的連接配接機器位址
建立資料庫
說明:
建立資料庫: 當use的時候,系統就會自動建立一個資料庫。 如果use之後沒有建立任何集合。系統就會删除這個資料庫。
删除資料庫
删除資料庫: 如果沒有選擇任何資料庫,會删除預設的test資料庫
建立集合
方法一:
檢視目前資料下的所有集合
方法二:
當插入一個文檔的時候,一個集合就會自動建立。
檢視建立的合集
檢視合集裡的内容
重命名集合
删除合集
插入1w行資料
查詢集合中的查詢所有記錄
注:預設每頁顯示20條記錄,當顯示不下的的情況下,可以用it疊代指令查詢下一頁資料。
删除集合中的記錄數
檢視集合存儲資訊
pretty()使用
MongoDB資料庫預設是沒有使用者名及密碼的,即無權限通路限制。為了友善資料庫的管理和安全,需建立資料庫使用者。
使用者中權限的說明
權限
說明
Read
允許使用者讀取指定資料庫
readWrite
允許使用者讀寫指定資料庫
dbAdmin
允許使用者在指定資料庫中執行管理函數,如索引建立、删除,檢視統計或通路system.profile
userAdmin
允許使用者向system.users集合寫入,可以找指定資料庫裡建立、删除和管理使用者
clusterAdmin
隻在admin資料庫中可用,賦予使用者所有分片和複制集相關函數的管理權限。
readAnyDatabase
隻在admin資料庫中可用,賦予使用者所有資料庫的讀權限
readWriteAnyDatabase
隻在admin資料庫中可用,賦予使用者所有資料庫的讀寫權限
userAdminAnyDatabase
隻在admin資料庫中可用,賦予使用者所有資料庫的userAdmin權限
dbAdminAnyDatabase
隻在admin資料庫中可用,賦予使用者所有資料庫的dbAdmin權限。
root
隻在admin資料庫中可用。超級賬号,超級權限
更多關于使用者權限的說明參照:https://docs.mongodb.com/manual/core/security-built-in-roles/
使用者建立文法
文法說明:
user字段:使用者的名字; pwd字段:使用者的密碼; cusomData字段:為任意内容,例如可以為使用者全名介紹; roles字段:指定使用者的角色,可以用一個空數組給新使用者設定空角色; roles 字段:可以指定内置角色和使用者定義的角色。
進入管理資料庫
建立管理使用者,root權限
注意:
建立管理者角色使用者的時候,必須到admin下建立。 删除的時候也要到相應的庫下操作。
檢視建立完使用者後的collections;
檢視建立的管理者使用者
驗證使用者是否能用
使用者建立完成後在配置檔案中開啟使用者驗證
重新開機服務
登陸測試,注意登陸時選擇admin資料庫
注意:使用者在哪個資料庫下建立的,最後加上什麼庫。
方法一:指令行中進行登陸
方法二:在資料庫中進行登陸驗證:
建立對某庫的隻讀使用者
在test庫建立隻讀使用者test
測試使用者是否建立成功
登入test使用者,并測試是否隻讀
建立某庫的讀寫使用者
建立test1使用者,權限為讀寫
檢視并測試使用者
建立對多庫不同權限的使用者
建立對app為讀寫權限,對test庫為隻讀權限的使用者
檢視并測試使用者
删除使用者
删除app使用者:先登入到admin資料庫
進入app庫删除app使用者
建立app資料庫的管理者:先登入到admin資料庫
建立app資料庫讀寫權限的使用者并具有clusterAdmin權限:
SQL語言與CRUD語言對照
SQL Schema Statements
MongoDB Schema Statements
CREATE TABLE users (
id MEDIUMINT NOT NULL
AUTO_INCREMENT,
user_id Varchar(30),
age Number,
status char(1),
PRIMARY KEY (id)
)
Implicitly created on first insert() operation. The primary
key _idis automatically added if _id field is not specified.
db.users.insert( {
user_id: "abc123",
age: 55,
status: "A"
} )
However, you can also explicitly create a collection:
db.createCollection("users")
ALTER TABLE users
ADD join_date DATETIME
在Collection 級沒有資料結構概念。然而在 document級,可以通過$set在
update操作添加列到文檔中。
db.users.update(
{ },
{ $set: { join_date: new Date() } },
{ multi: true }
DROP COLUMN join_date
在Collection 級沒有資料結構概念。然而在 document級,可以通過$unset
在update操作從文檔中删除列。
{ $unset: { join_date: "" } },
CREATE INDEX idx_user_id_asc
ON users(user_id)
db.users.createIndex( { user_id: 1 } )
CREATE INDEX
idx_user_id_asc_age_desc
ON users(user_id, age DESC)
db.users.createIndex( { user_id: 1, age: -1 } )
DROP TABLE users
db.users.drop()
插入/删除/更新 語句對比
SQL Statements
MongoDB Statements
INSERT INTO
users(user_id,
age
status)
VALUES ("bcd001",
45,
"A")
db.users.insert(
{ user_id: "bcd001", age:
45, status: "A" }
DELETE FROM users
WHERE status = "D"
db.users.remove( { status: "D" } )
db.users.remove({})
UPDATE users
SET status = "C"
WHERE age > 25
{ age: { $gt: 25 } },
{ $set: { status: "C" } },
SET age = age + 3
WHERE status = "A"
{ status: "A" } ,
{ $inc: { age: 3 } },
查詢類操作對比
SQL SELECT Statements
MongoDB find() Statements
SELECT *
FROM users
db.users.find()
SELECT id,
user_id,
status
db.users.find(
{ user_id: 1, status: 1, _id: 0 }
SELECT user_id, status
{ user_id: 1, status: 1 }
{ status: "A" }
{ status: "A" },
在登陸資料庫的時候,發現會由描述檔案相關的報錯。
解決辦法:
修改後,重新開機伺服器,即可解決該問題。
[1] https://docs.mongodb.com/manual/introduction/ [2] http://www.mongoing.com/docs/introduction.html [3] https://zh.wikipedia.org/ [4] https://docs.mongodb.com/manual/core/security-built-in-roles/