天天看點

MySQL Meta 資訊與 CREATE TABLE 的對應關系前情提要混亂的MySQL定義總結

下面四篇文章是數月之前對length的了解

<a href="http://blog.csdn.net/maray/article/details/48657119">mysql meta中的length字段 -- (1) 初始值的length計算</a>

<a href="http://blog.csdn.net/maray/article/details/48660725">mysql meta中的length字段 -- (2) length的推導</a>

<a href="http://blog.csdn.net/maray/article/details/48687731">mysql meta中的length字段 -- (3) length的推導舉例</a>

<a href="http://blog.csdn.net/maray/article/details/48712329">mysql meta中的length字段 -- (4) 玩兒mysql代碼</a>

溫故而知新,幾個月後,對 length 等 meta 資訊的了解又進一步,本文再記之。

用“混亂”這個詞有點大言不慚,但是,mysql通過sql語句描述 length、scale、precision、display width這幾個概念,描述手法真的很混亂。

你能清楚地描述 length、scale、precision、display width 四個概念嗎?他們的差別與關聯是什麼?create table 語句如何表達這四個概念?

如果你能說清楚,就已經掌握,不用看本文了。說不清楚,就聽我慢慢道來。

本文簡單起見,隻以 mysql 的四大類資料類型作為範例讨論:

整形(int、tinyint、mediumint、bigint)

浮點(float、double)

字元串(binary、char、varbinary、varchar)

定點數(decimal)

建立一個包含上面4中類型的表:

i int(3)

其中 3 僅僅表示display width,i 的 precision 為 11,也就是說,insert into sample (i) values (1234567) 是沒問題的,盡管1234567的位數超過了3位。它的 scale 為 0。它的 length 是 3,它的 length 是 3,它的 length 是 3(重要事情說三遍!!!),display width 等于 length。

在這種情況下,如果用戶端傻乎乎地按照length的值配置設定記憶體,必将buffer溢出。怎麼辦?用戶端才不會相信伺服器傳來的這個值,它完全可以根據type=long來配置設定一個最大buffer,確定任意整數都能放得下。

了解了上面的概念後,回去好好看看自己寫的 server 代碼,是不是把 length 和 precision 的概念弄混了? 再來個例子加強了解:

f double(4, 1),

4 表示 precision,1 表示 scale,length 為4 + 1 + 1 = 6。其中 length 的算法為 precision + 小數點1位 + 符号位1位。 display width 有意義的前提是有 zerofill 标記。如果有 zerofill 标記,則自動為 unsigned,是以 display width = precision + 小數點1位, length = precision + 小數點 1 位。 總結一下:沒有zerofill,length 有意義, display width 無意義;有 zerofill,length 和 display width 相等。

d decimal(6, 1),

因為 decimal 會用于金融領域,mysql 那幫孫子也謹慎起來,把 decimal 的行為實作得非正常範,所有的行為都可以解釋。 6 表示 precision,1 表示 scale,length = precision + 小數點1 + 符号位1 = 8。如果後面加上 zerofill,則 length = precision + 小數點 = 7, display width = length = 7。

下面專門寫一個case來驗證上面對decimal的分析,同時證明 mysql 那幫人的不嚴肅。按道理講,decimal 和 double 在 precision、scale、length 上的表現行為應該是一緻的,但實際偏偏不是,請看:

看!除了type不同,其餘都一樣,但計算出來的length、填充的0的個數,居然不一樣。沒别的原因,mysql 的浮點類型實作得不對。

c varchar(5)

precision、scale都無意義,預設為0,length=5,display width無意義。

字元類型在這四大類中是最簡單的,其次是定點數,整形和浮點數都有點bug,根本就無法“了解”

display width 僅僅在有zerofill、且為基礎列的時候有意義

當 display width 有意義的時候,display width = length

length 總是有意義,它表示一個列轉化成字元串時需要用多少個位元組來容納

create table語句中的數字,對不同類型的意義不同:

整形:display width

浮點:precision、scale、display width、length

定點:precision、scale、display width、length

字元:length

繼續閱讀