零基礎入門非關係型資料庫MongoDB,含與mysql的對比
來自專欄編程學習筆記
文件管理階段:
我們知道word文件是保存在磁碟中,當我們在寫的時候,為什麼會出現不保存就丟失數據的情況?按說磁碟是可以長期保存的啊。
那是因為寫文件是先寫入到內存,過一段時間再一起保存到磁碟,使用這種操作機制,是因為內存的讀寫速度比較快。
用文件存儲數據被編程語言調用比較麻煩(python可以用來調用excel文件,但是比較麻煩)
資料庫管理階段
優點:數據組織結構化,可以實現用多種語言調用。
缺點是:使用起來相對文件更複雜,需要使用sql或者其他特定的語句。
資料庫相關概念
數據:能夠輸入到計算機中並被識別處理的信息集合。
數據結構:研究一個數據集合中數據之間關係
資料庫:按照數據結構,存儲、管理數據的倉庫,資料庫是在資料庫管理系統的管理和控制下,在一定介質上(硬碟上)的數據集合。
資料庫管理系統:一個軟體,用於建立和維護資料庫。mysql就是資料庫管理系統。
資料庫系統:由資料庫和資料庫管理系統,開發工具等組成的集合。
分類:
關係型和非關係型資料庫
關係型資料庫:採用關係模型(二維表)來組織數據結構的資料庫。資料庫管理系統mysql,oracle,DB2,sql server,Sqlite。
大型資料庫是oracle,DB2。
學校里學的通常是sql server,盜版非常多,中國中小公司很多用sql server。
網站的開發用mysql比較多。
Sqlite是python可以直接操作,標準庫支持,不用安裝第三方庫,常用於嵌入式設備上的資料庫,比如手機,只能設備等,輕量級。
現在的資料庫無論是關係型還是非關係型基本都跨平台,已經不算是優點了。
所以我們這裡說的優點,都是指相對優點。
相比非關係型資料庫的優點:
1.容易理解,類似我們常見的表格,有行有列。
2.使用方便,關係型資料庫都是用sql語句操作,只是個別命令不同,非常成熟。
3.數據一致性高,冗餘度低,完整性好
4.技術成熟,可以使用外部連接等比較複雜的操作
缺點:
1.不能很好的滿足高並發(同時有大量的客戶端請求操作資料庫)的需求,每次都需要進行sql語句的解析
2.針對海量數據瞬間爆發,讀寫性能不足。關係型內部每次操作都需要加鎖,保證操作的原子性。
3.數據擴展普遍比非關係型困難。二維表不好拆分。
4.數據一致性高(雙刃劍),有時會浪費大量空間。有些記錄的欄位是可以為空的,比如一個人的微信,QQ,郵箱可能只填了其中一種。
針對這些缺點,非關係型數據這種解決方案應運而生。
非關係型資料庫(統稱NoSql---Not only Sql):
版本更新比較快,相對不是那麼成熟。市面上還是使用關係型比較多。那為什麼要使用它呢?技術是有適用場景的,沒有絕對的好與不好。
優點:
1.高並發,大數據讀寫能力強。在執行時省去解析sql語句的那一步
2.支持分散式,容易擴展。
分散式:一台伺服器滿足不了需求,讓多台伺服器同時工作來分擔,相互之間數據共享。
3.弱化了數據結構,降低了數據的一致性。
缺點:
1.通用型差,沒有像sql那樣一致性的操作,不同的非關係型資料庫的操作是不同的。比如,MongoDB和redis的操作不同。
2.操作靈活,靈活不是純優點,靈活意味著容易混亂。就好像自由不是絕對的好事。
3.沒有join,事物支持等操作。
NoSql適用場景:
1.對數據的一致性要求低
2.對資料庫並發處理要求高
3.資料庫設計時對大小的估算不確定,需要分布擴展
4.給定的數據比較容易建立起Nosql的模型
做並發性比較高的網站比較適合。
Nosql分類:
四類
1.鍵值型資料庫,以鍵值對的方式(類似字典)存儲數據,如:redis
2.列存儲資料庫。而mysql中一行一個記錄。如:Hbase。
3.文檔型資料庫。按照文檔的方式存儲,如MongoDB,CouchDB
4.圖形資料庫。
今天我們只需要知道,MongoDB屬於非關係型資料庫中的文檔型資料庫即可。
準確來說,MongoDB是資料庫管理系統,是一種軟體。這裡簡單稱為資料庫。
1.底層是由C++編寫的。
2.是最像關係型資料庫的非關係型資料庫。支持豐富的增刪改查數據操作。
3.MongDB支持的數據類型非常豐富,比mysql多。(mysql支持存儲的數據類型或格式有:數值、字元、枚舉、時間和日期,共四大類。)
4.使用方便,便於部署,支持分布,容易拓展。
5.支持眾多的編程語言介面(python,ruby,c++,PHP等),ruby是日本開發的編程語言,借鑒python,中國的編程語言是易語言。
假設我們要存儲朋友圈內容,設計關係型資料庫要怎麼做?
思路:
首先,關係型資料庫設計,確定實體和聯繫。確定有幾張表,表中欄位問題,
表和欄位:朋友與朋友圈內容是一對多的關係,朋友圈內容與評論是多對多的關係。可能需要三張表,朋友個人信息(id,age,telephone),朋友圈內容(id,content,iamge,time,addres),評論信息表(id,conten,flags(點贊標識位),time,user(用戶連接))。
用mongoDB存儲:是鍵值型資料庫的升級版,使之看起來像文檔。
{name:zhangsan,age:14,sex:14,sex:boy,friend:[{id:1,....}]}
以上對mongo有了初步了解後,下面進入動手環節。
安裝環境,MongoDB
因為是跨平台,我這裡選的是在Linux下安裝。
1.自動安裝,在linux下,sudo apt-get install mongoDB, apt-get install 是安裝軟體的命令,默認安裝位置在/var/lib/mongoDB。
配置文件位置/etc/mongodb.conf
在終端上我們用mysql命令啟動mysql軟體,在哪個文件夾都可以使用,說明mysql在環境變數當中。
各個操作系統都有環境變數,就是一個特殊目錄,凡是把目錄添加到環境變數的,這個目錄在任何目錄下都可以使用。
命令集在linux中通常是/usr/bin目錄下
2.手動安裝
1.在官網下載mongDB
www.mongdb.com, --->Download-->community server -->選擇合適版本下載。
下載完是一個.tgz的壓縮包。選擇安裝目錄(建議在/usr/local或者/opt)解壓,得到文件夾,將文件夾下的命令集目錄(bin目錄)添加到環境變數。然後重啟即可。
添加到環境中:PATH表示環境變數,
PATH=$PATH:/opt/mongo.../bin
export PATH
但是上面兩句的添加是一次性的,斷電後重啟失效、
如果將以上兩句寫在/etc/rc.local,每次啟動系統會自動執行這兩句。
(在win系統安裝簡單,下載時默認自動添加進環境變數。)
我的是手動安裝的,查看一下有哪些命令集。
$cd /opt
$ls
$cd mongodb-linux-x86_64-ubuntu1604-3.4.10
$ls
$cd bin
$ls
bsondump mongodump mongoimport mongoreplay mongostat
mongo mongoexport mongooplog mongorestore mongotop
mongod mongofiles mongoperf mongos
凡是在mongodb下的bin下的命令都是在shell命名行中可以使用的
比如上面列出的幾個命令:
mongod -- dbpath 指定路徑,設置資料庫存儲位置
mongod -- port 指定埠號,默認埠號是27017,mysql是默認埠號是3306。
mongo命令,用來進入mongo shell界面(mongdb的交互界面,用來操作資料庫)。在任意目錄下都可以使用。
ctrl+l清除屏幕 quit()退出
兩種資料庫的組織形式對比:
mysql:記錄——>表--->資料庫
mongodb:鍵值對--->文檔---集合--->資料庫
也就是說,mysql的一行記錄對應mongodb的一個文檔
示例:
{
"_id":ObjectId("abcd1234afhkasyr"),
"name":"lily",
"age":"17"
}
大括弧為一個文檔。id自動分配。
二者的概念/叫法的不同
mysql mongdb
database database
table(表) collection(集合)
column(列/欄位) field(域)
row(行/記錄) document(文檔)
index(索引) index(索引)
如何創建資料庫?
use databasename 表示創建資料庫(如果資料庫不存在就直接創建並切換,use本身是切換的意思),不用加分號。和open(「xx.txt」,w『)一樣 ,有則寫文件,無則創建文件。
使用use不會馬上創建資料庫,只有插入內容,資料庫才能真正創建,這也是對資源空間的保護。
示例:use stu
在mysql中需要先創建才能use來選擇使用哪個資料庫。
show dbs 查看系統中已有的資料庫。
裡面有一些比較特殊的已有的資料庫。
admin:存儲用戶
local:存儲本地數據
這裡是查不到剛剛use的資料庫的,因為沒有寫入東西。
在資料庫stu中插入一條文檔。
db.class1.insert({name:lily,age:17})
資料庫名稱規則:
1原則上是任意滿足以下幾條的utf-8字元,即mongo默認是utf-8的字元編碼,mysql默認是ASCII類型。
2不能是空字元,不能含有空格,及. / 符號。 在C++中是較特殊的字元,而mongdb是由C++編寫的。
3習慣上使用英文小寫,長度不超過64位元組
4不能使用admin,local,config這樣的名字。
mongdb系統全局變數
db:代表當前正在使用的資料庫,如果沒有指定資料庫,默認值是test資料庫,如果寫入數據即創建test資料庫。
資料庫創建講完後說一下資料庫的備份和恢復
備份 採用mongodb中的命令集 mongodump -h dbhost -d dbname -o dbdir
選項參數:現在的主機名,要備份哪個資料庫,備份在哪個文件中
比如 將本機下將stu資料庫備份到當前目錄的student文件夾中,會在student文件夾中自動生成一個stu文件夾則為備份文件。
在終端上運行:mongodump -h 127.0.0.1 -d stu -o student
命令集都是在shell下運行的。
恢復 mongorestore -h <dbhost>:<port> -d dbname <path>
將文件恢復到指定的主機上的資料庫中
mongorestore -h 127.0.0.1:27017 -d test student/stu
將student文件夾下的備份文件stu恢復到本機的test資料庫中。
資料庫的監測命令
mongostat監測資料庫的狀態,實時的監測。
insert query update delete對應到列表示每秒增查改刪的次數
getmore command 每秒運行命令次數
dirty used flushes 每秒操作磁碟的次數
vsize res 使用虛擬內存和物理內存的情況
mongotop監測每個資料庫的持續讀寫時長,以毫秒為單位。單個插入比較小,看不太出來。
ns 數據集合
total 總時長
read 讀時長
write 寫時長
刪除資料庫命令:
db.dropDatebase() db代表當前資料庫,刪除用函數來完成,無參數
資料庫的下一層 -->集合的創建
集合類似mysql中的表
創建方法有兩種
第二種創建集合的方法
db.createCollection(collection)第一個單詞小寫,第二個單詞首字母大寫,括弧里是字元串
在當前資料庫下創建一個名字為class2 的集合
db.createCollection("class2")
查看集合show collections/ show tables
集合的命名規則
1.不能為空字元串,不能有』 『。
2.不能以system.開頭。因為這是系統集合的保留前綴。
3.不能和保留字重複。
第二種創建集合的方法
db.collectionnName.insert(),當向一個集合中插入文檔時,如果該集合不存在則自動創建。
示例:
db.class0.insert({a:1})
用第二種方法,集合在創建後就會有數據。
用第一種方法可以創建空集合。
刪除集合
db.collectionName.drop() 刪除成功返回True。
示例:
db.class0.drop()
集合重命名
db.collectionName.renameCollection("new_name") 將原有集合進行重命名,參數是新的名字
示例:db.class2.renameCollection("class0")
集合的部分就講完了。
集合的下一層--->文檔
等同於mysql中的記錄。
對數據的增刪改查,是選定某個集合,具體操作文檔來實現的。
文檔由鍵值對組成,類似python中的字典。
但不是字典,這裡叫做bson。
mongodb中文檔的數據組織形式為bson格式。
bson是借鑒了json。
javascript讓網頁和後端進行交互。交互數據格式是json。json類似python中的字典。
比如在網頁輸入用戶名和密碼,需要在後端程序判斷,前端提交的用戶名和密碼通過json格式傳給後端。
比如{name:「張三」,password:」123「},後端用的python就要理解json是什麼意思,如果是java,就要讓java來理解這個json是什麼意思。
文檔中鍵的命名規則:
(回顧一下python中字典的鍵的命名規則:
不可變類型就可以作為鍵,列表不可以做鍵,字元串,數字,元組可以,元組做鍵時比如經緯度做坐標,植為地點。)
1.utf-8格式的字元串
2.不能有 ,習慣上不用 . $
3.以下劃線開頭的多為保留鍵(系統定義的鍵),自定義時一般不用。
注意點:
在文檔鍵值對是有序的(python字典是無序的),mongdb中嚴格區別大小寫(mysql語句中的關鍵字不區分大小寫)。鍵也叫域,相當於mysql中的欄位名。
文檔中值:mongodb所支持的數據類型。
mongodb支持的數據類型:
基於3.4版本的常用數據類型,新更新的在這裡不提。
類型 值
整型 整數
布爾類型 true,false
浮點型 小數
Arrays 數組類型[1,2,3] 類似python中的列表
Timestamp 時間戳(當前的時間點)
Date 時間日期類型
Object 內部文檔(文檔中的值還是文檔)
Null 空值
Symbol 特殊字元
String 字元串
Binary data 二進位字串
code 代碼
regex 正則表達式(一個用來匹配字元串的技術)
ObjectId ObjectId字串,自動生成主鍵,即隨機字串,保證ID唯一。系統自動為每個文檔生成的不重複的主鍵,鍵的名稱是_id,是固定的。
比如ObjectId(」5b03b.............「)
函數內的字串是24位的16進位數,前8位為文檔創建時間,後6為機器ID,後4為進程ID,後6是計數器。
數據類型和mysql可以做個對比,mongodb中的數據類型更豐富。
支持的數據類型多廣往往決定這個資料庫是否會流行起來。
一個集合中文檔特點:
1.文檔中鍵是域,相當於mysql的欄位。
文檔中想要哪個域就要哪個域,不想要就不要。比較靈活。
集合中的文檔域不一定相同,比如第一個文檔是姓名,性別,微信號,第二個文檔時姓名,性別,手機號,第三個文檔可以是姓名,姓名,郵箱。
2.集合中的文檔結構不一定相同。可能文檔嵌套文檔等。
文檔具備的這種靈活性但是帶來數據不一致的現象。因此,在設計時除了語法規則外,還需要遵循一些規則。
文檔的設計原則:
1.集合中的文檔儘可能描述的數據類似。
2.同一類文檔放在相同的集合,不同的文檔分集合存放。
3.層次的包裹不宜太多。
插入文檔:
向集合中插入文檔db.collectionName.insert()
示例:db.class0.insert({name:lily,age:15,"sex":"f"})
因為鍵只能是字元串,在插入時引號是可以不加的。
db.class0.insert({name:lily,age:15,sex:"f"})。
插入過後,查看插入的信息 db.collectionName.find()
相當於select *
如果要同時插入多條文檔,加中括弧,可以理解成是數組。
db.collectionName.insert([{},{},...])
示例:db.class0.insert([{name:花花,age:28},{name:"阿紅",age:26},{name:"阿彪",age:23}])
查看一下,會發現每個文檔都自動加入了ID
那如果自定義加入id呢,當然也是可以的,會使用自己定義的值。系統就不會再自動生成跟你定義的id相同的id。
另外一種插入方法
db.collectionName.save()
示例:db.class0.save({_id:2,name:lei,age:17})
可以插入,在不加_id時,和insert是相同的。
如果加入_id,則如果_id值不存在則正常插入,如果該_id值存在,就修改原來的內容。
再插入一個文檔:db.class0.save{_id:2,name:八戒,age:17})
返回信息:matched:1匹配到,modified:1修改了。
查看一下s
可以看到八戒把lei修改掉了,這裡是整個文檔都會修改掉,只是舉的例子比較像,看起是只修改了name。
save一次無法插入多個文檔。
說完創建之後,刪除文檔怎麼做呢?未完待更。
推薦閱讀:
※教你怎麼用EXCEL練習SQL
※如何評價cmu-db的peloton資料庫?
※機器數據的探索性分析 - SQL引擎與BI的銜接
※Oracle資料庫在違章表裡面,怎麼找出30天內違章大於3次的人?
※第五課 資料庫之mysql