轉帖|行業資訊|編輯:龔雪|2015-10-15 15:38:11.000|閱讀 290 次
概述:在新建表和數據倉庫時,往往需要做出許多決定。一些在當時看起來似乎是無關緊要的決定,卻最終會導致你和你的客戶在使用數據庫的整個過程中飽嘗痛苦。本文中的十個技巧,讓你免于這些困擾。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
在新建表和數據倉庫時,往往需要做出許多決定。一些在當時看起來似乎是無關緊要的決定,卻最終會導致你和你的客戶在使用數據庫的整個過程中飽嘗痛苦。
我們已經和數千人以及他們的數據庫打過交道了,在經歷了無數個小時的讀寫查詢之后,可以說我們幾乎見過所有的情況了。下面是我們總結出的有助于創建無痛模式(Schema)的10條規則。
不要在數據庫、模式、表格或者列名上使用點、空格或者破折號。因為點號是用來識別對象的,通常只在 database.schema.table.column 這種情況下使用。
在對象的名字中也包含點號會帶來困擾。同樣地,在對象名中使用空格將迫使你給查詢加入一堆不必要的引號:
另外,一旦在表格或者列名上使用了大寫字母,查詢就會變得更加難寫。因為如果全部都是小寫字母的話,人們就沒有必要去特別記憶用戶表到底是Users還是users。
不僅如此,當你最終變更數據庫或者將表復制到數據倉庫中時,除了一些數據庫以外,你無須記住哪個數據庫是大小寫敏感的。
如果users表需要定義一個引用了packages表的外鍵,那么將其命名為package_id是個不錯的選擇。我們應該避免像是pkg_fk這樣的又短又含糊的列名,因為其他人很難知道那是什么意思。具有描述性的名字能夠使得其他人更容易理解模式,而且當團隊擴大時這一點對于保持工作效率也是很重要的。
不要使用模棱兩可的名字命名可能有多種解釋方法的數據。如果你發現自己正在以item_type或item_value這樣的命名風格創建列時,那么可能就說明你應該使用更多的帶有具體名字的列了,像是photo_count、view_count和transaction_price。
因為這樣做的話,列中存儲了什么樣的數據總是可以由模式得知的,而并不需要由行中的其他值推導出來。
不要使用表名作為列名的前綴。因為一般來說在users表中定義諸如user_birthday、user_created_at或者user_name這樣的列名起不到什么輔助作用。
最后,還要避免將諸如column、tag或user這樣的保留關鍵字用作列名。因為一旦使用了保留關鍵字,就意味著不得不在查詢語句中使用額外的引用符,而當有人忘記這么做的時候,數據庫就會產生非常令人困惑的錯誤信息。而且如果在本該是列名出現地方使用了關鍵字,那么數據庫就無法理解查詢語句。
如果表名是由多個單詞組成的,那么請使用下劃線分割它們。因為package_deliveries要比packagedeliveries更容易讀。
如果可能的話,總是使用一個單詞而不是兩個,因為deliveries要更加容易閱讀。
不要用模式的名字作為表名的前綴。如果你需要將一些表劃入一個范圍,那么只需將這些表放入到一個模式中即可。和有前綴的列名一樣,諸如store_items、store_transactions或者store_coupons這樣的表名,通常都是不需要額外的前綴的。
我們推薦使用復數形式的名字為表命名(例如packages),并且對聯合表的表名中的兩個單詞也都使用復數形式。單數形式的表名更可能意外地與關鍵字沖突并且一般在查詢中其可讀性也不高。
無論你是正在使用各種UUID(通用唯一識別碼)類型的列作為主鍵,還是你認為加入帶有自增長整型序列的主鍵根本沒有意義(比如對于聯合表),我們都建議你添加一個帶有自增長整型序列的標準id列。這種類型的主鍵會使得特定的分析變得更加容易,比如從一組數據中只選出第一行。
并且當導入數據的工作導致了數據的重復時,主鍵也會成為靈丹妙藥,因為我們可以通過主鍵輕松刪除特定的行:
避免多列主鍵。當努力編寫高效的查詢時,多列主鍵將會導致查詢語句很難理解,并且很難修改。我們可以使用一個整型的主鍵,或者一個多列的唯一約束,再或者一些單列的索引來取代多列主鍵。
命名主鍵和外鍵有許多種風格。我們建議諸位使用的是最為普遍的風格,即對于任意的表格foo,將foo中的主鍵命名為id,將所有的外鍵命名為foo_id。
另一種風格是使用全局統一的主鍵名。在這種風格下,表foo的主鍵稱為foo_id,而所有的外鍵也稱為foo_id。不過無論使用哪種風格,使用縮寫的話(比如將users表縮寫為uid),總是會造成困擾或名稱沖突,所以應該避免使用縮寫。
而且,無論你選用了什么風格,都要堅持下去。不要在某些地方使用uid,而又在其他地方使用user_id或者users_fk。
除此之外還要留意外鍵并不顯式匹配一張表的情況。一個名為owner_id的列可能是users表的一個外鍵,當然也可能不是。因此如果有必要的話,請將作為外鍵的列命名為user_id或者owner_user_id。
不要使用Unix的時間戳或者字符串來存儲日期,而是要將它們轉換為各種日期時間類型。雖然SQL的日期計算函數并不是最棒的,但是調用這些函數來處理時間戳總比自己來處理要簡單。在查詢時,我們需要為每一個涉及到從timestamp到datetime類型的轉換的查詢調用SQL的日期函數。
不要將年、月、日分別存儲到不同的列中。因為這樣會導致每個有關時間序列的查詢都更加難寫,而且也會在使用這張表的日期信息時給大多數的SQL初學者造成障礙。
使用時區而不是UTC將導致無窮無盡的問題。好的工具(包括我們的Periscope)擁有你所需要的從UTC轉換為你所在時區數據的所有功能。在Periscope中,簡單地加個:pst就可以將UTC轉換為太平洋時間。
應該將數據庫的時區設為UTC,并且所有datetime的列都應該是剝離時區后的類型(如,無時區的timestamp)。
如果你的數據庫的時區不是UTC,或者你的數據庫混合了UTC和非UTC時間日期,那么時間序列的分析查詢將會變得更加困難。
一塊數據應該只有單一的真相源(Source of Truth)。視圖和匯總(Rollup)本身應該有所標示。這樣做的話,數據的消費者就會知道他們使用的數據和原生真相之間的區別。
另一方面,將諸如user_id、user_id_old或者user_id_v2的遺留列都保留的話,只會帶來無盡的困擾。因此請確保在日常維護中會進行刪除廢棄的表格和不再使用的字段的工作。
請不要使用列過多的表。如果一張表有超過幾十個列并且其中一些是以序列命名(例如,answer1、answer2、answer3)的話,那么馬上你就會感到不好過了。
正確的做法是將這樣的表轉化為不包含重復列的模式,因為這樣的模式將很容易查詢。例如,在一個查詢中計算某個調查表中已完成的題目的數目:
對于查詢分析而言,從JSON列抽出數據的操作將大幅降低查詢的性能。雖然有很多很棒的理由支持我們在產品中使用JSON列,但是對于查詢分析來說并不是這樣。大膽得將JSON列拆解為更簡單數據類型,可以使查詢分析變得更快更容易。
日期,郵編和國家不需要使用帶有外鍵查詢的表單獨存放。過度地規范化將會導致每個查詢后面都要帶上一些相同的表連接操作。這樣不但創建了許多重復的SQL,而且數據庫為此還要做很多額外的工作。
表是數據庫中的一等對象,擁有很多屬于自己的數據。其余的任何數據都可以作為另一個更重要對象的附加列。
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn