Mysql_Learning_Notes_系統結構_1_數據類型

數據類型

整型

1.tinyint 1Bytes -128~127(255)
2.smallint 2Bytes -32768~32676(65535)
3.mdeiumint 3Bytes -8388608~8388607(16777215)
4.int 4Bytes -2147483648~2147483647(4294967295,42億)
5.bigint 8Bytes -9223372036854775808~9223372036854775807(18446744073709551615)
int列若是是主鍵不能online DDL 轉成bigint.mysql

  • onlineDDL
    :pt-osc(更容易致使主從數據延時,執行過程報錯,沒法從上一個位置開始,只能重頭開始,pt 建立trigger 或者刪除trigger 的時候 有坑。 )和gh-ost(推薦,因基於binlog,能夠隨時中止或繼續).推薦使用gh-st

int(11),11是修飾符,不是長度限制,int(8)zerofill zerofill也是修飾符,左側補零.
溢出:
cast(9223372036854775807 as unsigned) 改成不符號sql

  • IPv4地址能夠用INT存儲:
    select length('255.255.255.255')
    +---------------------------+
    | length('255.255.255.255') |
    +---------------------------+
    | 15 |
    +---------------------------+
    root@localhost [(none)]>select inet_aton('255.255.255.255'); //IPv4最大值,正好是int的無符號數最大值.
    +------------------------------+
    | inet_aton('255.255.255.255') |
    +------------------------------+
    | 4294967295 |
    +------------------------------+
    root@localhost [(none)]>select inet_ntoa(4294967295);
    +-----------------------+
    | inet_ntoa(4294967295) |
    +-----------------------+
    | 255.255.255.255 |
    +-----------------------+函數

  • IPv6和IPv4共用的方法(數據類型爲VARBINARY(16),而不是BINARY(16)。惟一的緣由是MySQL函數同時適用於IPv6和IPv4地址。 BINARY(16)只適用於存儲IPv6地址,並保存一個字節。在處理IPv6和IPv4地址時應使用VARBINARY(16)):ui

root@localhost [(none)]>SELECT HEX(INET6_ATON('fdfe::5a55:caff:fefa:9089'));
+----------------------------------------------+
| HEX(INET6_ATON('fdfe::5a55:caff:fefa:9089')) |
+----------------------------------------------+
| FDFE0000000000005A55CAFFFEFA9089 |
+----------------------------------------------+
1 row in set (0.00 sec)
root@localhost [(none)]>SELECT HEX(INET6_ATON('192.168.9.1'));
+--------------------------------+
| HEX(INET6_ATON('192.168.9.1')) |
+--------------------------------+
| C0A80901 |
+--------------------------------+
1 row in set (0.00 sec)unix

mysql> SELECT INET6_NTOA(INET6_ATON('fdfe::5a55:caff:fefa:9089'));
-> 'fdfe::5a55:caff:fefa:9089'
mysql> SELECT INET6_NTOA(INET6_ATON('192.168.9.1'));
-> '192.168.9.1'code

mysql> SELECT INET6_NTOA(UNHEX('FDFE0000000000005A55CAFFFEFA9089'));
-> 'fdfe::5a55:caff:fefa:9089'
mysql> SELECT INET6_NTOA(UNHEX('C0A80901'));
-> '192.168.9.1'對象

  • 時間戳也是推薦使用無符號int也存儲.
    select unix_timestamp();
    root@localhost [(none)]>select unix_timestamp();
    +------------------+
    | unix_timestamp() |
    +------------------+
    | 1539644023 |
    +------------------+
    1 row in set (0.00 sec)
    root@localhost [(none)]>select from_unixtime(1539644023);
    +---------------------------+
    | from_unixtime(1539644023) |
    +---------------------------+
    | 2018-10-16 06:53:43 |
    +---------------------------+
    1 row in set (0.00 sec)

時間

優先使用:timestamp,其次datetime
timetamp\datetime 從5.6.6開始均支持自動更新爲current_timestamp
日期轉換:
CAST()datetime_col as DATE)
SELECT NOW()+0;排序

root@localhost [wenyz]>SELECT NOW()+0;
+----------------+
| NOW()+0 |
+----------------+
| 20181016075647 |
+----------------+
1 row in set (0.00 sec)table

root@localhost [wenyz]>SELECT NOW();
+---------------------+
| NOW() |
+---------------------+
| 2018-10-16 07:56:54 |
+---------------------+
1 row in set (0.00 sec)ast

root@localhost [wenyz]>select CAST(now() as DATE)
-> ;
+---------------------+
| CAST(now() as DATE) |
+---------------------+
| 2018-10-16 |
+---------------------+
1 row in set (0.00 sec)

root@localhost [wenyz]>select CAST(now() as DATE);
+---------------------+
| CAST(now() as DATE) |
+---------------------+
| 2018-10-16 |
+---------------------+
1 row in set (0.00 sec)

root@localhost [wenyz]>select CAST(now() as time);
+---------------------+
| CAST(now() as time) |
+---------------------+
| 07:57:53 |
+---------------------+
1 row in set (0.00 sec)

root@localhost [wenyz]>select now(),now()+5;
+---------------------+----------------+
| now() | now()+5 |
+---------------------+----------------+
| 2018-10-16 07:59:36 | 20181016075941 |
+---------------------+----------------+
1 row in set (0.00 sec)

字符

1.char(M) Mw(字符集的單字符字節數) bytes,0<=M<=255 (utf8 2553,utf8.mb4:2554)
2.BINARY(M) M bytes,0<=M<=255
3.VARCHAR(M),VARBINARY(M) L+1 bytes if column values require 0-255 bytes if values may require more than 255 bytes,L+2bytes if values may require more than 255 bytes.(除M
w都須要額外1或2個節點存信息),實際存儲長度超過255字節時,會被作TEXT處理.全部VARCHAR列的總可用長度是65535字節(其實是65533)
字符集是utf8mb4時,實際可存儲字符數是FLOOR(65533/4)=16384
4.mysql8.0默認字符集是utf8mb4

長文本\大對象

data type storange required
tinyblob,tinytext L+1bytes,where L<2^8
Blob,text L+1bytes,where L<2^16
mediumblob,mediumtext L+4bytes,where L<2^24
longlob,longtext L+4bytes,where L<2^32
  • 超長字段有可能會發生行溢出Off page (overflow)存儲.一個page爲16k,當一行超過8k時就會發現行溢出.
  • 儘可能不能,沒法避免時則儘可能獨立表存放
  • 對text列排序時,實際排序長是max_sort_length字節(默認1kb,排序時最多隻考慮字段的前1kb)
  • 實例:一個100G的表拆分紅4個表後,總大小僅25G

    浮點\小數位

    FLOAT是單精度
  • 用於存儲通常精確度金額
  • 事實上,更建議把金額轉換成INT來存儲,更精確.
  • FLOAT列類不指定精度時不能等值查詢
    • num FLOAT,where num=0.12,查詢結果爲空,須要用範圍查詢.
    • num FLOAT(9,7),where num=0.12,能夠查詢到.
      DECIMAL
  • 精確的十進制浮點型,高精度計算
  • M最大65(默認10),D最大30(默認0)
  • 小數點後面的位數超限後,自動四捨五入(SQL_MODE=''時)

枚舉,ENUM

ENMU(VALUE_LIST)

  • Value_list數量不超過255時,佔用1個字節,超過期佔2字節,最多65535個
  • 表面上是用字符型表示,但實際底層採用INT來存儲,顯示時再轉換爲以前存儲表示的值
  • 因此,能夠直接用TINYINT/SMALLINT代替(在單獨的字典表裏對應1表示xxx,2表示bbb,在須要枚舉的列直接用數字來表示就能夠了),
  • 使用注意:千萬不要用char或vchar來存儲枚舉.

類型選擇建議:

  • 最大限度減小IO請求
  • 讓數據表每行長度越小越好,能夠避免行遷移或碎片
  • 有TEXT/BLOB等大列時,儘可能拆分到獨立子表中,或者使用TokuDB引擎
  • 常常更新的列和不常常更新的列分開不一樣的表存儲.
  • 更新數據也儘量不要讓長度變大.
相關文章
相關標籤/搜索