關於資料儲存型別的一點分析
簡介
SQL Server每個表中各列的資料型別的有各種形式,產生的效果也各有不同,我們主要根據效率兼顧效能的情況下討論下如何規定型別。
在SQL Server中,資料的儲存以頁為單位。八個頁為一個區。一頁為8K,一個區為64K,這個意味著1M的空間可以容納16個區。 SQL Server中的分配單元分為三種,分別為儲存行內資料的In_Row_Data,儲存Lob物件的LOB_Data,儲存溢位資料的Row_Overflow_data。下面我們通過一個更具體的例子來理解這三種分配單元。
我建立如圖2所示的表。
圖2.測試表
圖2的測試表不難看出,通過插入資料使得每一行的長度會超過每頁所能容納的最大長度8060位元組。使得不僅產生了行溢位(Row_Overflow_Data),還需要儲存LOB的頁.測試的插入語句和通過DBCC IND看到的分配情況如圖3所示。
圖3.超過8060位元組的行所分配的頁
除去IAM頁,這1行資料所需要三個頁來儲存。首先是LOB頁,這類是用於儲存存在資料庫的二進位制檔案所設計,當這個型別的列出現時,在原有的列會儲存一個24位元組的指標,而將具體的二進位制資料存在LOB頁中,除去Text之外,VarBinary(max)也是存在LOB頁中的。然後是溢位行,在SQL Server 2000中,一行超過8060位元組是不被允許的,在SQL Server 2005之後的版本對這個特性進行了改進,使用Varchar,nvarchar等資料型別時,當行的大小不超過8060位元組時,全部存在行內In-row data,當varchar中儲存的資料過多使得整行超過8060位元組時,會將額外的部分存於Row-overflow data頁中,如果update這列使得行大小減少到小於8060位元組,則這行又會全部回到in-row data頁。
資料型別的選擇
在瞭解了一些基礎知識之後。我們知道SQL Server讀取資料是以頁為單位,更少的頁不僅僅意味著更少的IO,還有更少的記憶體和CPU資源消耗。所以對於資料選擇的主旨是:
儘量使得每行的大小更小
這個聽起來非常簡單,但實際上還需要對SQL Server的資料型別有更多的瞭解。
比如儲存INT型別的資料,按照業務規則,能用INT就不用BIGINT,能用SMALLINT就不用INT,能用TINYINT就不用SMALLINT。
所以為了使每行的資料更小,則使用佔位元組最小的資料型別。
1.比如不要使用DateTime型別,而根據業務使用更精確的型別,如下表:
型別
所佔位元組
Date(僅日期)
3
Time(僅時間)
5
DateTime2(時間和日期)
8
DateTimeOffSet(外加時區)
10
2.使用VarChar(Max),Nvarchar(Max),varbinary(Max)來代替text,ntext和image型別
根據前面的基礎知識可以知道,對於text,ntext和image型別來說,每一列只要不為null,即使佔用很小的資料,也需要額外分配一個LOB頁,這無疑佔用了更多的頁。而對於Varchar(Max)等資料型別來說,當資料量很小的時候,存在In-row-data中就能滿足要求,而不用額外的LOB頁,只有當資料溢位時,才會額外分配LOB頁,除此之外,Varchar(Max)等型別支援字串操作函式比如:
- COL_LENGTH
- CHARINDEX
- PATINDEX
- LEN
- DATALENGTH
- SUBSTRING
3.對於僅僅儲存數字的列,使用數字型別而不是Varchar等。
因為數字型別佔用更小的儲存空間。比如儲存123456789使用INT型別只需要4個位元組,而使用Varchar就需要9個位元組(這還不包括Varchar還需要佔用4個位元組記錄長度)。
4.如果沒有必要,不要使用Nvarchar,Nchar等以“字”為單位儲存的資料型別。這類資料型別相比varchar或是char需要更多的儲存空間。
5.關於Char和VarChar的選擇
這類比較其實有一些了。如果懶得記憶,大多數情況下使用Varchar都是正確的選擇。我們知道Varchar所佔用的儲存空間由其儲存的內容決定,而Char所佔用的儲存空間由定義其的長度決定。因此Char的長度無論儲存多少資料,都會佔用其定義的空間。所以如果列儲存著像郵政編碼這樣的固定長度的資料,選擇Char吧,否則選擇Varchar會比較好。除此之外,Varchar相比Char要多佔用幾個位元組儲存其長度,下面我們來做個簡單的實驗。
首先我們建立表,這個表中只有兩個列,一個INT型別的列,另一個型別定義為Char(5),向其中插入兩條測試資料,然後通過DBCC PAGE來檢視其頁內結構,如圖4所示。
下面我們再來看改為Varchar(5),此時的頁資訊,如圖5所示。
圖5.Varchar(5),每行所佔用的空間為20位元組
因此可以看出,Varchar需要額外4個位元組來記錄其內容長度。因此,當實際列儲存的內容長度小於5位元組時,使用char而不是varchar會更節省空間。
關於Null的使用
關於Null的使用也是略有爭議。有些人建議不要允許Null,全部設定成Not Null+Default。這樣做是由於SQL Server比較時就不會使用三值邏輯(TRUE,FALSE,UNKNOWN),而使用二值邏輯(True,False),並且查詢的時候也不再需要IsNull函式來替換Null值。
但這也引出了一些問題,比如聚合函式的時候,Null值是不參與運算的,而使用Not Null+Default這個值就需要做排除處理。
因此Null的使用還需要按照具體的業務來看。
考慮使用稀疏列(Sparse)
稀疏列是對 Null 值採用優化的儲存方式的普通列。 稀疏列減少了 Null 值的空間需求,但代價是檢索非 Null 值的開銷增加。 當至少能夠節省 20% 到 40% 的空間時,才應考慮使用稀疏列。
稀疏列在SSMS中的設定如圖6所示。
圖6.稀疏列
更具體的稀疏列如何能節省空間,請參看MSDN。
對於主鍵的選擇
對於主鍵的選擇是表設計的重中之重,因為主鍵不僅關係到業務模型,更關係到對錶資料操作的的效率(因為主鍵會處於B樹的非葉子節點中,對樹的高度的影響最多)。這個我們得結合主鍵索引的選擇來具體分析,之前寫過一篇關於索引的,以後有需要再進一步延伸來講
總結
本篇文章對於設計表時,資料列的選擇進行了一些探尋。好的表設計不僅僅是能滿足業務需求,還能夠滿足對效能的優化。
相關推薦
關於資料儲存型別的一點分析
簡介 SQL Server每個表中各列的資料型別的有各種形式,產生的效果也各有不同,我們主要根據效率兼顧效能的情況下討論下如何規定型別。 在SQL Server中,資料的儲存以頁為單位。八個頁為一個區。一頁為8K,一個區為64K,這個意味著1M的空間可以容納16個區。 SQL
NAR:gcMeta——全球微生物組資料儲存和標準化分析平臺
文章目錄 gcMeta全球微生物組資料儲存和標準分析平臺 導讀 摘要 正文 圖1.使用者資料管理、分析及釋出流程 圖2.資料庫結構 表1.平臺內建工具 圖3.使用者介面展示
C語言筆記之資料儲存型別
變數的儲存型別是指儲存變數值的記憶體型別。變數的儲存型別決定變數何時建立,何時銷燬以及他的值要儲存多久。 在任何程式碼塊之外申明的變數總是儲存與靜態記憶體中(不屬於堆疊的記憶體),這叫做靜態(static)變數。對於這種變數,你無法為他們指定其
【MYSQL】金額(金錢)相關的資料儲存型別
int 對於遊戲幣等代幣,一般儲存為int型別是可行的。 問題在於越界,int型別長度為11位。 在儲存人民幣相關的金額的時候,則只能儲存到9長度的人民幣,也就是說,最大隻能儲存999999999,不到10億的數值,如果業務增長很快的話,就會給自己留下隱患
C++資料儲存型別
和C語言一樣,C++也為靜態儲存持續性變數提供了3種連結性:外部連結性(可在其他檔案中訪問)、內部連結性(只能在當前檔案中訪問)和無連結性(只能在當前函式或程式碼中訪問)。這3種連結性都在整個程式執行期間存在,與自動變數相比,它們的壽命更長。由於靜態變數的數目在程式執行期間是不變的,因此程式不需要使用特殊的裝
棧和佇列資料儲存型別---佇列(簡單瞭解)
引言 前面介紹了棧資料儲存型別,下面接著介紹佇列資料儲存型別。佇列和棧一樣也被用作程式設計師的工具。佇列也是一種資料結構,有點類似棧,只是在佇列中第一個插入的資料項也會最先被移除,先進先出。佇列的作用就像人們排隊買東西,第一個排隊的人對於後面的人來說就是隊頭,隊伍最後一
SQL SERVER大話儲存結構(1)_資料頁型別及頁面指令分析
SQLServer的資料頁大小是8kb,8個連續的物理頁組成一個區。區分混合區跟統一區,混合區內可以儲存不同資料庫物件的內容,通常這個資料庫物件較小;統一區表示區內連續的8個數據頁儲存的都是同一個資料庫物件的內容。 SQL SERVER的磁碟讀寫是按頁級進行,每次I/O操作的資料最小
11.1 js中級,資料型別、資料儲存方式、作用域記憶體空間的區別以及例識別。
一. 基本資料型別和引用資料型別的區別。 1.基本資料型別:基本資料型別就是簡單的操作值。 2.引用資料型別:就是把引用的地址賦給變數。 堆記憶體: 就是存放程式碼塊的,存放形式有兩種 1)物件以鍵值對的形式存放 2)引用資料型別的賦值,是把引用
讀取blob型別圖片資料 儲存到本地
如何將blob型別資料的圖片資料從資料庫中讀取出來,並儲存到本地呢? 程式碼如下: 定義一個實體類: public class IdeaImgOutVo { private byte[] photo;//圖片 private String plNO;//手冊編碼
原創 | 入門資料分析--資料儲存之常用資料庫及區別
獲取資料,除了通過外部獲得,內部獲取,也是一個主要獲取資料的方式。內部資料主要是通過資料庫儲存的方式,將資料存下來,便於各個需求方再去提取應用。那麼,企業常用的儲存資料的資料庫都有哪些呢?不同的資料庫的儲存區別又有哪些? 目前市場上的資料庫主要可以分為關係型資料庫和非關係型資料庫,關係型資料庫通過外來鍵關聯
Docker容器進階--建立映象、資料管理、網路、儲存型別
一、Docker映象建立方法--基於已有映象、基於本地模板; 基於已有映象: 1.準備映象: 2.準備容器: 3.將容器建立成為docker映象檔案: 基於本地模板: 1.下載本地作業系統模板: https://download.open
海量電力裝置監測資料儲存分析
關於海量電力裝置監測資料的儲存和特徵分析的詳細教程: 海量電力裝置監測資料的儲存和特徵分析 電力裝置線上監測指在不停電的情況下,對電力裝置狀況進行連續或週期性地自動監視檢測,使用的技術包括:感測器技術、廣域通訊技術和資訊處理技術。電力裝置線上監測是實現電力裝置狀態執行檢修管理、提升生產執行管
JSON檔案的應用——記錄型別的使用者資料儲存
章節索引 前提 從問題出發 JSON和XML 專精JSON JSON檔案讀與寫 (1)讀JSON檔案 (2)正向對映 (3)反向對映 (4)寫JSON檔案 後記 前提
【案例】Danone依靠Matrikon進行資料儲存和分析
Matrikon是基於OPC UA和基於OPC的控制自動化資料互操作性產品的供應商,提供自動化廠商的高階OPC UA開發工具包,適用於從嵌入式裝置到雲應用的所有產品線。對於終端使用者客戶,Matrikon提供了關鍵資料工具,以最好地促進企業廣泛的資料共享。 Danone是一家致力於通過保證食品安
【乾貨】各區塊鏈底層資料儲存分析(一)
網際網路的中心化發展模式是傳統網路安全的的軟肋,區塊鏈作為一種去中心化、集體維護、不可篡改的新興技術,是對網際網路底層架構的革新,是對當今生產力和生產關係的變革。區塊鏈也被譽為是繼蒸汽機、電力、資訊和網際網路科技之後,目前最有潛力觸發第五輪顛覆性革命浪潮的核心技術。 目前
c#資料型別/變數/常量/計算機資料儲存(進位制之間的相互轉化)
一c#資料型別 注:值型別:值直接儲存在堆疊中(儲存空間小,呼叫速度快); 引用型別:值儲存在堆中(儲存空間大,呼叫速度慢) 1.值型別 a. 值型別變數可以直接分配給一個值.它們是從類System.ValueType中派生的. b.值型別直接儲存其值. c.值型別的例項通常是線上程棧上
首頁 Hadoop Spark Hive Kafka Flume 大資料平臺 Kylin 專題文章 Spark運算元 一起學Hive Hive儲存過程 Hive分析函式 Spark On Yarn 資料
關鍵字: orc、index、row group index、bloom filter index之前的文章《更高的壓縮比,更好的效能–使用ORC檔案格式優化Hive》中介紹了Hive的ORC檔案格式,它不但有著很高的壓縮比,節省儲存和計算資源之外,還通過一個內建的輕量級索引
python 全棧開發:資料型別整體分析
資料型別初始 資料型別: int :用於計算。 例子:1、2、3、4、.......................... 常用方法操作: bit_length() ps:求一個數字轉換成二進
以太坊資料儲存原始碼分析
上一篇主要講解了MPT的基本原理,這篇分析一下以太坊資料儲存相關的流程。 首先介紹一下MPT的儲存流程,然後依次分析StateDB、Transactions、Receipts的儲存,這3棵樹的Merkle Root最終會儲存到區塊Header中的Root、TxH
SSM框架Jsp頁面POST提交的中文資料儲存到資料庫變成亂碼問題的分析
在SSM框架搭建的專案中,當在頁面表單提交(POST方式)漢字資料時,儲存到資料庫中是亂碼,遇到這個情況有以下幾個原因,等到一一排除改正之後,基本上不會出現這個問題了: 這裡我以UTF-8編碼為標準,整個環節都是用UTF-8(也可以使用其它編碼格式,但是要保證編碼一致性)