python、mysql三-2:數據類型

一 介紹

存儲引擎決定了表的類型,而表內存放的數據也要有不一樣的類型,每種數據類型都有本身的寬度,但寬度是可選的html

詳細參考:mysql

  • http://www.runoob.com/mysql/mysql-data-types.html
  • http://dev.mysql.com/doc/refman/5.7/en/data-type-overview.html

mysql經常使用數據類型概覽sql

#1. 數字:
    整型:tinyinit  int  bigint
    小數:
        float :在位數比較短的狀況下不精準
        double :在位數比較長的狀況下不精準
            0.000001230123123123
            存成:0.000001230000

        decimal:(若是用小數,則用推薦使用decimal)
            精準
            內部原理是以字符串形式去存

#2. 字符串:
    char10):簡單粗暴,浪費空間,存取速度快
        root存成root000000
    varchar:精準,節省空間,存取速度慢

    sql優化:建立表時,定長的類型往前放,變長的日後放
                    好比性別           好比地址或描述信息

    >255個字符,超了就把文件路徑存放到數據庫中。
            好比圖片,視頻等找一個文件服務器,數據庫中只存路徑或url。



#3. 時間類型:
    最經常使用:datetime


#4. 枚舉類型與集合類型
View Code

 

二 數值類型

一、整數類型數據庫

整數類型:TINYINT SMALLINT MEDIUMINT INT BIGINT服務器

做用:存儲年齡,等級,id,各類號碼等less

========================================
        tinyint[(m)] [unsigned] [zerofill]

            小整數,數據類型用於保存一些範圍的整數數值範圍:
            有符號:
                -128127
            無符號:
~ 255

            PS: MySQL中無布爾值,使用tinyint(1)構造。



========================================
        int[(m)][unsigned][zerofill]

            整數,數據類型用於保存一些範圍的整數數值範圍:
            有符號:
                    -21474836482147483647
            無符號:
~ 4294967295



========================================
        bigint[(m)][unsigned][zerofill]
            大整數,數據類型用於保存一些範圍的整數數值範圍:
            有符號:
                    -92233720368547758089223372036854775807
            無符號:
 ~  18446744073709551615
View Code
=========有符號和無符號tinyint==========
#tinyint默認爲有符號
MariaDB [db1]> create table t1(x tinyint); #默認爲有符號,即數字前有正負號
MariaDB [db1]> desc t1;
MariaDB [db1]> insert into t1 values
    -> (-129),
    -> (-128),
    -> (127),
    -> (128);
MariaDB [db1]> select * from t1;
+------+
| x    |
+------+
| -128 | #-129存成了-128
| -128 | #有符號,最小值爲-128
|  127 | #有符號,最大值127
|  127 | #128存成了127
+------+



#設置無符號tinyint
MariaDB [db1]> create table t2(x tinyint unsigned);
MariaDB [db1]> insert into t2 values
    -> (-1),
    -> (0),
    -> (255),
    -> (256);
MariaDB [db1]> select * from t2;
+------+
| x    |
+------+
|    0 | -1存成了0
|    0 | #無符號,最小值爲0
|  255 | #無符號,最大值爲255
|  255 | #256存成了255
+------+



============有符號和無符號int=============
#int默認爲有符號
MariaDB [db1]> create table t3(x int); #默認爲有符號整數
MariaDB [db1]> insert into t3 values
    -> (-2147483649),
    -> (-2147483648),
    -> (2147483647),
    -> (2147483648);
MariaDB [db1]> select * from t3;
+-------------+
| x           |
+-------------+
| -2147483648 | #-2147483649存成了-2147483648
| -2147483648 | #有符號,最小值爲-2147483648
|  2147483647 | #有符號,最大值爲2147483647
|  2147483647 | #2147483648存成了2147483647
+-------------+



#設置無符號int
MariaDB [db1]> create table t4(x int unsigned);
MariaDB [db1]> insert into t4 values
    -> (-1),
    -> (0),
    -> (4294967295),
    -> (4294967296);
MariaDB [db1]> select * from t4;
+------------+
| x          |
+------------+
|          0 | #-1存成了0
|          0 | #無符號,最小值爲0
| 4294967295 | #無符號,最大值爲4294967295
| 4294967295 | #4294967296存成了4294967295
+------------+




==============有符號和無符號bigint=============
MariaDB [db1]> create table t6(x bigint);
MariaDB [db1]> insert into t5 values  
    -> (-9223372036854775809),
    -> (-9223372036854775808),
    -> (9223372036854775807),
    -> (9223372036854775808);

MariaDB [db1]> select * from t5;
+----------------------+
| x                    |
+----------------------+
| -9223372036854775808 |
| -9223372036854775808 |
|  9223372036854775807 |
|  9223372036854775807 |
+----------------------+



MariaDB [db1]> create table t6(x bigint unsigned);
MariaDB [db1]> insert into t6 values  
    -> (-1),
    -> (0),
    -> (18446744073709551615),
    -> (18446744073709551616);

MariaDB [db1]> select * from t6;
+----------------------+
| x                    |
+----------------------+
|                    0 |
|                    0 |
| 18446744073709551615 |
| 18446744073709551615 |
+----------------------+




======用zerofill測試整數類型的顯示寬度=============
MariaDB [db1]> create table t7(x int(3) zerofill);
MariaDB [db1]> insert into t7 values
    -> (1),
    -> (11),
    -> (111),
    -> (1111);
MariaDB [db1]> select * from t7;
+------+
| x    |
+------+
|  001 |
|  011 |
|  111 |
| 1111 | #超過寬度限制仍然能夠存
+------+
驗證

 

注意:爲該類型指定寬度時,僅僅只是指定查詢結果的顯示寬度,與存儲範圍無關,存儲範圍以下ide

其實咱們徹底不必爲整數類型指定顯示寬度,使用默認的就能夠了函數

默認的顯示寬度,都是在最大值的基礎上加1性能

int的存儲寬度是4個Bytes,即32個bit,即2**32測試

無符號最大值爲:4294967296-1

有符號最大值:2147483648-1

有符號和無符號的最大數字須要的顯示寬度均爲10,而針對有符號的最小值則須要11位才能顯示徹底,因此int類型默認的顯示寬度爲11是很是合理的

最後:整形類型,其實沒有必要指定顯示寬度,使用默認的就ok

 

二、浮點型

定點數類型  DEC等同於DECIMAL  

浮點類型:FLOAT DOUBLE

做用:存儲薪資、身高、體重、體質參數等

======================================
#FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]

定義:
        單精度浮點數(非準確小數值),m是數字總個數,d是小數點後個數。m最大值爲255,d最大值爲30

有符號:
           -3.402823466E+38 to -1.175494351E-38,
           1.175494351E-38 to 3.402823466E+38
無符號:
           1.175494351E-38 to 3.402823466E+38


精確度: 
           **** 隨着小數的增多,精度變得不許確 ****


======================================
#DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]

定義:
           雙精度浮點數(非準確小數值),m是數字總個數,d是小數點後個數。m最大值爲255,d最大值爲30

有符號:
           -1.7976931348623157E+308 to -2.2250738585072014E-308
           2.2250738585072014E-308 to 1.7976931348623157E+308

無符號:
           2.2250738585072014E-308 to 1.7976931348623157E+308
            
精確度:
           ****隨着小數的增多,精度比float要高,但也會變得不許確 ****

======================================
decimal[(m[,d])] [unsigned] [zerofill]

定義:
          準確的小數值,m是數字總個數(負號不算),d是小數點後個數。 m最大值爲65,d最大值爲30。


精確度:
           **** 隨着小數的增多,精度始終準確 ****
           對於精確數值計算時須要用此類型
           decaimal可以存儲精確值的緣由在於其內部按照字符串存儲。
View Code
mysql> create table t1(x float(256,31));
ERROR 1425 (42000): Too big scale 31 specified for column 'x'. Maximum is 30.
mysql> create table t1(x float(256,30));
ERROR 1439 (42000): Display width out of range for column 'x' (max = 255)
mysql> create table t1(x float(255,30)); #建表成功
Query OK, 0 rows affected (0.02 sec)

mysql> create table t2(x double(255,30)); #建表成功
Query OK, 0 rows affected (0.02 sec)

mysql> create table t3(x decimal(66,31));
ERROR 1425 (42000): Too big scale 31 specified for column 'x'. Maximum is 30.
mysql> create table t3(x decimal(66,30));
ERROR 1426 (42000): Too-big precision 66 specified for 'x'. Maximum is 65.
mysql> create table t3(x decimal(65,30)); #建表成功
Query OK, 0 rows affected (0.02 sec)

mysql> show tables;
+---------------+
| Tables_in_db1 |
+---------------+
| t1            |
| t2            |
| t3            |
+---------------+
rows in set (0.00 sec)



mysql> insert into t1 values(1.1111111111111111111111111111111); #小數點後31個1
Query OK, 1 row affected (0.01 sec)

mysql> insert into t2 values(1.1111111111111111111111111111111);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t3 values(1.1111111111111111111111111111111);
Query OK, 1 row affected, 1 warning (0.01 sec)

mysql> select * from t1; #隨着小數的增多,精度開始不許確
+----------------------------------+
| x                                |
+----------------------------------+
| 1.111111164093017600000000000000 |
+----------------------------------+
row in set (0.00 sec)

mysql> select * from t2; #精度比float要準確點,但隨着小數的增多,一樣變得不許確
+----------------------------------+
| x                                |
+----------------------------------+
| 1.111111111111111200000000000000 |
+----------------------------------+
row in set (0.00 sec)

mysql> select * from t3; #精度始終準確,d爲30,因而只留了30位小數
+----------------------------------+
| x                                |
+----------------------------------+
| 1.111111111111111111111111111111 |
+----------------------------------+
row in set (0.00 sec)
驗證

 

三、位類型(瞭解)

BIT(M)能夠用來存放多位二進制數,M範圍從1~64,若是不寫默認爲1位。
注意:對於位字段須要使用函數讀取
    bin()顯示爲二進制
    hex()顯示爲十六進制

MariaDB [db1]> create table t9(id bit);
MariaDB [db1]> desc t9; #bit默認寬度爲1
+-------+--------+------+-----+---------+-------+
| Field | Type   | Null | Key | Default | Extra |
+-------+--------+------+-----+---------+-------+
| id    | bit(1) | YES  |     | NULL    |       |
+-------+--------+------+-----+---------+-------+

MariaDB [db1]> insert into t9 values(8);
MariaDB [db1]> select * from t9; #直接查看是沒法顯示二進制位的
+------+
| id   |
+------+
|     |
+------+
MariaDB [db1]> select bin(id),hex(id) from t9; #須要轉換才能看到
+---------+---------+
| bin(id) | hex(id) |
+---------+---------+
| 1       | 1       |
+---------+---------+

MariaDB [db1]> alter table t9 modify id bit(5);
MariaDB [db1]> insert into t9 values(8);
MariaDB [db1]> select bin(id),hex(id) from t9;
+---------+---------+
| bin(id) | hex(id) |
+---------+---------+
| 1       | 1       |
| 1000    | 8       |
+---------+---------+
驗證

 

三 日期類型

DATE TIME DATETIME TIMESTAMP YEAR 

做用:存儲用戶註冊時間,文章發佈時間,員工入職時間,出生時間,過時時間等

YEAR
            YYYY(1901/2155)

        DATE
            YYYY-MM-DD(1000-01-01/9999-12-31)

        TIME
            HH:MM:SS('-838:59:59'/'838:59:59')

        DATETIME

            YYYY-MM-DD HH:MM:SS(1000-01-01 00:00:00/9999-12-31 23:59:59    Y)

        TIMESTAMP

            YYYYMMDD HHMMSS(1970-01-01 00:00:00/2037 年某時)
View Code
============year===========
MariaDB [db1]> create table t10(born_year year); #不管year指定何種寬度,最後都默認是year(4)
MariaDB [db1]> insert into t10 values  
    -> (1900),
    -> (1901),
    -> (2155),
    -> (2156);
MariaDB [db1]> select * from t10;
+-----------+
| born_year |
+-----------+
|      0000 |
|      1901 |
|      2155 |
|      0000 |
+-----------+


============date,time,datetime===========
MariaDB [db1]> create table t11(d date,t time,dt datetime);
MariaDB [db1]> desc t11;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| d     | date     | YES  |     | NULL    |       |
| t     | time     | YES  |     | NULL    |       |
| dt    | datetime | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+

MariaDB [db1]> insert into t11 values(now(),now(),now());
MariaDB [db1]> select * from t11;
+------------+----------+---------------------+
| d          | t        | dt                  |
+------------+----------+---------------------+
| 2017-07-25 | 16:26:54 | 2017-07-25 16:26:54 |
+------------+----------+---------------------+



============timestamp===========
MariaDB [db1]> create table t12(time timestamp);
MariaDB [db1]> insert into t12 values();
MariaDB [db1]> insert into t12 values(null);
MariaDB [db1]> select * from t12;
+---------------------+
| time                |
+---------------------+
| 2017-07-25 16:29:17 |
| 2017-07-25 16:30:01 |
+---------------------+



============注意啦,注意啦,注意啦===========
1. 單獨插入時間時,須要以字符串的形式,按照對應的格式插入
2. 插入年份時,儘可能使用4位值
3. 插入兩位年份時,<=69,以20開頭,好比50,  結果2050      
                >=70,以19開頭,好比71,結果1971
MariaDB [db1]> create table t12(y year);
MariaDB [db1]> insert into t12 values  
    -> (50),
    -> (71);
MariaDB [db1]> select * from t12;
+------+
| y    |
+------+
| 2050 |
| 1971 |
+------+



============綜合練習===========
MariaDB [db1]> create table student(
    -> id int,
    -> name varchar(20),
    -> born_year year,
    -> birth date,
    -> class_time time,
    -> reg_time datetime);

MariaDB [db1]> insert into student values
    -> (1,'alex',"1995","1995-11-11","11:11:11","2017-11-11 11:11:11"),
    -> (2,'egon',"1997","1997-12-12","12:12:12","2017-12-12 12:12:12"),
    -> (3,'wsb',"1998","1998-01-01","13:13:13","2017-01-01 13:13:13");

MariaDB [db1]> select * from student;
+------+------+-----------+------------+------------+---------------------+
| id   | name | born_year | birth      | class_time | reg_time            |
+------+------+-----------+------------+------------+---------------------+
|    1 | alex |      1995 | 1995-11-11 | 11:11:11   | 2017-11-11 11:11:11 |
|    2 | egon |      1997 | 1997-12-12 | 12:12:12   | 2017-12-12 12:12:12 |
|    3 | wsb  |      1998 | 1998-01-01 | 13:13:13   | 2017-01-01 13:13:13 |
+------+------+-----------+------------+------------+---------------------+
驗證
在實際應用的不少場景中,MySQL的這兩種日期類型都可以知足咱們的須要,存儲精度都爲秒,但在某些狀況下,會展示出他們各自的優劣。下面就來總結一下兩種日期類型的區別。

1.DATETIME的日期範圍是1001——9999年,TIMESTAMP的時間範圍是1970——2038年。

2.DATETIME存儲時間與時區無關,TIMESTAMP存儲時間與時區有關,顯示的值也依賴於時區。在mysql服務器,操做系統以及客戶端鏈接都有時區的設置。

3.DATETIME使用8字節的存儲空間,TIMESTAMP的存儲空間爲4字節。所以,TIMESTAMP比DATETIME的空間利用率更高。

4.DATETIME的默認值爲null;TIMESTAMP的字段默認不爲空(not null),默認值爲當前時間(CURRENT_TIMESTAMP),若是不作特殊處理,而且update語句中沒有指定該列的更新值,則默認更新爲當前時間。
datetime與timestamp的區別

 

mysql> create table t1(x datetime not null default now()); # 須要指定傳入空值時默認取當前時間
Query OK, 0 rows affected (0.01 sec)

mysql> create table t2(x timestamp); # 無需任何設置,在傳空值的狀況下自動傳入當前時間
Query OK, 0 rows affected (0.02 sec)

mysql> insert into t1 values();
Query OK, 1 row affected (0.00 sec)

mysql> insert into t2 values();
Query OK, 1 row affected (0.00 sec)

mysql> select * from t1;
+---------------------+
| x                   |
+---------------------+
| 2018-07-07 01:26:14 |
+---------------------+
1 row in set (0.00 sec)

mysql> select * from t2;
+---------------------+
| x                   |
+---------------------+
| 2018-07-07 01:26:17 |
+---------------------+
1 row in set (0.00 sec)
 

四 字符串類型

#官網:https://dev.mysql.com/doc/refman/5.7/en/char.html
#注意:char和varchar括號內的參數指的都是字符的長度

#char類型:定長,簡單粗暴,浪費空間,存取速度快
    字符長度範圍:0-255(一箇中文是一個字符,是utf8編碼的3個字節)
    存儲:
        存儲char類型的值時,會往右填充空格來知足長度
        例如:指定長度爲10,存>10個字符則報錯,存<10個字符則用空格填充直到湊夠10個字符存儲

    檢索:
        在檢索或者說查詢時,查出的結果會自動刪除尾部的空格,除非咱們打開pad_char_to_full_length SQL模式(SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';)

#varchar類型:變長,精準,節省空間,存取速度慢
    字符長度範圍:0-65535(若是大於21845會提示用其餘類型 。mysql行最大限制爲65535字節,字符編碼爲utf-8:https://dev.mysql.com/doc/refman/5.7/en/column-count-limit.html)
    存儲:
        varchar類型存儲數據的真實內容,不會用空格填充,若是'ab  ',尾部的空格也會被存起來
        強調:varchar類型會在真實數據前加1-2Bytes的前綴,該前綴用來表示真實數據的bytes字節數(1-2Bytes最大表示65535個數字,正好符合mysql對row的最大字節限制,即已經足夠使用)
        若是真實的數據<255bytes則須要1Bytes的前綴(1Bytes=8bit 2**8最大表示的數字爲255)
        若是真實的數據>255bytes則須要2Bytes的前綴(2Bytes=16bit 2**16最大表示的數字爲65535)
    
    檢索:
        尾部有空格會保存下來,在檢索或者說查詢時,也會正常顯示包含空格在內的內容
#官網:https://dev.mysql.com/doc/refman/5.7/en/char.html
CHAR 和 VARCHAR 是最常使用的兩種字符串類型。
通常來講
CHAR(N)用來保存固定長度的字符串,對於 CHAR 類型,N 的範圍 爲 0 ~ 255
VARCHAR(N)用來保存變長字符類型,對於 VARCHAR 類型,N 的範圍爲 0 ~ 65 535
CHAR(N)和 VARCHAR(N) 中的 N 都表明字符長度,而非字節長度。
ps:對於 MySQL 4.1 以前的版本,如 MySQL 3.23 和 MySQL 4.0,CHAR(N)和 VARCHAR (N)中的 N 表明字節長度。

#CHAR類型
對於 CHAR 類型的字符串,MySQL 數據庫會自動對存儲列的右邊進行填充(Right Padded)操做,直到字符串達到指定的長度 N。而在讀取該列時,MySQL 數據庫會自動將 填充的字符刪除。有一種狀況例外,那就是顯式地將 SQL_MODE 設置爲 PAD_CHAR_TO_ FULL_LENGTH,例如:
mysql> CREATE TABLE t ( a CHAR(10));
      Query OK, 0 rows affected (0.03 sec)
mysql> INSERT INTO t SELECT 'abc';
      Query OK, 1 row affected (0.03 sec)
      Records: 1  Duplicates: 0  Warnings: 0
mysql> SELECT a,HEX(a),LENGTH(a) FROM t\G;
      *************************** 1. row ***************************
              a: abc
         HEX(a): 616263
      LENGTH (a): 3
row in set (0.00 sec)
      mysql> SET SQL_MODE='PAD_CHAR_TO_FULL_LENGTH';
      Query OK, 0 rows affected (0.00 sec)
mysql> SELECT a,HEX(a),LENGTH(a) FROM t\G;
      *************************** 1. row ***************************
              a: abc
         HEX(a): 61626320202020202020
      LENGTH (a): 10
row in set (0.00 sec)

在上述這個例子中,先建立了一張表 t,a 列的類型爲 CHAR(10)。而後經過 INSERT語句插入值「abc」,由於 a 列的類型爲 CHAR 型,因此會自動在後面填充空字符串,使其長 度爲 10。接下來在經過 SELECT 語句取出數據時會將 a 列右填充的空字符移除,從而獲得 值「abc」。經過 LENGTH 函數看到 a 列的字符長度爲 3 而非 10。
接着咱們將 SQL_MODE 顯式地設置爲 PAD_CHAR_TO_FULL_LENGTH。這時再經過 SELECT 語句進行查詢時,獲得的結果是「abc 」,abc 右邊有 7 個填充字符 0x20,並通 過 HEX 函數獲得了驗證。此次 LENGTH 函數返回的長度爲 10。須要注意的是,LENGTH 函數返回的是字節長度,而不是字符長度。對於多字節字符集,CHAR(N)長度的列最多 可佔用的字節數爲該字符集單字符最大佔用字節數 *N。例如,對於 utf8 下,CHAR(10)最 多可能佔用 30 個字節。經過對多字節字符串使用 CHAR_LENGTH 函數和 LENGTH 函數, 能夠發現二者的不一樣,示例以下:
mysql> SET NAMES gbk;
     Query OK, 0 rows affected (0.03 sec)
mysql> SELECT @a:='MySQL 技術內幕 '; Query OK, 0 rows affected (0.03 sec)
mysql> SELECT @a,HEX(@a),LENGTH(@a),CHAR_LENGTH(@a)\G; ***************************** 1. row **************************** a: MySQL 技術內幕
HEX(a): 4D7953514CBCBCCAF5C4DAC4BB
LENGTH (a): 13
CHAR_LENGTH(a): 9
row in set (0.00 sec)

變 量 @ a 是 g b k 字 符 集 的 字 符 串 類 型 , 值 爲 「 M y S Q L 技 術 內 幕 」, 十 六 進 制 爲 0x4D7953514CBCBCCAF5C4DAC4BB,LENGTH 函數返回 13,即該字符串佔用 13 字節, 由於 gbk 字符集中的中文字符佔用兩個字節,所以一共佔用 13 字節。CHAR_LENGTH 函數 返回 9,很顯然該字符長度爲 9。



#VARCHAR類型
VARCHAR 類型存儲變長字段的字符類型,與 CHAR 類型不一樣的是,其存儲時須要在 前綴長度列表加上實際存儲的字符,該字符佔用 1 ~ 2 字節的空間。當存儲的字符串長度小 於 255 字節時,其須要 1 字節的空間,當大於 255 字節時,須要 2 字節的空間。因此,對 於單字節的 latin1 來講,CHAR(10)和 VARCHAR(10)最大佔用的存儲空間是不一樣的, CHAR(10)佔用 10 個字節這是毫無疑問的,而 VARCHAR(10)的最大佔用空間數是 11 字節,由於其須要 1 字節來存放字符長度。
-------------------------------------------------
注意 對於有些多字節的字符集類型,其 CHAR 和 VARCHAR 在存儲方法上是同樣的,一樣 須要爲長度列表加上字符串的值。對於 GBK 和 UTF-8 這些字符類型,其有些字符是以 1 字節 存放的,有些字符是按 23 字節存放的,所以一樣須要 1 ~ 2 字節的空間來存儲字符的長 度。
-------------------------------------------------
雖然 CHAR 和 VARCHAR 的存儲方式不太相同,可是對於兩個字符串的比較,都只比 較其值,忽略 CHAR 值存在的右填充,即便將 SQL _MODE 設置爲 PAD_CHAR_TO_FULL_ LENGTH 也同樣,例如:
mysql> CREATE TABLE t ( a CHAR(10), b VARCHAR(10));
    Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO t SELECT 'a','a';
    Query OK, 1 row affected (0.00 sec)
    Records: 1  Duplicates: 0  Warnings: 0
mysql> SELECT a=b FROM t\G;
    *************************** 1. row ***************************
    a=b: 1
row in set (0.00 sec)
    mysql> SET SQL_MODE='PAD_CHAR_TO_FULL_LENGTH';
    Query OK, 0 rows affected (0.00 sec)
mysql> SELECT a=b FROM t\G;
    *************************** 1. row ***************************
    a=b: 1
row in set (0.00 sec)
官網詳解

 

Value CHAR(4) Storage Required VARCHAR(4) Storage Required
'' '    ' 4 bytes '' 1 byte
'ab' 'ab  ' 4 bytes 'ab' 3 bytes
'abcd' 'abcd' 4 bytes 'abcd' 5 bytes
'abcdefgh' 'abcd' 4 bytes 'abcd' 5 bytes

 

測試前瞭解兩個函數
length:查看字節數
char_length:查看字符數

1. char填充空格來知足固定長度,可是在查詢時卻會很不要臉地刪除尾部的空格(裝做本身好像沒有浪費過空間同樣),而後修改sql_mode讓其現出原形

mysql> create table t1(x char(5),y varchar(5));
Query OK, 0 rows affected (0.26 sec)

#char存5個字符,而varchar存4個字符
mysql> insert into t1 values('你瞅啥 ','你瞅啥 ');
Query OK, 1 row affected (0.05 sec)

mysql> SET sql_mode='';
Query OK, 0 rows affected, 1 warning (0.00 sec)

#在檢索時char很不要臉地將本身浪費的2個字符給刪掉了,裝的好像本身沒浪費過空間同樣,而varchar很老實,存了多少,就顯示多少
mysql> select x,char_length(x),y,char_length(y) from t1; 
+-----------+----------------+------------+----------------+
| x         | char_length(x) | y          | char_length(y) |
+-----------+----------------+------------+----------------+
| 你瞅啥    |              3 | 你瞅啥     |              4 |
+-----------+----------------+------------+----------------+
row in set (0.00 sec)

#略施小計,讓char現出原形
mysql> SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';
Query OK, 0 rows affected (0.00 sec)

#這下子char原形畢露了......
mysql> select x,char_length(x),y,char_length(y) from t1;
+-------------+----------------+------------+----------------+
| x           | char_length(x) | y          | char_length(y) |
+-------------+----------------+------------+----------------+
| 你瞅啥      |              5 | 你瞅啥     |              4 |
+-------------+----------------+------------+----------------+
row in set (0.00 sec)


#char類型:3箇中文字符+2個空格=11Bytes
#varchar類型:3箇中文字符+1個空格=10Bytes
mysql> select x,length(x),y,length(y) from t1;
+-------------+-----------+------------+-----------+
| x           | length(x) | y          | length(y) |
+-------------+-----------+------------+-----------+
| 你瞅啥      |        11 | 你瞅啥     |        10 |
+-------------+-----------+------------+-----------+
row in set (0.00 sec)
View Code
mysql> select concat('數據: ',x,'長度: ',char_length(x)),concat(y,char_length(y)
) from t1;
+------------------------------------------------+--------------------------+
| concat('數據: ',x,'長度: ',char_length(x))     | concat(y,char_length(y)) |
+------------------------------------------------+--------------------------+
| 數據: 你瞅啥  長度: 5                          | 你瞅啥 4                 |
+------------------------------------------------+--------------------------+
row in set (0.00 sec)
瞭解concat

 

點擊查看關於sql_mode的詳細介紹

2. 雖然 CHAR 和 VARCHAR 的存儲方式不太相同,可是對於兩個字符串的比較,都只比 較其值,忽略 CHAR 值存在的右填充,即便將 SQL _MODE 設置爲 PAD_CHAR_TO_FULL_ LENGTH 也同樣,,但這不適用於like

Values in CHAR and VARCHAR columns are sorted and compared according to the character set collation assigned to the column.

All MySQL collations are of type PAD SPACE. This means that all CHAR, VARCHAR, and TEXT values are compared without regard to any trailing spaces. 「Comparison」 in this context does not include the LIKE pattern-matching operator, for which trailing spaces are significant. For example:

mysql> CREATE TABLE names (myname CHAR(10));
Query OK, 0 rows affected (0.03 sec)

mysql> INSERT INTO names VALUES ('Monty');
Query OK, 1 row affected (0.00 sec)

mysql> SELECT myname = 'Monty', myname = 'Monty  ' FROM names;
+------------------+--------------------+
| myname = 'Monty' | myname = 'Monty  ' |
+------------------+--------------------+
|                1 |                  1 |
+------------------+--------------------+
row in set (0.00 sec)

mysql> SELECT myname LIKE 'Monty', myname LIKE 'Monty  ' FROM names;
+---------------------+-----------------------+
| myname LIKE 'Monty' | myname LIKE 'Monty  ' |
+---------------------+-----------------------+
|                   1 |                     0 |
+---------------------+-----------------------+
row in set (0.00 sec)
View Code

 

3. 總結

#InnoDB存儲引擎:建議使用VARCHAR類型
單從數據類型的實現機制去考慮,char數據類型的處理速度更快,有時甚至能夠超出varchar處理速度的50%。

但對於InnoDB數據表,內部的行存儲格式沒有區分固定長度和可變長度列(全部數據行都使用指向數據列值的頭指針),所以在本質上,使用固定長度的CHAR列不必定比使用可變長度VARCHAR列性能要好。於是,主要的性能因素是數據行使用的存儲總量。因爲CHAR平均佔用的空間多於VARCHAR,所以使用VARCHAR來最小化須要處理的數據行的存儲總量和磁盤I/O是比較好的。

#其餘字符串系列(效率:char>varchar>text)
TEXT系列 TINYTEXT TEXT MEDIUMTEXT LONGTEXT
BLOB 系列    TINYBLOB BLOB MEDIUMBLOB LONGBLOB 
BINARY系列 BINARY VARBINARY

text:text數據類型用於保存變長的大字符串,能夠組多到65535 (2**16 − 1)個字符。
mediumtext:A TEXT column with a maximum length of 16,777,215 (2**24 − 1) characters.
longtext:A TEXT column with a maximum length of 4,294,967,295 or 4GB (2**32 − 1) characters.
 

五 枚舉類型與集合類型

字段的值只能在給定範圍中選擇,如單選框,多選框
enum 單選 只能在給定的範圍內選一個值,如性別 sex 男male/女female
set 多選 在給定的範圍內能夠選擇一個或一個以上的值(愛好1,愛好2,愛好3...)

枚舉類型(enum)
            An ENUM column can have a maximum of 65,535 distinct elements. (The practical limit is less than 3000.)
            示例:
                CREATE TABLE shirts (
                    name VARCHAR(40),
                    size ENUM('x-small', 'small', 'medium', 'large', 'x-large')
                );
                INSERT INTO shirts (name, size) VALUES ('dress shirt','large'), ('t-shirt','medium'),('polo shirt','small');

  

            集合類型(set)
            A SET column can have a maximum of 64 distinct members.
            示例:
                CREATE TABLE myset (col SET('a', 'b', 'c', 'd'));
                INSERT INTO myset (col) VALUES ('a,d'), ('d,a'), ('a,d,a'), ('a,d,d'), ('d,a,d');
View Code
MariaDB [db1]> create table consumer( 
    -> name varchar(50),
    -> sex enum('male','female'),
    -> level enum('vip1','vip2','vip3','vip4','vip5'), #在指定範圍內,多選一
    -> hobby set('play','music','read','study') #在指定範圍內,多選多
    -> );

MariaDB [db1]> insert into consumer values  
    -> ('egon','male','vip5','read,study'),
    -> ('alex','female','vip1','girl');

MariaDB [db1]> select * from consumer;
+------+--------+-------+------------+
| name | sex    | level | hobby      |
+------+--------+-------+------------+
| egon | male   | vip5  | read,study |
| alex | female | vip1  |            |
+------+--------+-------+------------+
驗證
相關文章
相關標籤/搜索