簡介
資料庫從不孤單。使用者、應用程式、腳本,甚至其他資料庫都會將資訊饋入其中並從中提取資訊,就像生物消耗和分配環境中的能量以及彼此的能量一樣。沒有資料庫在規模或複雜性上能與地球的全球生態系統相提並論,但設計和支援資訊系統仍然與照料較小的生態系統(如花園、溫室或玻璃缸)有許多相似之處。
經典的生態學劃分也可以應用於資料庫在資訊系統中的角色:動物、植物或礦物?要確定哪種模式適用於給定的資料模型,需要盡可能了解其所處的環境脈絡。
「動物」似乎描述了一種主動的組織原則,嵌入(或委婉地說,糾纏)於營運流程和工作流程中,經過調整、編程——總之,是專業化的。「動物」方法在圍繞單一資料庫作為資訊流收集器和單一事實來源而明確建立的重點明確的系統或子系統中表現非常出色。如果失去這種重點,「動物」資料庫可能會變得更像一隻大熊貓:行動遲緩、維護成本高,而且在後勤和官僚方面都是一場噩夢。
更「植物性」的資料庫物種會組織其取得的資料,僅此而已,在不對資訊採取積極行動的情況下約束和完善資訊。這些資料庫犧牲了集中化和對工作流程的主動控制,以換取適應性,在不將行為和使用假設編碼到更剛性的資料庫結構中的情況下收集和組織資訊。在資料庫不是資訊處理的唯一站點,或較大的團隊和溝通結構相互作用的系統中,將編程較少的資料庫視為一個而非主要的組織原則來使用,可能會更容易。
還有其他「礦物性」資料庫設計甚至放棄了對資訊的最低限度權威,僅提供具有最基本結構的儲存,例如五千年前的泥板,蘇美人將從分類帳到投訴的所有內容都印在上面。確實有時情況僅需要一個
資料庫,複數
每個與資料庫互動的程式或系統——不包括設計師、使用者或開發人員——也具有生態學角色,消耗和產生資訊,組合、分離資訊,為了好的或壞的目的而添加或消除細微差別。許多這些互動系統都有自己的資料模型,目標系統的資料模型現在構成這些模型的部分或全部組件(有時是透過眾所周知的模糊不清的方式,任何曾經詛咒過意外 VARCHAR(20)
的人都知道)。
這些連線意味著資料庫設計必須經常容納至少部分假設,如果不是外部於自身之其他資料模型的結構元素。資訊被分割:一個資料庫中的使用者和預訂,另一個資料庫中的飯店空房情況,航空公司的航班預訂以及在使用者和預訂端複製的預訂。綱要變得糾纏不清,一個資料庫中的變更會對其他資料庫產生影響。
管理更多事物以及它們之間更多的互動總是更困難的,尤其是在多個儲存區中拆分資料模型會產生深遠的後果。使用綱要來封裝和處理完整關聯式模型的子部分更安全,所有主要的 RDBMS
拆分資料模型最重大的損失是參考完整性。在單一資料庫中,伺服器可以阻止會違反外鍵約束的操作,例如,插入或更新具有不存在的父項 ID 的記錄,或
專業解決方案
與其他任何事物一樣,參考完整性是一種可協商的約束,如果能獲得足夠的回報,犧牲它是可行的選項。有時,如果資料模型在圖論意義上足夠簡單,實體很少,它們之間或多數是階層式連線,或兩者兼具,那麼這甚至不是一個需要提出的問題。效能和可擴展性需求也可能成為引入關聯式模型替代方案的理由,在這些替代方案中,資料模型的一部分表示真實資訊,其數量和變動速度比 RDBMS 可以輕鬆容納的要高。
00 年代後半期見證了這些替代方案的寒武紀大爆發。突然間出現了「NoSQL」資料庫,用於儲存文件、圖形、鍵值對。柱狀儲存透過將表格側放並對平面、非正規化資料進行塑模,實現了驚人的效能。新來者擁抱跨網路伺服器的擴展,拋棄了 ACID 規則手冊,轉而支持 BASE(「基本可用、軟狀態、最終一致性」),並為 SQL 陌生的概念開發了 API 和特定領域語言。不僅如此,圍繞資料儲存的對話重塑模糊了資料庫作為概念的界線。像 Kafka 這樣的流處理器是資料庫嗎?像 ElasticSearch 這樣的搜尋引擎呢?每個從根本上都有助於資訊的儲存和檢索;討論任何一個都需要調用許多資料庫的技術語言。更根本的是,每個都是針對特定類型資料塑模問題的解決方案。
如果您需要儲存和處理... | 請考慮... |
---|---|
具有少量互連的階層、原始結構化文件或至少有一些共同欄位的物件 | 文件資料庫(Couchbase、MongoDB) |
大量「平面」資料,例如儀器讀數或結構化分析 | 面向柱狀的資料庫(Cassandra、HBase)、時間序列資料庫(TimescaleDB、InfluxDB、Druid) |
由鍵識別且僅由該鍵查詢的記錄 | 鍵值儲存區(Redis、LevelDB)、快取(memcached) |
記錄之間具有點對點導航的複雜關係 | 圖形資料庫(OrientDB、Neo4j、TerminusDB) |
按接收順序排列的暫時性資料饋送 | 流處理器和佇列(Kafka、RabbitMQ、ZeroMQ) |
檔案。大量檔案 | 雲端檔案儲存(Google Cloud Storage、Amazon S3 和 Athena) |
非結構化文件,或具有高度可變綱要的結構化文件 | 搜尋引擎(ElasticSearch、Solr)、內容儲存庫(Jackrabbit) |
行星級規模的關聯式資料 | NewSQL 高度分散式關聯式資料庫(VoltDB、Spanner) |
至少以上幾種 | 多模型資料庫(FaunaDB、ArangoDB) |
請注意,以上僅為範例,並非背書!Kristof Kovacs 也維護了一份 更詳細的摘要,其中介紹了許多 NoSQL 選項,從流行的到默默無聞的。
預設值
如果您不需要儲存至少數 GB 的關聯式資料模型例外情況,您甚至可能不需要拋棄 ACID 和參考完整性!關聯式資料庫通常在全文檢索和儲存結構化或非結構化文件方面非常出色;PostgreSQL 對 JSON 的處理方法尤其廣泛,具有可索引的二進制儲存和豐富的查詢工具集,使得混合關聯式文件策略切實可行。Postgres 和其他 RDBMS 都透過伺服器組件、擴充功能或儲存引擎支援其他模型,一些專業儲存區(如 TimescaleDB)建立在關聯式資料庫之上。
因此,儘管數十個行銷部門盡了最大努力,但問世已半個世紀的 RDBMS 仍然是首選的通用資料儲存區,而非關聯式解決方案則找到了適合其優勢的專業利基市場。NoSQL 資料庫可以完成其關聯式對應資料庫無法輕易或完全完成的各種事情,但關聯式資料庫在可預見的未來仍然會存在。透過 伺服器調整、索引和表格分割,單一關聯式資料庫可以容納除了最繁重工作負載之外的所有工作負載。即使這還不夠,仍然有複寫。
複寫與架構
深入探討複寫技術超出了資料塑模指南的範圍,但它們的使用確實會產生不可忽視的後果。複寫資料庫不僅僅是更大:當即時資料儲存變成網路化時,它不再是整個系統架構的單一元素。複寫引入了一整套關於延遲、網路分割、維護等的新問題。
最常見的複寫形式涉及僅將資料寫入單一
在替代的「多主」複寫模式中,資料可以寫入多個伺服器並從中讀取,這些伺服器透過網路連接,在繁重的工作負載下比單一伺服器可能更具彈性。但是,制定共識是複雜的,並且實現更高層級的寫入驗證以保證持久性可能會很慢。這往往需要更簡單的資料模型以及更精細的衝突和回滾處理。
大多數 NoSQL 資料儲存區都設計用於叢集,有些甚至到了幾乎完全不考慮是否能夠在單一電腦上運行的程度。特別是,NoSQL 將分片的概念(即從叢集中的不同節點提供表格分割區)帶到了最前沿。分片是這些資料庫實現規模的主要因素,但如果沒有複寫,丟失節點仍然意味著丟失資料。大多數 NoSQL 資料庫都提供基本複寫,通常具有自動故障轉移功能。少數幾個(如 Cassandra 和 Couchbase)使用多個主要伺服器。
CAP 定理
他的「CAP 定理」(一致性、可用性、分割容錯:三者選其二)至今仍引起共鳴,但像動物/植物/礦物三分法一樣,它是一種優雅的過度簡化——僅此而已。
Martin Kleppmann 在 2015 年詳細描述了 CAP 的缺點,並基於 Coda Hale 先前 闡明「三者選其二」方面 的努力。Brewer 本人已進一步宣稱 Google 的 Spanner 資料庫 「實際上是 CA」,這要歸功於 Google 網路的龐大規模,克服了 AP/CP 二分法。
整合外部資訊
資訊很少僅在系統的資料庫或資料庫及其使用者之間流通。大多數資訊系統都是開放系統,資料從其他資訊系統流入和流出。這些流通常適合自動化,並且在達到一定程度的數量(並非非常大)時,自動化幾乎成為必然;手動資料輸入是最後的最後手段。有時外部資訊來源始終處於開啟狀態,佇列、流處理器或專用守護程式會在記錄到達時添加記錄,但永遠不會一次執行太多操作。但是,有時即時資料可能不可用或根本不必要——每月銷售額或昨天的網站分析不需要精確到秒。
大量資料擷取的過程通常以首字母縮略詞 ETL(代表擷取-轉換-載入)來表示,即使在沒有發生擷取或轉換的情況下也是如此(非正式地)。典型的 ETL 程序是 cron 作業或排程任務,它從外部系統下載封存的資料匯出,通常是平面分隔格式(如 CSV 或 TSV)。記錄可能會在 ETL 任務將其寫入資料庫時進行轉換,或者,與首字母縮略詞相反,之後大量轉換。當涉及與現有資料的聯結時,大量轉換尤其有用,因為資料庫可以一次優化數千列的聯結,比單列聯結數千次更有效。
用於資料匯入的第一方工具各不相同。專有 RDBMS 通常包含專用的 ETL 管理程式,例如 SQL Server Integration Services 或 Oracle Data Integrator,而主要的開放原始碼和 NoSQL 選項通常止步於使用 mysqlimport
和 mongoimport
等應用程式進行基本檔案載入,或 PostgreSQL 和 Cassandra 中的伺服器端 COPY
命令(Postgres 還在 psql 用戶端中提供用戶端 \copy
指令)。
但是,第三方 ETL 自動化正成為一個可行的商業利基市場,尤其是在越來越多的資料庫託管在雲端中的情況下。如果您有大量不同的傳入流或嚴格的法規遵循約束,則可能值得研究這些服務。它們並未執行任何您無法使用已有的工具執行的操作——問題是您是否有時間自己實作和維護足夠穩健的 ETL 流程。
聯邦式:統一資訊來源
ETL 不是唯一的選擇。2003 年,SQL 標準引入了一個名為 SQL/MED 的擴充功能,代表外部資料管理。檔案、其他資料庫、其他關聯式或非關聯式 DBMS、REST 端點、目錄服務——所有這些以及更多都涉及看起來很像欄和列的資料集,至少從正確的角度來看是這樣。任何看起來足夠像欄和列的東西都可以在概念上透過 SQL 進行查詢(如果不是直接管理)。資料庫向使用者和其他外部系統呈現單一介面,同時將請求和變更路由到適當的目的地。
在 IBM 的 DB2 首次實作之後,其他資料庫花費了數年時間才趕上 SQL/MED。目前,Oracle 支援對平面檔案進行讀/寫訪問作為「外部表格」,而 SQL Server 可以連線到「連結伺服器」,只要它們符合 Microsoft 的 OLEDB API。
真正有趣的事情正在開放原始碼 RDBMS 中發生。PostgreSQL 在 9.1 版中引入了 外部資料包裝器,並繼續擴展其功能,而 MariaDB 的 CONNECT
儲存引擎 可以包裝大量的資料來源。此外,Postgres 和 MariaDB 的實作都是可擴展的:如果您的外部資料採用現有包裝器無法處理的格式,您可以編寫自己的包裝器。Postgres 社群甚至開發了一個名為 Multicorn 的 Python 框架,以簡化原本基於 C 的外部資料包裝器開發過程。
「聯邦式」架構的概念源自區域和中央(聯邦)政府共存的雙重政府形式,並且像其他系統設計技術一樣,其目的是管理複雜性。各個子系統的使用者在這些子系統中工作和使用這些子系統;僅關注整體運作的人員與整體互動。就生態學角色而言,這在很大程度上是一種「動物」模式的資料庫運作。聯邦式資料庫是其所處系統的核心。它將資訊流吸引到自身並透過自身,建立連線,編碼附屬綱要的預期。但在可以蓬勃發展此類巨獸的資訊生態系統中,SQL/MED 是一種用於控制不同資料來源的強大工具。