怎樣理解分析王垠文章《SQL,NoSQL 以及資料庫的實質》的觀點?

  1. 關係模型是一個無需有的東西。它嚴重束縛了人們的思想,其本質並不如普通的數據結構簡單和高效。它比起邏輯式語言的理論來說是非常膚淺的。
  2. SQL,Datalog,Prolog 等所謂「描述性語言」的價值被大大的高估了。使用它們的人往往有「避免編程」的心理,結果不得不做比編程還要痛苦的工作:資料庫查詢優化。
  3. 資料庫完全可以使用普通的程序語言(Java,Scheme 等)的「遠程執行」來進行查詢,而不需要專門的查詢語言。這在某種程度上就是 NoSQL 資料庫的實質和終極發展方向。

via SQL,NoSQL 以及資料庫的實質 by 王垠


有道理和沒道理的地方都很多。
有道理的地方是關於sql的評價和sql語言的問題。沒有道理的地方是關於關係模型的評價和NOSQL數據。
就從軟體開發來講,RDBMS的出現大大降低了APP的開發難度,你想想如果沒有RDBMS,讓開發者來開發個BBS,你的費多大牛勁啊。
至於說樓上得高票的NOSQL支持者,我只是想說,對絕大部分應用程序來講,沒有你講的那麼大的數據量。
文章里講的面向列存儲和面向行存儲,這個也要具體分析,基本上來說分析型的業務,適合面向列存,事務型的系統適合面向行存,很難一概而論,不是誰比誰好,而是適用場景不同,也有做兩者混合存儲的,他沒說而已。
實現一個資料庫最難的地方就是如何再保證並發訪問的情況下,最大量的把隨機io轉化為順序IO,而不是王同學講的那些,說白了是一個工程實現的問題,這也是我不太看好很多NOSQL的原因,你就實現了一個人家的功能的子集,然後跑出來說,哦,我好牛逼哦,我快的多。這不是笑話是什麼。還有那種動不動就說比rdbms快幾萬倍的資料庫系統,我只是想問你保證事務么,我需要事務支持,你支持mvcc么,支持行級鎖么?
至於很多人扯rdbms的分散式問題,你可以看看oracle最新的exadata,在計算節點看來是share storage的,在存儲節點來看是share nothing的,就是分散式資料庫。只是一般web開發用的mysql現在只能是偽分散式而已。
至於大的互聯網網站,難道除了GOOGLE在用自己的那套東西之外,FB,TWITTER,淘寶,新浪微博不都是主要在用rdbms么?至於廣大小站,難道rdbms不夠用么?


我可以說,所有的程序設計語言都是 bullshit,最好的編程語言是自然語言,我只要跟電腦說說話,就什麼都搞定了。

看,我一眼就看清楚了問題的實質,我比誰都聰明。

說這樣話的人,是不是以後就沒朋友了?

分割線,下面說正經的。
-----------------------------
我算是學過資料庫的,實際上,最早的資料庫就是 NO-SQL 的,發明關係資料庫和 SQL 的那廝得了圖靈獎。學過的都知道,這是入門的常識。

關係資料庫的確有很多很多的問題,這是常識,不需要任何天才都知道。但是RDBMS能解決目前遇到的很多問題,簡單的說,這玩意是個榔頭,你不能責怪他為什麼不能開啤酒瓶。

SQL 發明出來,不是為了什麼優雅,什麼強大,那些根本就扯不上。其最初目的是為了解決如何用最方便的辦法來查詢數據,他就是一個用來描述查詢的。

當然我們都知道,最好的查詢語言是自然語言。但是目前的技術條件根本達不到,如果王大神認為自己天才,請他去人工智慧領域混吧。

SQL 已經足夠好,好到很多人能學會用。而且對於現代的 RDBMS 而言,數據的查詢優化是由系統完成的。當然你說好的 DBA 必不可少,但 RDBMS 本身的優化器是無可代替的,這也是相關廠商的核心技術。

使用 NO-SQL 去用編程的方式查詢數據結構,這當然可行。我前面說過,這是最原始的方法。當你碰到大規模的數據存儲或者高並發量的查詢的時候,這幾乎是唯一的方法。

但這要付出巨大的代價,你要投錢,投人,投工時。對於中小項目,特別是數據特別複雜,查詢特別複雜,而數據並不是海量,查詢量也不是海量的時候。RDBMS 就特別有用。

這有很多例子,比如銀行,各種企業的管理系統等等等。

我一再說過,NO-SQL 是最原始的方法,並不是什麼新玩意,而且一直都存在。如果你了解這個領域的研究的話,相關的項目或者論文就一直沒斷過。

但沒有任何一個體系能取得 RDBMS 這麼廣泛的影響,一個解決方案必然有其局限性,汽車不能飛飛上天,飛機不會潛水,這有什麼好奇怪的呢?我也知道一種什麼地方都能去的交通工具是 「終極解決方案」 ,但這有什麼意思呢?

從王大神的行文來看,他對於資料庫這個領域的了解非常膚淺,說了一堆無比正確的廢話。也許他對於編程語言非常精通,但是對於 DB,他充其量就是抖了個機靈,說了段單口相聲,娛樂大眾而已。

繼續分割線。
---------------------

另外,範式本身並不是 RDBMS 所必需的,範式能解決的是資料庫的冗餘問題,數據冗餘存儲會帶來很多麻煩,最麻煩的是數據不一致的情況,如果你在兩個表裡面存了冗餘信息,而又沒有同時更新的話,就會出大麻煩。所以引入了事務,乃至分散式事務等等這些。

如果你學過資料庫,書本里都會告訴你,範式不是越高越好,適當的冗餘是有好處的,這是常識。

為什麼現在 NO-SQL 會引起重視呢,因為對於很多互聯網網站來說,數據很簡單,而對查詢要求特別苛刻,同時又不是很在乎用戶數據的一致性和安全性,這個時候,如果你用 RDBMS 就很愚蠢。

就好比你讓麥當勞給你攤個煎餅,這個有點勉為其難。

但如果你讓銀行,電信或者 ERP 系統去用 NO-SQL,這個就相當荒謬了。這種系統裡面動輒幾百張表很常見,而且查詢經常變來變去,今天讓你出這個報表,明天讓你出那個報表,而且報表又非常複雜,你用 NO-SQL 去做,光搞掂這些數據之間的關係和保證數據一致性就搞死了,不是花多少錢的問題,而是能不能搞定的問題了。


感覺這個問題需要非常資深的架構師才能回答,一般的dba完全沒有軟體設計的經驗所以很難全面得看待SQL 和 NOSQL的區別,而一般的程序其實也沒有海量數據處理的概念。
我們公司最近剛把一個項目從SQL搬到aws的DynomoDB,小小分享一下體會,拋磚引玉。
SQL和關係型資料庫的理念仍然時非常經典的,也不存在過時一說,但為何越來越不適合現在的系統開發要求,主要有幾個原因:
1. 移動互聯網發展迅速,系統變化太快。而關係型資料庫本質是需要先設計好資料庫的,其可擴展性和靈活性天生太弱,再強的架構師也會遇到資料庫最初的設計跟不上需求的情況。nosql在這方面強太多,屬性可以任意增加,結構幾乎可以任意變化,而且數據類型非常精簡。
2. 現在的存儲成本實在太低了,根本不在乎冗餘,而且對絕大多數系統來說,客戶端處理數據異常的能力非常強,不再需要資料庫去費力地在表與表之間建立複雜的關聯來規範數據。這樣關係型資料庫很多設計理念出發點就錯了,而這些範式的缺點就是不夠靈活,又回到了1。
3. 老實說傳統的關係型資料庫dba還挺貴的,而nosql感覺入門門檻低很多。當然因為不是專業搞資料庫的,我也不知道現在的數據倉庫(或者時髦點大數據)的技術是往什麼方向發展的。
4. 目前成熟的雲供應商(亞馬遜,微軟等),nosql的服務都比SQL資料庫的服務便宜,不知道是不是因為sql server或oracle都需要購買,而很多nosql的項目都開源。

寫了一大堆才發現我好像沒直接回答樓主問題,我覺得那個文章寫地不對。他僅從語言或者資料庫這個層面去分析,其實從這個層面來說,關係型資料庫和SQL是非常精巧的,而NoSql相對粗糙。但是,就是因為其精巧導致了最致命的問題:對需求應變不夠靈活。
舉幾個例子:比如我們以前視為經典的軟體開發模式(瀑布式、迭代式等等),現在哪個移動項目敢嚴格地用?很多移動互聯網項目都是每天更新版本,這種情況下基本不存在固定的code freeze。所謂敏捷,其實就是隨時地應對變化,因為現在需求太快太多變。
還有,大約十多年前很多人研究怎麼在設計模式的基礎上,對系統進一步地解耦,研究了很多方向,提出aop等很多編程概念,但這些研究方向很快全部夭折。為什麼?因為發現硬體越來越便宜,虛擬機技術又發展地很好,完全可以從伺服器節點與節點這個層面進行解耦,單節點上的程序粗糙點已經不是什麼問題了。反觀那些很優美的概念,其實其本身是沒有問題的,只不過不再適合現在的開發方式和系統環境了。

不知道我說明白了沒有。。。。


大規模使用的系統應該支持低智商用戶,所以他那種做法是不能被別人接受的


最早的時候世界上肯定是沒有relational database這種東西的,那時候大家都在手動寫程序管理自己的數據。後來有人想,這麼干實在比較累,乾脆做一個專門管理數據的程序吧。這就有了資料庫。創造資料庫的目的,是簡化常見的問題。設計資料庫的時候,是從實際出發,考慮怎麼樣能處理大部分的日常問題,而不是處理一切人類可以設想的問題。你也可以說這是個頭疼醫頭的辦法,但它確實也解決了大部分的頭疼。

因此SQL是一種domain-specific language (DSL),主要處理一些常見的資料庫查詢操作。用起來至少比自己重寫一個資料庫容易。你也可以說它圖靈完備什麼的,但是也沒什麼人拿它寫資料庫之外的東西。

現在王垠說,SQL不能利用某些問題的特點來簡化運算。比如說,平面上的點有一些幾何性質,可以利用這些性質來簡化運算。要用SQL寫這麼個玩意就很麻煩。或者要用某些方法繞過(workarounds),也很麻煩。

這麼說肯定沒錯。普遍性的程序,要解決普遍性的問題,對特殊的問題往往就沒有很快的解法。有個no free lunch theorem,也是類似的意思。普遍性和效率沒法兼顧。可是你不能這麼就斷言普遍性的程序就沒用了。

如果要追求效率,可以用Berkeley DB之類的東西再接上隨便什麼語言,把查詢操作自己管理起來,儲存留給資料庫。如果一定要追求最高效率,可以乾脆從從資料庫底層寫起,寫一個專門用來儲存平面上的點的資料庫。你要是嫌麻煩,我就沒什麼說的了。


老實說目前資料庫的技術是值得噴一噴的,但這篇文章完全根本不在點子上。


關係型資料庫目前最大的問題是,你們做的是互聯網的項目,數據是海量的,並發是極高的,需求是多變的,架構師還在扯第一第二第三BC範式。

這樣一來果斷各種扯,各種不爽啊。

關係型資料庫原本就是用來處理企業內部規範化數據的,你用關係型資料庫來做個什麼ERP、什麼MIS,自然是各種好用,各種合理。

又受限於各公司架構師、DBA的水平(都是關係數據模型那一套理論培養出來的),完全無法提供解決方案。而真正有互聯網數據解決方案的谷歌、百度之流,根本沒興趣將這些技術做成商業化項目出售。因為賣服務比賣技術產品要好多了。

這才造成了目前市面上資料庫技術這一塊嚴重短板,與人工智慧、語言神馬的沒有關係。


據我所知
SQL是一階邏輯語言,是實現不了圖靈機的功能的。
所以寫dijkstra就是扯淡

再說關係模型。關係模型本質是一種數學模型,先有模型再有的按照這種模型設計的後面的商用DBMS系統。
從數學上看關係模型和SQL的關係是很,自洽的。

至於實際系統中要對數據管理,組織,那肯定是量體裁衣,自己造輪子最好


槽點不少 。前來打臉。

首先是資料庫無法handle變長的數據類型,也就是數組。讓我們看看Postgres的官方文檔:
PostgreSQL: Documentation: 9.1: Arrays

CREATE TABLE sal_emp (
name text,
pay_by_quarter integer[],
schedule text[][]
);

人家不僅支持,還支持multi-dimension;

再者,他關於列存儲資料庫的認識基本上都是在亂說。

反例:基於Postgres的列存儲資料庫Amazon Redshift不支持變長存儲。

列存儲試圖解決的最基本問題如下:
1.更好的數據壓縮比:因為整個列的數據類型一致,所以可以採用更具有針對性的壓縮演算法。針對不同的數據類型也可以採用更加有效的索引。
2.I/O優化,只處理query涉及到的column,略去沒有涉及的column


總結來說,column based db的設計初衷就是為了讓scan變得更有效。什麼變長數組什麼的,根本不是列存儲資料庫關注的重點。

另外把Vertica和HBase放在一起,也好意思說自己是計算機科學家。

我甚至懷疑他根本就沒有多少使用列存儲資料庫的經驗,否則怎麼會連列存儲資料庫的最基本概念都會搞錯呢。。。不過我愛戴垠神的一個重要原因就是,他有一種神奇的魔力,就算一知半解,卻依然能在文章裡面把自己包裝成一個無所不曉的專家,高。

什麼時候發一篇罪己詔來批判一下這種自我神化的傾向就更好了。
==============================================
離題吐槽,雖然我打心裡認為垠神是有真才實學的,但是跟垠神在中文(英文完全另外一番風景)博客里描繪的指點江山、糞土萬戶侯的激昂形象相比,還是太過不足。文字逼格太高,用來強化論斷的自我佐證("我夠格"),卻一再使用XXX課的大作業和TA經歷說事兒,未免有點兒喜劇效果十足。


基本上王垠講的和大多數上面駁的,都不是站在同一個角度或者一個背景講的。


寫過一個Database Management System。參見:https://github.com/songsense/Simple-Database-Management-System
Database的基本問題的本質實際上就是Disk!Disk!Disk!所有的問題都是基於如何在硬碟上處理數據。硬碟的一個基本特性就是Sequential Access與內存的Random Access有著本質的區別。由於考慮到了這種因素,SQL背後的複雜程度遠遠超出一般想像。SQL的設計理念背後都是有周全深刻的考慮在其中的。NOSQL亦如此。
王垠的文章通篇感受是堆砌名詞,故作牛逼。實際上根本不了解SQL的本質。只能算是亂噴而已。


覺得有點吹毛求疵了,資料庫做運算的本質意義是什麼?那上層計算存在的價值又是什麼?
贊成database目的就是分開存儲和邏輯的說法。


王垠雖博,還是沒理解 關係資料庫。
關係資料庫,有其創立的原因和歷史,其根本點,似乎王垠並未發現:
最節省的存儲,最高效地得到最詳細的返回
為了實現這2個矛盾的需求、目標,才出現了關係資料庫,而SQL只是關係資料庫最有效的操作手段。

舉個例子:
一個城市的學生檔案信息,每個學生都是屬於 某個學校某一年級某個班級的
我們總不能為每個學生都加上他所在的學校的地址、校長等信息吧,只能加上一個最簡潔但有效(需要時能查到)的學校ID(一般是班級ID,但能從此得到年級ID、學校ID)。
需要返回學生的學校信息時,才會根據他的學校ID關聯回來他所在的學校的地址、校長等信息。

所以,節省是目標,關聯是手段,SQL就是用來快速、批量地進行關聯過濾的,
而不是解決 人工智慧 的問題的。當然,一定要解決 人工智慧 問題也不是不行,但是效率不一定最高。他最後提的 Dijkstra 的最短路徑演算法,如果用SQL解,其實就是通過關聯生成一個巨大的可能組合,然後通過篩選條件大量排除不符合的可能。。。。

從【關聯】就知道,NoSQL其實要麼不進行關聯,要麼沒法達到SQL的效率
2014.05.04

2015.01.01 補充一點:
最節省的存儲,也帶來了最高效的更新
如上面的例子,如果每條學生記錄帶學校、校長信息,那麼,萬一這個學校的名字、校長換了,需要對每個學生的對應部分信息進行更新。而節省之後,只需修改一條學校信息,成千上萬的學生記錄無須任何修改!


使用sql的時候很多地方就感覺不方便- -函數什麼的和一門完整的語言比太簡陋了


資料庫的應用不僅僅只有他描述的哪一種情形,所以他的吐槽是沒有在點上。比如你到銀行取錢,錢沒給你,電子賬戶里的數值卻減掉了,那你還不是一口老血噴在地上?這個用他說的btree庫加手工編程就是扯淡了。再說過去的機器是很貴的,人工便宜,所以花人力去搞複雜的、不優雅的系統來省一點cpu和存儲空間是划算的。不能因為今天機器便宜了,就開始噴過去人不會設計優雅的系統。


有人讓貼王珢的SQL實現Dijkstra"s algorithm

我就不花心思寫詳細過程了,先講箇舊事,再講一下SQL實現演算法的大致思路。
99年的時候,因為工作太累,就辭職休息,玩了大半年網遊。休息之前接了個私活。
養殖場的一個管理軟體,裡面有個模塊是兔子交配的優選程序(類似人的幾代之內不能近親)。
剛開始的時候,想用c++寫,發現一地狗屎啊。後來就選了一個access,用vba一周就搞定了,掙的錢剛好夠當時買的房子首期。
選種那塊演算法大部分是基於sql完成的。
Dijkstra"s algorithm 那塊最簡單的方法是兩張表,一張是城市之間的基本信息,一張是n個城市的窮舉里程,sql一個一個加城市統計數目,增加里程。一直到全部加完夠所有城市。這時候用選距離最小值。
加點技巧的話,同一個sql,不停的運行,運行夠城市數目,然後選最小值。
例如,有個欄位是城市的名稱累計和(#城市名#城市名#),一次一次把不包括的城市加進去,加的時候再把城市的里程加進去。

這種方法只有理論上的可行性,因為窮舉了所有的路徑可能,數據量可能是天文數字


觀點基本沒有錯誤。


這篇文章所說完全正確。他提到的:

資料庫完全可以使用普通的程序語言(Java,Scheme 等)的「遠程執行」來進行查詢,而不需要專門的查詢語言。這在某種程度上就是 NoSQL 資料庫的實質和終極發展方向。

這個觀點我完全贊同,只不過王垠現在還停留在嘴炮階段。
我兩年前就按他說的這個方式實現了一套內存資料庫,大概可以比Memcached快上千倍吧,比MySQL快十萬倍。
這個項目沒開源,但是我有個同事曾經某個講座裡面分享過。

http://www.slideshare.net/cppgohan/viny-storage


理解王垠的文章很簡單,因為他所有的文章都在說同一件事:
「看我多牛逼」。


王老師的文章我沒讀哦,我就以一個後端工程師的角度來談這個問題。

RDBMS最大的問題是Scale不上去,就是你沒法很輕易的把數據分(sharding)到幾百台server上。要分也行,但很多操作一旦需要橫跨不同的server,代價就太大了。

第二大的問題是table, row, column的結構過於死板,不利於快速原型開發。當然現在mysql等也在進步,但還是很難達到nosql那種靈活程度。

NoSql最大的問題在於數據一致性,雖然很多nosql提供了一定的保證,可要做到rdbms那麼嚴格的一致性,就會非常難。而數據一致性對很多應用特別重要,比如說銀行,比如說線上交易和支付。

NoSql第二大的問題是不支持Sql (很多人是一定要用sql的),rdbms和sql的搭配是有數學基礎的,另外sql的歲數比我還大,它當初可能沒有考慮數據要sharding的情況,Nosql這種要支持Sql就難了。

很多朋友提到一般應用沒有那麼大數據量,這個觀點是對的,如果數據量不是特別巨大,並發數不是特別高,你用一台資料庫伺服器,外加一些replication的技術就足夠的。但是如果你在互聯網行業,你不好這麼粗暴的假設,萬一你們這個應用火了呢?到時候你scale不上去,老闆不得殺了你?這也是為什麼很多一線互聯網公司比如說Facebook和twiiter都花那麼大力氣研究Nosql的原因,的確是他們都曾經用mysql承擔了巨大的訪問量,那時候幾個主要nosql實現還不成熟,mysql其實也可以當nosql那麼用,當然還是挺痛苦的,所以現在twitter的主要服務都轉到nosql上了。


有幾點理解得很透徹。

關係型資料庫裡面是table,nosql裡面是object。傻子都知道後者更能描述客觀世界的物體,也更能夠和程序中的對象進行對接,否則就不用做什麼orm映射了。nosql顯然是未來發展的方向。

如果是orm或者nosql的話,用什麼查詢最方便?當然是閉包。一個框架支持不支持傳閉包進去,易用性是天差地別的,不明白的對比一下hibernate和linq。所以,還要專門設計一種查詢語言幹什麼。


推薦閱讀:

Redis集群方案應該怎麼做?
MySQL為主,NoSQL為輔正成為網站技術的標配嗎?
NoSQL 會有注入問題嗎?
如何在node項目中引入redis做session持久化?
數據多的時候為什麼要使用redis而不用mysql?

TAG:資料庫 | SQL | NoSQL | 王垠人物 |