Tag Archives: SQL

Database Design for Mere Mortals – Michael J. Hernandez

我學懂寫SQL已經很多年,但我從來沒有正式地學習如何設計一個database,大多數只是隨便地上網找些SQL例子現炒現賣。這本課本是database設計的天書,已經有二十五年歷史出版至第四版。整本書內沒有教一句SQL語法,若果連SQL還未懂的話,恐怕這本書太過艱深了。

有三分一本書的篇幅,談論應該如何訪問database的用家,在開始設計database之前,先找出database需要儲存的資料和要做什麼類型的query。現在看完書後回顧重溫,覺得這部份有點是想當然爾的常識,但我初次閱讀那些章節時,很有增廣見聞的新鮮感。我工作上寫了程式幾十年,那些系統需求的規格,自問見過不少亦做過不少,但我始終是邊做邊學紅褲子出身,第一次接觸如此有系統寫系統需求的方法。

Relational database是什麼,說到底就是一個個table,寫著一行行的資料,每筆資料有很多field載著data,而每個table之間用key去互相連系。在看這本書前,我連什麼是normal form也不知道,不過看完書,其實我還是一知半解,因為normal form實在太深了。作者教用另一個設計方法,一步步把資料的fields組合為不同的tables。由細到大一層層建築上去,比起從一個大table開始,然後用normal form去分拆成不同的tables,雖然工序更多步驟更費神,但初學者比較容易明白。

Database設計最重要是資料的可靠性,「唯一」就是設計的關鍵,每一項資料只存在一個地方,每一個地方只儲存一項資料。可以計算出來的資料,就不要浪費地方去存放,有需要加速就建立view來暫存。聽起來好像很容易,實際設計database時,要很有耐心去逐項逐項校對,才不會不小心產生設計上的缺陷。

SQL Clearly Explained 3rd Edition – Jan L. Harrington

sqlclearlyexplained

學習架設網站,要一步步慢學,不要妄想一步登天。原本學完Ruby後,打算直接學寫RAILS,然後發現自已不懂SQL。沒有SQL的基本功夫,不能有效地架設網站,任何網站都要用database來儲存資料啊。說起database程式,很多年前我學過dBase III,在中學電腦科被迫學了一個學期。當年覺得學一個過時的軟件很浪費時間,想不到database程式設計的最基本慨念,廿幾年後會從封塵的記憶中找出來有用。

我挑選了好幾本學習SQL的書,思前想後到底用那一本好,最後決定用這本SQL Clearly Explained為主幹,再用兩本O’Reilly的書為輔助參考。很多SQL的書只會教某一個SQL server的應用,很容易見樹不見林,分不清到底那些是SQL語言本身,那些是某一個server的syntax。這本書從SQL標準入手,第一章不是教你安裝軟件,而是很有系統地講解relational database的理論。只要基本知識清楚明白,學syntax很簡單,可以邊用邊學,查document摸摸下就上手。那兩本O’Reilly的書,一本教SQLite,另一本教MySQL,兩大常用的database。那兩本書不是好的入門書,內容太著重講syntax,不過卻是十分有用的reference書。

51vowxhiiul learning_sql_2nd_ed

Relational database的理論,說難不難,說易不易,領悟到就一理通百理明。Database是什麼,不外乎一堆table。Table就好似Excel的spreadsheet咁,打橫打直一行行,每格就是一項資料。每一行有一格係primary key,用來look up那一行。一行之又可以有foriegn key,連結另外一個table的primary key,表明table與table之間行與行的關係,謂之relation是也。檢查搜尋database只有6個基本操作,所有都只是萬變不離其中。6個操作包括,filter行(WHERE)或filter列(SELECT),把兩組行的行加起來(UNION),找出相同的行(INTERSECT),找出不同的行(EXCEPT),而最重要的操作是JOIN,即係連結起primary key同foreign key既relation。

此書的第二部份教SQL Syntax,實習第一部份的SQL理論。這本書的另一個優點,是書中附帶現成的database,一間二手書店的存貨買賣資料,不似其他書只講空談syntax。我把書中的例子輸入了SQLite檔案,並附上各table的csv檔案,有興趣的朋友可以在此下載SQL Clearly Explained Sample Database。學習SQL的次序,最先學搜查,如何在database中找出你想要的資料,其次學如何更新資料,最後才學如何建立設計database的table。所以有一個現成的database,再跟著書中的不同應用例子,學搜查很方便,事半功部。更新資料的syntax很簡單,有很輔助function讓你可以寫少幾行code,最重要的慨念是ACID transaction,說穿了就是multi-threads的synchronization problem,只是改了個好聽的acronym。設計table那一章教CREATE的syntax,不過我想沒有人會用SQL去直接起table,不是有其他GUI工具更好用嗎。起一個有效率的table是門很高深的學問,入門書教syntax只是教了table design的皮毛。

餘下的第三部份和第四部份,我只是快速略讀。SQL本身是一個turing-complete的程式語言,第三部份教SQL寫一般程式的syntax,只是我不明白有什麼人會用,SQL的PROCEDURE和TRIGGER只是search filter的輔助工具,真正要做heavy lifting資料運算,為什麼不把資料讀出來後,用host功能更強大的programming langauge去process。第四部份教SQL中XML的功能和Object Relational Data Model,不過除了Oracle或Microsft那些商用級的server,SQLite和MySQL都不支援這些功能,不過要搜查更新XML,用DOM不是更方便嗎?我想不到有什麼理由,要把XML直接當數據儲存在database中,為什麼不先解讀了XML中的資料,再有系統地儲放入table中呢?Open Source的server中,只有PostgreSQL支援Object Relational Data Model,簡單來說就是把OOP中的object儲存在database中,懂OOP的人學Object Model很簡單。Object Relation就在table的一格內,可以儲存一個object,或array,set等等,原本table的一格只可以儲存一個數值。另外一行可以用pointer直接link去另一行度,比用foreign key更有效率,因為不用做search。

學完SQL,忽然引起我對database的興趣,暫時放下RAILS,(反正要等RAILS-5的新書出版,沒有理由走去學RAILS-4),決定先學其他No-SQL database,看看還有什麼其他儲存資料的其他方法,才決定網站該採用那種database最好。