從json到python解析python,從bson到monogdb


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)都會使用這種抽象。

當Client端要將寫入文檔,使用查詢等等操作時,需要將文檔編碼為BSON格式,然后再發送給Server端。同樣,Server端的返回結果也是編碼為BSON格式再放回給Client端的。

MongoDB以BSON做為其存儲結構的一種重要原因是其可遍歷性。

使用BSON格式出於以下3種目的:
  • 效率

    BSON是為效率而設計的,它只需要使用很少的空間。即使在最壞的情況下,BSON格式也比JSON格式再最好的情況下存儲效率高。

  • 傳輸性

    在某些情況下,BSON會犧牲額外的空間讓數據的傳輸更加方便。比如,字符串的傳輸的前綴會標識字符串的長度,而不是在字符串的末尾打上結束的標記。這樣的傳輸形式有利於MongoDB修改傳輸的數據

  • 性能
    BSON格式的編碼和解碼都是非常快速的。它使用了C風格的數據表現形式,這樣在各種語言中都可以高效地使用。

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數據類型的比較與排序優先級

  1. MinKey (internal type)
  2. Null
  3. Numbers (ints, longs, doubles)
  4. Symbol, String
  5. Object
  6. Array
  7. BinData
  8. ObjectId
  9. Boolean
  10. Date
  11. Timestamp
  12. Regular Expression
  13. MaxKey (internal type)

2.3格式案例

BSon和JSON一樣,支持內嵌的文檔對象和數組對象,但是BSON有JSON沒有的一些數據類型,如Date和BinData類型。
1.簡單型
{
    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

數據文件

在MongoDB的數據文件夾中(默認路徑是/data/db)由構成數據庫的所有文件。 每一個數據庫都包含一個.ns文件和一些數據文件,其中數據文件會隨着數據量的增加而變多。
所以如果有一個數據庫名字叫做foo,那么構成foo這個數據庫的文件就會由foo.ns,foo.0,foo.1,foo.2等等組成。
數據文件每新增一次,大小都會是上一個數據文件的2倍,每個數據文件最大2G。這樣的設計有利於防止數據量較小的數據庫浪費過多的空間,同時又能保證數據量較大的數據庫有相應的空間使用。
MongoDB會使用預分配方式來保證寫入性能的穩定(這種方式可以使用–noprealloc關閉), 預分配的方式可以減少碎片。預分配在后台進行,並且每個預分配的文件都用0進行填充。這會讓MongoDB始終保持額外的空間和空余的數據文件,從而避免了數據增長過快而帶來的分配磁盤空間引起的阻塞。

名字空間和盤區

每一個數據庫都由多個名字空間組成,每一個名字空間存儲了相應類型的數據。數據庫中的每一個Collection都有各自對應的名字空間,索引文件同樣也有名字空間。所有名字空間的元數據都存儲在.ns文件中。

名字空間中的數據在磁盤中分為多個區間,這個叫做盤區。在下圖中,foo這個數據庫包含3個數據文件,第三個數據文件屬於空的預分配文件。頭兩個數據文件被分為了相應的盤區對應不同的名字空間。

每一個名字空間可以包含多個不同的盤區,這些盤區並不是連續的。與數據文件的增長相同,每一個名字空間對應的盤區大小的也是隨着分配的次數不斷增長的。
這樣做的目的是為了平衡名字空間浪費的空間與保持某一個名字空間中數據的連續性。還有一個需要注意的名字空間: $freelist,這個名字空間用於記錄不再使用的盤區(被刪除的Collection或索引)。
每當名字空間需要分配新的盤區的時候,都會先查看$freelist是否有大小合適的盤區可以使用。

內存映射存儲引擎

MongoDB目前支持的存儲引擎為內存映射引擎當MongoDB啟動的時候,會將所有的數據文件映射到內存中,然后操作系統會托管所有的磁盤操作。

(這里的意思就是,MongoDB中的數據可以通過Java中的new操作設置一個對象,進而將對象映射到內存中,內存根據指針等實現對磁盤的操作)

這種存儲引擎有以下幾種特點:

  1. MongoDB中關於內存管理的代碼非常精簡,畢竟相關的工作已經有操作系統進行托管。
  2.  MongoDB服務器使用的虛擬內存將非常巨大,並將超過整個數據文件的大小。不用擔心,操作系統會去處理這一切。
  3. MongoDB無法控制數據寫入磁盤的順序,這樣將導致MongoDB無法實現writeahead日志的特性。所以,如果MongoDB希望提供一種durability的特性,需要實現另外一種存儲引擎。
  4.  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 //隨機數

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM