高性能MYSQL讀書要點摘錄_3_Schema與數據類型優化

一 選擇優化的數據類型

  1.  更小的一般更好:佔用更少的磁盤,內存 ,CPU。同時要確保沒有低估要存儲值的範圍。mysql

  2.  簡單就好:簡單的數據類型操做一般須要更少的CPU週期。好比 整形比字符操做的代價更低。sql

  3. 儘可能避免NULL:一般狀況下最好指定列爲NOT NULL,除非真的要存儲爲NULL。由於若是查詢中包含NULL的列,對MYSQL來講更難優化,由於可爲NULL的列使得索引,索引統計和值比較都更加複雜。同時 可爲NULL的列會使用更多的存儲空間,在MYSQL裏須要特殊處理。緩存

  4. 爲列肯定合適的數據類型,第一步須要肯定合適的大類型:數字,字符串,時間等;第二步,選擇具體的類型。不少MYSQL的數據類型能夠存儲爲相同的數據類型,只是存儲的長度和範圍不同、容許的精度不一樣,相同大類型的不一樣子類型數據有時也有一些特殊的行爲和屬性。例如datetime和timestamp列均可以存儲相同的類型的數據:時間和日期,精確到秒。然而timestamp只使用datetime一半的存儲空間,而且會根據時區變化,具備特殊的自動更新能力。另外一方面,TIMESTAMP容許的時間範圍要小的多,有時候它的特殊能力會成爲障礙。MYSQL爲了兼容性支持不少別名,例如INTEGER,BOOL,NUMERIC都是整形,只是別名不一樣。經過show create table 能夠查看基本類型,而不是別名。服務器

二 整數類型

    整數類型包含:TINYINT,SMALLINT,MEDIUMINT,INT,BIGINT。分別使用8,16,24,32,64位存儲空間。整數類型可選UNSIGNED屬性,表示不容許負值,可使得正數的上限提升一倍。有符號和無符號類型使用相同的存儲空間,而且有相同的性能,所以能夠根據實際狀況選擇合適的類型。
數據結構

    MYSQL能夠爲整數類型指定寬度,例如INT(11),對大多數應用沒有意義的:它不會限制值的合法範圍,只是規定了MYSQL的一些交互工具(例如MYSQL命令行客戶端)用來顯示字符的個數。對於存儲和計算來講,INT(1)和INT(20)是相同的。
app


三 實數類型

    MySQL即支持精確的類型,也支持不精確的類型。FLOAT和DOUBLE支持標準的浮點運算進行近似計算。DECIMAL類型用於存儲精確的小數。
函數

    浮點類型和DECIMAL類型均可以指定精度。對於DECIMAL列,能夠指定小數點先後所容許的最大位數。這會影響列的空間消耗。例如,DECIMAL(18,9)小數點的兩邊將各存儲9個數字,一共使用9個字節:小數點前的數字用4個字節,小數點後的數字用4個字節,小數點自己佔一個字節。
工具


四 字符串類型

    VARCHAR和CHAR類型是兩種最主要的字符串類型。VARCHAR類型用於存儲可變長字符串,它比定長類型更加省空間,由於它僅使用必要的空間。VARCHAR須要使用1或2個額外字節記錄字符串的長度。CHAR適合存儲很短的字符串,或者全部值長度接近的。例如 CHAR很是適合存儲密碼的MD5值。
性能

    與CHAR和VARCHAR相似的類型還有BINARY和VARBINARY,它們存儲的是二進制字符串。二進制字符串存儲的是字節碼而不是字符。二進制存儲相對於字符存儲有比較方面的優點,按字節比較速度更快。
優化

    BLOB和TEXT類型都是爲了存儲很大的數據而設計的字符串類型,分別採用二進制和字符方式存儲。BLOB存儲的是二進制數據,沒有排序規則或字符集,而TEXT類型有字符集和排序的規則。同時 MYSQL不能將BLOB和TEXT列所有長度的字符串進行索引,也不能使用這些索引消除排序。

    使用枚舉代替字符串類型,MYSQL會根據對應的關係 保存枚舉類型的整形數值。

CREATE TABLE ENUM_TEST(e ENUM('fish','apple','dog') not null);
INSERT INTO ENUM_TEST(e) VALUES('fish'),('dog'),('apple');
--- 經過下面查詢能夠看到MYSQL實際存儲的數值----

select e+0 from enum_test;

----若是想指定枚舉查詢的排序能夠經過field()實現---
select e from enum_test order by field(e,'apple','dog','fish');


五 日期和時間類型

    DATETIME: 保存的範圍較大,從1001年到9999年,精度爲秒。使用8個字節的存儲空間。

    TIMESTAMP:存儲從1970年1月1日午夜開始的秒數,和unix時間戳類型。使用4個字節的存儲空間 只能到2038年。

MYSQL提供了FROM_UNIXTIME()和UNIX_TIMESTAMP()函數實現日期和UNIX時間戳的相互轉換。


六 其餘類型

    位數據類型:BIT ,SET; 

    特殊數據類型好比存儲IPv4時要把它存儲爲整形 ,能夠經過mysql的inet_aton() 和inet_ntoa()函數實現IP字符形式和整數形式的轉換。


七 schema設計中的陷阱

  1. 太多的列:MYSQL服務器層和存儲引擎層之間經過行緩衝格式拷貝數據。若是列數太多,列轉成行數據結構代價也會高。

  2. 太多的關聯:單個查詢最好在12個表之內作關聯。

  3. 全能的枚舉:防止過分使用枚舉。

  4. 變相的枚舉:ENUM列容許存儲單個枚舉值,集合(SET)容許存儲一個或多個值。有時在這兩個類型的選擇容易混淆。

  5. NULL:能夠經過使用0,或特殊值或空字符串代替NULL。

八 範式和反範式

    1 範式的優勢和缺點:範式化的更新操做一般比反範式化要快;數據範式化好時,一般不多或者沒有重複數據,因此修改更快;範式化的表一般更小,能夠更好的放在內存裏,因此執行操做會更快;範式化的缺點是一般須要更多的關聯操做,同時可能會使一些索引策略無效;

    2 反範式化的優勢和缺點:能夠更好的避免關聯操做,有效的使用索引策略;缺點是須要額外的存儲空間。

    3 設計表結構時能夠混用範式化和反範式化。

九 表結構設計其餘技巧

  1. 使用緩存表和彙總表。。。。。。。。。


本文連接:http://my.oschina.net/robinyao/blog/596561

相關文章
相關標籤/搜索