| 
       咨詢電話:010-51727811/12/13
      當前位置: 首頁 > 新聞中心 > 業內新聞 >
      無模式數據庫NoSQL講解
      時間:2014-03-03 09:23  來源:飛客數據恢復   作者:飛客數據恢復工程師
      很多NoSQL 數據庫有個共同點,那就是它們都沒有模式。若要在關系型數據庫中存儲數據,首先必須定義“模式”,也就是用一種預定義結構向數據庫說明:要有哪些表格,表中有哪些列,每一列都存放何種類型的數據。必須先定義好模式,然
      后才能存放數據。
       
      相比之下,NoSQL 數據庫的數據存儲就比較隨意了。“鍵值數據庫”可以把任何數據存放在一個“鍵”的名下。“文檔數據庫”實際上也如此,因為它對所存儲的文檔結構沒有限制。在列族數據庫中,任意列里面都可以隨意存放數據。你可以在圖數據庫中新增邊,也可以隨意向節點和邊中添加屬性。
       
      無模式數據庫的倡導者們很享受它所帶來的自由與靈活。如果用了模式,那么就必須提前指明你要存儲的數據,然而這一點卻比較難辦。擺脫模式的制約后,就可以輕易存儲所需數據了,于是我們很容易就能根據項目的進展情況來修改原有的數據存儲方式,一旦發現了新東西,只要把它們加入數據庫中就好。此外,若是發現某些東西已經沒用了,那么不再存儲它們就行了。在使用模式的關系型數據庫中,如果刪除了某列,那么你恐怕得擔心此操作會不會導致舊數據丟失。
       
      除了更改數據方面的差別外,無模式數據庫也更容易處理“格式不一致的數據”(nonuniform data),也就是那種每條記錄都擁有不同字段集(set of field)的數據。“模式”會將表內每一行的數據類型強行統一,若不同行所存放的數據類型不同,那這么做就很別扭。要么得分別用很多列來存放這些數據,而且把用不到的字段值填成null (這就成了“稀疏表”,sparse table),要么就要使用類似custom column 4 這樣沒有意義的列類型。而無模式表則沒有這么麻煩,每條記錄只要包含其需要的數據即可,不用再擔心上面的問題了。
      無模式數據庫很吸引人,而且確實能避免使用“固定模式數據庫”(fixed-schemadatabase)時所面臨的諸多麻煩,不過,它自身也存在一些問題。若存儲數據就是為了將其顯示成一列“字段名:字段值”(fieldName :value)格式的簡單報表,那“模式”的確是個障礙。
       
      可是,通常我們在處理數據時所要完成的任務并不止于此,而且處理數據的程序需要知道存放賬單地址的字段叫做billingAddress 而非addressForBilling,quality 字段應該包含整數“5”而非單詞“five”。
       
      在編寫數據訪問程序時,必須面對一個關鍵問題:盡管有時不甚方便,但程序通常要依賴于某種形式的“隱含模式”(implicit schema)。除非只需要執行下面這種極為簡單的邏輯。

      // pseudo code
      foreach (Record r in records) {
        foreach (Field f in r.fields) {
                print (f.name, f.value)
              }
      }

      復制代碼
      否則,程序必須假定表中存在某些特定的字段名,這些字段中包含帶有一定意義的數據,而且還要假定該字段存有某種類型的數據。程序與人類不同,它們不能在看到“qty”后立刻推斷出它與“quality”的意義一樣,至少在我們沒有專門為其編寫特定處理代碼時,它不行。所以說,不管數據庫“無模式”到何種地步,總會存在“隱含模式”。它是指在編寫數據操作代碼時,對數據結構所做的一系列假設。
      應用程序代碼中的隱含模式會帶來一些問題。它意味著,要想理解數據庫中存放的數據,必須深入研究應用程序的代碼才行。若代碼結構非常好,那么你就可以根據它明確推斷出數據的模式了,然而這一點卻無法保證,因為它完全取決于應用程序的代碼是否清晰。此外,無模式數據庫感知不到模式,所以它無法用模式來提升存儲與獲取數據的效率,它也無法自行驗證數據,以防止多個應用程序以不一致的方式操作其數據。
       
      上述問題就是關系型數據庫采用固定模式的原因,而且過去的數據庫基本都使用固定數據模式,也正是基于此種考量。“模式”有其價值,而NoSQL 數據庫棄用模式,真是個相當令人吃驚的決定。
       
      從本質上說,無模式數據庫是把模式交由訪問其數據的應用程序代碼來處理。如果由多位開發者制作的不同程序要訪問相同的數據庫,那就麻煩了。有幾個辦法能緩解此問題。一個辦法就是,將所有數據庫互動操作封裝成獨立的應用程序,并通過Web 服務將它與其他應用程序集成。當前很多開發者都通過Web 服務集成應用程序,該方法非常適合此類開發場景。還有一種辦法是,在聚合中為不同應用程序明確劃分出不同區域。在文檔數據庫中,可以把文檔分成不同的區段(section);在列族數據庫中,可以把不同的列族分給不同的應用程序。
       
      盡管NoSQL 支持者經常批評關系型數據庫,說它必須預定義模式,而且其模式也很不靈活,但事實并非如此。關系型數據庫的模式隨時可以通過標準SQL 命令修改。
       
      在必要時,可以立即添加新列,以存儲“類型不一致的數據”。我們只是很少碰到這種情況罷了,但如果真的遇上了,那此方法完全能應付。然而,在大多數情況下,如果你發現待存儲的數據類型不統一,那么應該優選無模式數據庫。
      無模式數據庫一直深遠地影響著數據庫的結構變更,尤其是存儲格式不一致的數據時更是如此。關系型數據庫的模式也可以用可控的方式改變,只是其運用范圍沒有理想中那么廣罷了。同理,也可以控制無模式數據庫存儲數據的方式,讓訪問新、舊數據都比較容易。此外,“無模式”的靈活性僅限于聚合內部,如果改動了聚合邊界,那么其數據遷移工作與關系型數據庫一樣,都非常復雜。