1.JSON
JSON是JavaScript Object Notation的縮寫,中文譯為JavaScript對象表示法。用來作為數據交換的文本格式,作用類似於XML,而2001年Douglas Crockford提出的目的就是為了取代XML,它不是一種編程語言,僅用來描述數據結構。
它只是一個字符串,它只是一個有規則的字符串,或者說帶有特定數據結構的字符串。(重點)然后它的表達(表現)形式是鍵值對的。
JSON基於兩種結構:"名稱/值”對 的集合(A collection of name/value pairs),在不同的編程語言中有不同的描述
如:對象(object),紀錄(record),結構(struct),字典(dictionary) 哈希表(hash table),有鍵列表(keyed list),或者關聯數組 (associative array) 值的有序列表。
在大部分語言中,它被實現為數組(array),矢量(vector),列表(list),序列(sequence)
1.2、JSON語法規則
JSON的語法可以表示以下三種類型的值:簡單值、JSON對象和數組。
(1)簡單值
// 簡單值 "Hello World!" // 字符串 99 // 數值 true // 布爾型 false // 布爾型 null // 在JSON中不能使用的值 NaN // 數值不能是NaN Infinity // 數值不能是Infinity undefined // 在JSON也不可以使用JavaScript中的undefined 'Hello World!' // 字符串必須使用雙引號表示,不能使用單引號 0x1 // 數值必須以十進制表示,不能使用十六進制
(2)對象
對象是一組有序的鍵值對的數據組成的數據類型。鍵值對中,值可以是簡單值,也可以是對象和數組(數組也是用來表示JSON的數據類型)
// 對象,對象的屬性名必須使用雙引號,值要是字符串也必須使用雙引號 { "name": "Andy", "age": 18, "isStudent": true, "isLeader": false, "mark": null, "school": { "name": "BIT", "region": "Beijing" // 這個地方不能有逗號,因為是對象的最后一個屬性成員 } // 這個地方也不可以有逗號,因為也是對象的最后一個屬性成員 }
(3)數組
數組是由一組有序的數組組成的列表。在數組中,值可以是簡單值,也可以是對象和數組。
// 示例一 ["Andy", "Ruby", "Danny", "Peter", "Lisa"] // 示例二 [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] // 示例三 [ {"name": "Andy", "age": 18}, {"name": "Ruby", "age": 18}, {"name": "Danny", "age": 20} ] // 示例四 [ [0, 1, 2], [3, 4, 5], [6, 7, 8] ]
2.2python解析json
使用Python編碼和解析Json
Python內置了json包來幫助我們完成對json的操作。
將Python的字典結構導出到json使用json.dumps()
,將json讀成Python的字典結構,使用json.loads()
。
如果不是針對string操作而是對文件操作,分別使用json.load()
函數和json.dump()
函數。
import json python_data = { 'name' : 'wqbin', 'shares' : 100, 'price' : 542.23 } json_str = json.dumps(python_data) python_data = json.loads(json_str) # Writing JSON python_data to file with open('python_data.json', 'w') as f: json.dump(python_data, f) # Reading python_data back with open('python_data.json', 'r') as f: python_data = json.load(f)
python數據類型與json數據類型對比:
2.Bson
2.1 bson的概念
BSON(Binary Serialized Document Format)是一種類json的一種二進制形式的存儲格式,簡稱Binary JSON,它和JSON一樣,支持內嵌的文檔對象和數組對象,但是BSON有JSON沒有的一些數據類型,如Date和BinData類型。
BSON可以做為網絡數據交換的一種存儲形式,這個有點類似於Google的Protocol Buffer,但是BSON是一種schema-less的存儲形式,它的優點是靈活性高,但它的缺點是空間利用率不是很理想。
BSON有三個特點:輕量性、可遍歷性、高效性。
{“hello":"world"} 這是一個BSON的例子,其中"hello"是key name,它一般是cstring類型,字節表示是cstring::= (byte*) "/x00" ,其中*表示零個或多個byte字節,/x00表示結束符;后面的"world"是value值,它的類型一般是string,double,array,binarydata等類型。
2.2 使用情況
MongoDB使用了BSON這種結構來存儲數據和網絡數據交換。
把這種格式轉化成文檔(Document)這個概念,因為BSON是schema-free的,所以在MongoDB中所對應的文檔也有這個特征,這里的一個Document也可以理解成關系數據庫中的一條記錄(Record),
文檔是對數據的抽象,它被使用在Client端和Server端的交互中。所有的Client端(各種語言的Driver)都會使用這種抽象。
MongoDB以BSON做為其存儲結構的一種重要原因是其可遍歷性。
-
效率
BSON是為效率而設計的,它只需要使用很少的空間。即使在最壞的情況下,BSON格式也比JSON格式再最好的情況下存儲效率高。
- 傳輸性
在某些情況下,BSON會犧牲額外的空間讓數據的傳輸更加方便。比如,字符串的傳輸的前綴會標識字符串的長度,而不是在字符串的末尾打上結束的標記。這樣的傳輸形式有利於MongoDB修改傳輸的數據。
- 性能
2.3數據類型演示
//null值 db.mycol.insert({x:null}) WriteResult({ "nInserted" : 1 }) //布爾型 db.mycol.insert({x:true}) WriteResult({ "nInserted" : 1 }) //小數 db.mycol.insert({x:3.1515}) WriteResult({ "nInserted" : 1 }) //整數 db.mycol.insert({x:3}) WriteResult({ "nInserted" : 1 }) //4字節帶符合整數 db.mycol.insert({x:NumberInt("3")}) WriteResult({ "nInserted" : 1 }) //8字節帶符號整數 db.mycol.insert({x:NumberLong("3")}) WriteResult({ "nInserted" : 1 }) //字符型 db.mycol.insert({x:"robin"}) WriteResult({ "nInserted" : 1 }) //日期型 db.mycol.insert({x:new Date()}) WriteResult({ "nInserted" : 1 }) //正則表達式 db.mycol.insert({x:/u01/i}) WriteResult({ "nInserted" : 1 }) //數組 db.mycol.insert({x:["a","b","c"]}) WriteResult({ "nInserted" : 1 }) //嵌套文檔 db.mycol.insert({x:{y:"nested"}}) WriteResult({ "nInserted" : 1 }) //對象id db.mycol.insert({x:ObjectId()}) WriteResult({ "nInserted" : 1 }) //代碼段 db.mycol.insert({x:function(){/ This is a test code /}}) WriteResult({ "nInserted" : 1 }) //undefined類型 db.mycol.insert({name:undefined}); WriteResult({ “nInserted” : 1 })
mongoDB數據類型的比較與排序優先級
- MinKey (internal type)
- Null
- Numbers (ints, longs, doubles)
- Symbol, String
- Object
- Array
- BinData
- ObjectId
- Boolean
- Date
- Timestamp
- Regular Expression
- MaxKey (internal type)
2.3格式案例
{ title:"MongoDB", last_editor:"192.168.1.122", last_modified:new Date("27/06/2011"), body:"MongoDB introduction", categories:["Database","NoSQL","BSON"], revieved:false }
2.復雜嵌套型
{ name:"lemo", age:"12", address:{ city:"suzhou", country:"china", code:215000 }, scores:[ {"name":"english","grade:3.0}, {"name":"chinese","grade:2.0} ] }
2.4mongo與Bson
數據文件
名字空間和盤區
每一個數據庫都由多個名字空間組成,每一個名字空間存儲了相應類型的數據。數據庫中的每一個Collection都有各自對應的名字空間,索引文件同樣也有名字空間。所有名字空間的元數據都存儲在.ns文件中。
名字空間中的數據在磁盤中分為多個區間,這個叫做盤區。在下圖中,foo這個數據庫包含3個數據文件,第三個數據文件屬於空的預分配文件。頭兩個數據文件被分為了相應的盤區對應不同的名字空間。
內存映射存儲引擎
MongoDB目前支持的存儲引擎為內存映射引擎。當MongoDB啟動的時候,會將所有的數據文件映射到內存中,然后操作系統會托管所有的磁盤操作。
(這里的意思就是,MongoDB中的數據可以通過Java中的new操作設置一個對象,進而將對象映射到內存中,內存根據指針等實現對磁盤的操作)
這種存儲引擎有以下幾種特點:
- MongoDB中關於內存管理的代碼非常精簡,畢竟相關的工作已經有操作系統進行托管。
- MongoDB服務器使用的虛擬內存將非常巨大,並將超過整個數據文件的大小。不用擔心,操作系統會去處理這一切。
- MongoDB無法控制數據寫入磁盤的順序,這樣將導致MongoDB無法實現writeahead日志的特性。所以,如果MongoDB希望提供一種durability的特性,需要實現另外一種存儲引擎。
- 32位系統的MongoDB服務器每一個Mongod實例只能使用2G的數據文件。這是由於地址指針只能支持32位。
關於_id與Object_Id
mongoDB中每一個文檔都必須有一個"_id"鍵,該鍵等同於RDBMS中的主鍵,只不過這個主鍵是由mongoDB自動生成
"_id"鍵的值可以使用任意類型,可以不使用系統創建,而由用戶自定義的規則生成
"_id"為輕量級,全局唯一,可類比為MySQL數據中的GTID,也用於解決不同機器副本集復制時唯一性問題
a 4-byte value representing the seconds since the Unix epoch, //時間戳 a 3-byte machine identifier, //機器唯一標識碼 a 2-byte process id, and //進程ID a 3-byte counter, starting with a random value. //隨機數
db.mycol.findOne() { “_id” : ObjectId(“57ce2d4cce8685a6fd9df3a3”), “x” : null } 57ce2d4c //時間戳 ==>1473129804 ==> 2016/9/6 10:43:24 ce8685 //機器唯一標識碼 a6fd //進程ID 9df3a3 //隨機數