數據模型與查詢語言 ------《Designing Data-Intensive Applications》讀書筆記2

来源:http://www.cnblogs.com/happenlee/archive/2017/12/20/8072693.html
-Advertisement-
Play Games

數據模型是開發軟體的最重要的部分,因為它們對應用程式有著深遠的影響:不僅是軟體的編寫方式,而且也影響我們如何解決的問題的方式。第二篇讀書筆記,我們聊一聊數據模型的設計。 1.數據模型的分層 作為一個開發者來說,在一個複雜的應用程式中,是存在很多 分層模型 的,但基本思想還是一樣的:每一層都提供了一個 ...


數據模型是開發軟體的最重要的部分,因為它們對應用程式有著深遠的影響:不僅是軟體的編寫方式,而且也影響我們如何解決的問題的方式。第二篇讀書筆記,我們聊一聊數據模型的設計。

1.數據模型的分層

作為一個開發者來說,在一個複雜的應用程式中,是存在很多分層模型的,但基本思想還是一樣的:每一層都提供了一個乾凈的數據模型,從而隱藏了底層的複雜性。通過這樣的抽象來允許不同的人群有效地協同工作。

每個數據模型都包含瞭如何使用它的假設。有些用法很容易,有些不支持;有些操作很快,有些執行不好;有些數據轉換很自然,有些則很笨拙。由於數據模型對其上層的應用程式能做什麼和不能做什麼有著深刻的影響,因此選擇適合於應用程式的數據模型十分重要。

(在這一章中,我們將完整的梳理各類數據模型和基於不同數據模型衍生的查詢語言)

2.數據模型

  • 關係型數據模型
    目前對電腦科學具有最深遠影響的數據模型就是SQL,基於Edgar Codd 提出了關係模型的對數據進行組織成表(SQL之中的表),其中每個元組稱之為行,行是一個無序的集合(SQL之中的行)。關係型的數據模型的目標將實現細節隱藏在一個更乾凈的介面後面。

  • 非關係型數據模型(NoSQL)
    與關係數據模型相比,非關係型數據模型具有下麵的一些優點。包括了:
  • 非常大的數據容量與非常高的讀寫吞吐量。
  • 很好地支持的專門查詢操作
  • 數據模型會更加靈活

舉個慄子:

目前大多數應用程式開發都是使用面向對象編程語言完成的,這導致了對SQL數據模型靈活性的批評:數據存儲在關係表中,應用程式代碼中需要在對象與表、行和列的資料庫模型之間需要一個笨拙的轉換層。(也就是我們日常使用的ORM
LinkedIn是我們常用的職業檔案網站,我們來看看使用不同數據模型的差異。

Linkedin檔案使用關係型數據模型表示

  • 在傳統的SQL模型中,最常見的規範化表示是將位置、教育和聯繫人信息放在單獨的表中,帶有外鍵表引用到用戶表,如上圖所示。問題是顯而易見的,多表之間的依賴關係大大的複雜化了應用程式的編寫。

Linkedin檔案使JSON模型表示

  • JSON模型減少了應用程式代碼和存儲層之間匹配問題,它會更加靈活。如上圖所示,JSON表示相比多表模式具有更好的局部性。如果要獲得如教育或職業信息,在 多表模型之中您需要執行多次查詢(通過user_id查詢每個表)或執行一個多表連接的操作。而在JSON的數據模型之中,所有相關信息都在一個位置,一次查詢就足夠完成了。

註:在例子中的前一段,region_id和industry_id給出的ID,不是純文本字元串“Greater Seattle Area”和“Philanthropy”。有如下幾個考量:(1)避免歧義(2)可以統一更新(3)可以更好的本地化來適應不同的語言。使用id的優點是,因為它對人類沒有意義,所以它不需要更改:id可以保持不變,即使它標識的信息是變化的。任何對人類有意義的東西都可能需要在將來某個時候改變,如果信息被覆制,所有多餘的副本都需要更新。這會導致寫開銷,並且不一致性的風險。區域和行業的列表可能很小,而且變化緩慢,以至於應用程式可以簡單地將它們保存在記憶體中。**)

文檔型數據模型的靈活性:

當應用程式希望改變其數據格式的情況下,靈活性就顯得至關重要了。 例如,假設我們在資料庫中將每個用戶的全名存儲在一個欄位中,而現在想要分別存儲名稱和姓氏。

  • 文檔資料庫中,只需要開始使用新欄位編寫新文檔,併在應用程式中有代碼處理舊文檔讀取時的情況。

    if (user && user.name && !user.first_name) {
       user.first_name = user.name.split(" ")[0];
    }
  • 在關係型資料庫模式中,通常按照這樣的思路修改模型:

    ALTER TABLE users ADD COLUMN first_name text;
    UPDATE users SET first_name = split_part(name, ' ', 1); 
    UPDATE users SET first_name = substring_index(name, ' ', 1);

    在一個大數據量的表上運行UPDATE語句可能在任何資料庫上都很慢,因為每一行都需要重寫。如果這是不可接受的,應用程式可以讓first_name設置為其預設為填寫在讀的時候,通過這樣的方式來模擬文檔資料庫的靈活性

小結:文檔型的數據模型的主要優點是模式靈活性,在局部性更好的性能,如程式經常需要訪問整個文檔時具有更好的性能優勢。對於特定的應用程式,它更接近應用程式所使用的數據結構。如果在應用程式中的數據具有類似文檔的結構(即一對多關係樹,通常是一次載入整個樹),那麼使用文檔模型會是一個好的選擇。關係型數據模型通過提供更好的連接支持、多對一和多對多關係,如果應用程式使用多對多關係,關係型數據模型會更加適合。通過在資料庫中生成多個請求,可以在應用程式代碼中模擬連接,但這也會將複雜性移動到應用程式中。

文檔型資料庫開始支持表之間的關係查詢,連接操作。關係型資料庫開始引入JSON與XML的支持。混合型的數據模型或許會是資料庫發展的方向

3.數據查詢語言

不知道大家有木有試想過一個問題,為什麼我們會有SQL語言。本身使用SQL語句表達的邏輯同樣可以用程式設計語言去表達,為何還需要多此一舉的使用另一種方式去表達數據模型呢?

其實這個答案是非必須的,也就是說,我們可以直接使用程式設計語言來和數據交互。(如:MongoDB就是使用了Js作為原生的交互語言。)但絕大多數我們直接使用的程式設計語言是命令式語言,而像SQL這種代數關係聲明式的查詢語言會有一些更貼合數據模型的優點。

舉個慄子:

例如,如果你有一個動物物種的列表,需要返回列表上的Shark
使用Js的數據表達
使用SQL的數據表達

由上圖所示,命令式語言告訴電腦按一定順序執行某些操作。你可以需要一行一行地單步執行代碼,評估條件,更新變數,並決定是否再迴圈一次。而在像SQL或關係代數這樣的聲明式查詢語言中,您只需指定您想要的數據的模式,結果必須滿足什麼條件,以及您希望如何轉換數據(例如,排序、分組和聚合),而不是具體的實現流程。資料庫系統的查詢優化器來決定哪些索引以及哪些連接方法可以使用,以及執行查詢的各個部分的順序。

  • 聲明式查詢語言通常比命令式語言的API更簡潔,更易於使用。但更重要的是,它還隱藏了資料庫引擎的實現細節,這使得資料庫系統可以在不需要對查詢進行任何更改的情況下引入性能改進。
  • 但SQL在功能上更為有限,靈活性上會受到限制,這給資料庫提供了更多的自動優化空間。
  • 聲明式語言通常適合於並行執行,因為它們只指定結果的模式,而不是用於確定結果的演算法。

4.總結

數據模型是一個龐大的主題,所有不同的數據模型。現在都被廣泛使用,它們各自的領域都很好。一個模型可以用另一個模型來模擬,例如,文檔型的數據可以用關係資料庫表示,但結果往往很笨拙。這就是為什麼我們有不同的系統為了不同的目的,而不是一個單一的一刀切的解決方案。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 關聯兩個數據表,在Model里建立StuModel.class.php: 在view中建立Stu文件夾,建立主頁面index.html: 在Stu中建立修改頁面edit.html: 在Controller中建立StuController.class.php: ...
  • 轉載自:http://blog.csdn.net/hsl0530hsl/article/details/78363222 ...
  • 首先要說明的是,咱現在不是高手,最多還是一個半桶水,算是入了JS的門。談不上經驗,都是一些教訓。 這個時候有人要說,“靠,你丫半桶水,憑啥教我們”。您先別急著罵,先聽我說! 你叫一個大學生去教小學數學,不見得比一個初中生教得好。因為大學生早已經過了那個階段,都忘記自己怎麼走過來的了。而對於初中生,剛 ...
  • public interface People { public void work(); } public class RealPeople implements People { public void work() { System.out.println("工作中..."); } } /**... ...
  • 適配器模式分為兩種:類適配器模式和對象適配器模式。廢話不多說,直接上代碼。 1、類適配器模式 2、對象適配器模式 ...
  • public interface Shape { public void outputShape(); } class Circle implements Shape { public void outputShape() { System.out.println("this is a circle... ...
  • 全文檢索這個系列在幾前年寫過lucene的文章,而現在看來它確實已經老了,它的兒子孫子都出來了,已經成為現在檢索行列的主流,像solr,elasticsearch等,今天我們主要來看一個solr在aspnetcore里的使用,也就是增刪改查之類的,比較容易! nuget包:solrnet 註入方式: ...
  • Vivado是Xilinx(賽靈思)公司出品的開發軟體平臺,適用於Zedboard開發板。本文介紹了Vivado2017.3的在Win10安裝和可能遇到的問題。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...