摘要:理想情況下,單一文檔將成為項目所有信息的唯一來源。然而,卻沒有相等的事務去更新不同的文檔。許多的問題已經被曝光,但大部分還是歸結為一個問題知識。
聲明:本文譯自SQL vs NoSQL The Differences,如需轉載請注明出處。
SQL(結構化查詢語言)數據庫作為一個主要的數據存儲機制已經超過40個年頭了。隨著web應用和像MySQL、PostgreSQL和SQLite這些開源項的興起,SQL使用量大大增加。
NoSQL數據庫在20世紀60年代就已經出現了,但最近因為MongoDB、CouchDB,Redis和Apache Cassandra等才受到廣泛的關注。
你會發現很多教程都會解釋如何根據你的興趣選擇去使用SQL還是NoSQL,但是很少討論為什么應該去選擇它。我希望能夠填補這一空白。在這篇文章中,我們將介紹基本的差異。在稍后的后續的文章中,我們將查看一些典型的場景,并確定最佳的選擇。
大多數的例子都適用于目前流行的MySQL SQL和MongoDB NoSQL數據庫系統。其他SQL/NOSQL數據庫都是類似的,但會有細微的差別和語法特征。
SQL和NoSQL的圣戰在我們開始之前,先糾正一些所謂的神話…
神話1:NoSQL將取代SQL
這么說就好比說船將被車取代,因為它是新的技術。SQL和NoSQL做的是相同的事:數據存儲。它們采取的方法不同,這可能回幫組或阻礙你的項目。盡管感覺技術更新,并經常在最近上頭條,NoSQL不是SQL的替代品——而是一種選擇。
神話2:NoSQL比SQL更好或更壞
一些項目更適合使用SQL數據庫,一些更適合NoSQL,而一些可以兩者交替使用。這邊文章不會是SitePoint Smackdown,因為你不能在所有方面都應用相同的廣泛性假設。
神話3:SQL和NoSQL天壤之別
這不一定是個事實。一些SQL數據庫采用NoSQL的特點,反之亦然。選擇可能會變得越來越模糊,NewSQL混合數據庫可能會在將來提供一些有趣的選擇。
神話4:語言/框架決定了使用什么樣的數據庫
我們已經習慣了技術堆,比如——
LAMP: Linux, Apache, MySQL (SQL), PHP
MEAN: MongoDB (NoSQL), Express, Angular, Node.js
.NET, IIS and SQL Server
Java, Apache and Oracle.
有實踐的、歷史的和商業的原因來解釋這些stack的發展——但不能認為它們就是規則。你可以在你的PHP或.NET項目中使用MongoDB NoSQL數據庫。你可以在Node.js中連接MySQL或者SQL服務器。你可能沒有找到很多教程和資源,但是是你的需求決定數據庫的類型——而不是所謂的語言。
(有句話是這么說的,不要讓生活有目地為難自己!選擇一個不尋常的技術組合或者SQL和NoSQL組合是可行的,但困難的是找到支持和聘請有經驗的開發者)
有了這樣的想法,我們來看看主要的差異。
SQL表VS NoSQL文檔SQL數據庫提供相關數據表的存儲。例如,如果你有一個網上書店,圖書的信息將會被添加到一個book的表中:
每一行是一個不同的記錄。設計是剛性的;你不能使用同一個表來存儲不同的信息,或者在一個數字格式輸入字符。
NoSQL數據庫存儲JSON格式的字段值對文檔,比如:
{
ISBN: 9780992461225, title: "JavaScript: Novice to Ninja", author: "Darren Jones", format: "ebook", price: 29.00
}
相似的文檔可以存儲于一個集合里,這類似于一個SQL表。然而你可以存儲任何數據在任何文檔里;而NoSQL數據庫永遠不會抱怨,例如:
{
ISBN: 9780992461225, title: "JavaScript: Novice to Ninja", author: "Darren Jones", year: 2014, format: "ebook", price: 29.00, description: "Learn JavaScript from scratch!", rating: "5/5", review: [ { name: "A Reader", text: "The best JavaScript book I"ve ever read." }, { name: "JS Expert", text: "Recommended to novice and expert developers alike." } ]
}
SQL表創建一個嚴格的數據模板,因此很難犯錯誤。NoSQL更加的靈活和寬容,但能夠存儲任何數據可能會導致一致性的問題。
在一個SQL數據庫中,除非你在指定模式中定義了表格和字段格式,不然不可能添加數據。該模式還可以包含其他的信息,例如——
主鍵——唯一的標識符,如ISBN,適用于單個記錄。
索引——通常被查詢的字段,用來幫助快熟搜索。
關系——數據字段之間的邏輯連接
功能——如觸發器和存儲過程
你的數據模式必須在任何商業邏輯可以被開發去處理數據前被設計出來并實現。完成后可以行進一些更新,但不能完成大的改變。
在一個NoSQL數據庫,數據可以隨時隨地被添加。沒有必要去制定一個文檔設計,甚至集合前端。例如在MongoDB,下面的語句將在新的book集合創建一個新的文檔,如果這個文檔之前沒有被創建過:
db.book.insert(
ISBN: 9780994182654, title: "Jump Start Git", author: "Shaumik Daityari", format: "ebook", price: 29.00
);
(MongoDB會給每個集合內的文檔自動添加唯一的_id值。你可能任然想要定義索引,如果需要的話可以稍后進行。)
如果一個項目初始數據要求很難去確定,那么NoSQL數據庫可能更加的適合。有句話說,不要為懶散而制造困難:忽略了在項目中設計適合的數據庫的重要性將會在之后導致很多的麻煩。
SQL規范化VS NoSQL反規范化假設我們要向書店數據庫中添加出版商信息。一個單一的出版商可以提供多個標題,在一個SQL數據庫里,我們創建一個新的publisher表:
我們接下來可以增加publisher_id到book表,這個表是publisher.id引用。
這最大限度的減少數據的冗余;我們不用重復每本書的出版商信息——僅僅只用索引。這種技巧可以稱作規范化,并有實際的好處。我們只用更新單一的出版商而不用改變整個book數據。
在NoSQL中,我們也可以使用規范化技巧。在book集中的文檔——
{
ISBN: 9780992461225, title: "JavaScript: Novice to Ninja", author: "Darren Jones", format: "ebook", price: 29.00, publisher_id: "SP001"
}
——在一個出版商集合中引用一個文檔:
{
id: "SP001" name: "SitePoint", country: "Australia", email: "feedback@sitepoint.com"
}
然而,這并不總是可行的,原因在下面很明顯。我們可能選擇反規范化我們的文檔,重復每本書的出版商信息:
{
ISBN: 9780992461225, title: "JavaScript: Novice to Ninja", author: "Darren Jones", format: "ebook", price: 29.00, publisher: { name: "SitePoint", country: "Australia", email: "feedback@sitepoint.com" }
}
這可以加快查詢的速度,但在多個記錄中更新出版商信息將會顯著變慢。
SQL查詢提供了一個強大的JOIN條款。我們可以使用單個SQL語句獲取不同表中的相關數據。例如:
SELECT book.title, book.author, publisher.name
FROM book
LEFT JOIN book.publisher_id ON publisher.id;
這將返回所有的書名、作者和相關出版商名稱。
NoSQL沒有等效的JOIN,有SQL的經驗的可能會驚訝. 如果我們使用上述的規范化集合,我們將需要獲取所有的book文檔,檢索所有的相關publisher文檔,并手動在程序邏輯中連接兩者。這就是反規范化常常是必不可少的一個原因。
SQL VS NoSQL數據完整性大多數SQL數據庫允許你使用外鍵約束去強制性數據完整性(除非你仍在使用舊的,在MySQL已不存在的MyISAM存儲引擎)。我們的書店可以——
? 確保所有的書都有一個有效的publisher_id編碼,這個編碼在 publisher表中都有匹配的條目
? 如果一個或多個書被分配給它們,則出版商不能被刪除。
模式強制數據庫遵循這些規則。開發者或用戶則不能增加、編輯或者移除可能引起無效數據或孤立的數據
相同數據完整性選項在NoSQL數據庫中不可用;你可以存儲所有你想存儲的東西。理想情況下,單一文檔將成為項目所有信息的唯一來源。
SQL VS NoSQL事務在SQL數據庫中,兩個或多個更新可以在同一個事務中執行——一個all-or-nothing的封裝保證成功或失敗。例如,假設我們的書店包含了order和stock表。當一本書被訂購時,我們在order表添加一條記錄并減少stock表中的庫存數。如果我們分別地執行這兩個更新,一個可能成功另外一個會失敗——因此我們的數據會不同步。在一個事務中放置相同更新可以保證同時成功或失敗。
在NoSQL數據庫中,單個文檔的修改是微小的。換句話說。如果你正在文檔中更新三個值,要不三個值都是成功的,要不三個值都保持不變。然而,卻沒有相等的事務去更新不同的文檔。有類似的選項,但是,在寫這些的時候,必須在你的代碼中手動處理。
SQL VS NoSQL CRUD 語法創建、讀取更新和刪除數據是上所有數據庫系統的基礎。本質上——
? SQL是一個輕量級的陳述性語言。這是非常強大的,并已經成為一個國際化的標準,雖然大多數系統實現略有不同的語法。
? NoSQL數據庫使用與JSON類似 JavaScripty-looking查詢!基本操作很簡單,但嵌套的JSON對于復雜的查詢會變得更加的繁雜。
簡單的比較:
這也許是最有爭議的比較,NoSQL經常被認為比SQL更快。這并不奇怪;NoSQL更加簡單的反規范化存儲允許你使用單個請求去在所有信息中查詢一個特定的項目。不需要使用相關的JSON或復雜的SQL查詢。
也就是說,你的項目設計和數據要求將產生最大的影響。一個良好設計的SQL數據庫必然會比一個設計很差的NoSQL表現要好,反之亦然。
SQL VS NoSQL縮放隨著你的數據的增長,你可能會發現在多個服務器之前分配負載是很必要的。這對于SQL為基礎的系統可能很棘手。如何分配相關的數據呢?聚類可能是最簡單的選擇;多個服務器訪問相同的中央存儲——但即使這樣也會存在挑戰。
NoSQL的簡單數據模型可以讓這個過程容易很多,許多一開始就建立了縮放功能。這是一個概論性的,所以如果碰到這種情況請去咨詢專家意見。
SQL VS NoSQL實用性最后,我們來考慮安全和系統的問題。最有名的NoSQL數據庫才存在了幾年;他們比更成熟的SQL產品更易出現問題。許多的問題已經被曝光,但大部分還是歸結為一個問題:知識。
開發人員和系統管理員對于新的數據庫系統有較少的經驗,所以錯誤常常發生。選擇NoSQL是因為它感覺會更快,或因為你想去避免架構設計而導致之后的問題。
SQL VS NoSQL的總結SQL和NoSQL數據庫用不同的方式做同樣的事情。從一個切換到另一個是可能的,但是一點計劃可以節約很多的時間和金錢。
更適合SQL的項目:
可預先確定的邏輯關系離散數據的要求 數據完整性是必不可少的 有良好開發經驗和支持的標準基礎技術
更適合NoSQL的項目:
不相關的、不確定或不斷變化的數據要求 更加簡單寬松的項目對象,可以立即編碼 速度和擴展性是必要的
在這個書店例子的背景下,SQL數據庫是最實用的選項——特別是當我們引進電商設施,需要強大的事務支持。
由于我們云巴是做跨設備平臺的消息服務的,對數據存取的速度和擴展要求非常高,NoSQl對我們來說是最合適的。關于Couchbase和 Redis 可以看我們往期的文章。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/18777.html
閱讀 3952·2021-11-11 10:58
閱讀 3321·2021-09-26 09:46
閱讀 1912·2019-08-30 15:55
閱讀 976·2019-08-30 13:52
閱讀 1944·2019-08-29 13:11
閱讀 3024·2019-08-29 11:27
閱讀 1517·2019-08-26 18:18
閱讀 2618·2019-08-23 14:17