1. 程式人生 > >mysql三-2:資料型別

mysql三-2:資料型別

一 介紹

儲存引擎決定了表的型別,而表記憶體放的資料也要有不同的型別,每種資料型別都有自己的寬度,但寬度是可選的

詳細參考:

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

mysql常用資料型別概覽

#1. 數字:
    整型:tinyinit  int  bigint
    小數:
        float :在位數比較短的情況下不精準
        double :在位數比較長的情況下不精準
            
0.000001230123123123 存成:0.000001230000 decimal:(如果用小數,則用推薦使用decimal) 精準 內部原理是以字串形式去存 #2. 字串: char(10):簡單粗暴,浪費空間,存取速度快 root存成root000000 varchar:精準,節省空間,存取速度慢 sql優化:建立表時,定長的型別往前放,變長的往後放 比如性別 比如地址或描述資訊 >255個字元,超了就把檔案路徑存放到資料庫中。 比如圖片,視訊等找一個檔案伺服器,資料庫中只存路徑或url。
#3. 時間型別: 最常用:datetime #4. 列舉型別與集合型別
View Code

二 數值型別

1、整數型別

整數型別:TINYINT SMALLINT MEDIUMINT INT BIGINT

作用:儲存年齡,等級,id,各種號碼等

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

            小整數,資料型別用於儲存一些範圍的整數數值範圍:
            有符號:
                
-128 ~ 127 無符號: 0 ~ 255 PS: MySQL中無布林值,使用tinyint(1)構造。 ======================================== int[(m)][unsigned][zerofill] 整數,資料型別用於儲存一些範圍的整數數值範圍: 有符號: -2147483648 ~ 2147483647 無符號: 0 ~ 4294967295 ======================================== bigint[(m)][unsigned][zerofill] 大整數,資料型別用於儲存一些範圍的整數數值範圍: 有符號: -9223372036854775808 ~ 9223372036854775807 無符號: 0 ~ 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 | #超過寬度限制仍然可以存
+------+
驗證

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

其實我們完全沒必要為整數型別指定顯示寬度,使用預設的就可以了

預設的顯示寬度,都是在最大值的基礎上加1

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

無符號最大值為:4294967296-1

有符號最大值:2147483648-1

有符號和無符號的最大數字需要的顯示寬度均為10,而針對有符號的最小值則需要11位才能顯示完全,所以int型別預設的顯示寬度為11是非常合理的

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

2、浮點型

定點數型別  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            |
+---------------+
3 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 |
+----------------------------------+
1 row in set (0.00 sec)

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

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

3、位型別(瞭解)

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
      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,HEX(a),LENGTH(a) FROM t\G;
      *************************** 1. row ***************************
              a: abc
         HEX(a): 61626320202020202020
      LENGTH (a): 10
      1 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
1 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 位元組 存放的,有些字元是按 2 或 3 位元組存放的,因此同樣需要 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
    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
    1 row in set (0.00 sec)
官網詳解
ValueCHAR(4)Storage RequiredVARCHAR(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 |
+-----------+----------------+------------+----------------+
1 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 |
+-------------+----------------+------------+----------------+
1 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 |
+-------------+-----------+------------+-----------+
1 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                 |
+------------------------------------------------+--------------------------+
1 row in set (0.00 sec)
瞭解concat

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 |
+------------------+--------------------+
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 |
+---------------------+-----------------------+
1 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('
            
           

相關推薦

mysql-2:資料型別

一 介紹 儲存引擎決定了表的型別,而表記憶體放的資料也要有不同的型別,每種資料型別都有自己的寬度,但寬度是可選的 詳細參考: http://www.runoob.com/mysql/mysql-data-types.html http://dev.mysql.com/doc/refman/5.7/

2mysql的一般資料型別

int:整形 double/float:浮點型 char:char(10) 固定長度字元竄 Varchar:varchar(10) 可變長度字元竄 text:大文字型別 blob:位元組型別,多用於儲存圖片 date:日期格式,為yyy-MM-dd time:時間型別,格

2.資料型別和變數

1.整數 1 100 -100 299 使用type(100)打印出資料的型別 print(type(100))  <class 'int'> 2.浮點數 3.1415 -0.999 26.0 使用type(3.1415)打印出資料型別 prin

Pandas學習2 --- 資料型別Series、DataFrame

Pandas的資料型別 Series(一維資料結構) Dataframe Series --- 帶標籤的一維陣列 常用的初始化方法: 可迭代物件 np陣列 字典物件 標量 一、Series 1. Series初始化 匯入 import pan

C語言第天-資料型別,if switch,for while

背會!!! 格式字元有d,o,x,u,c,s,f,e,g等。  如 %d整型輸出,%ld長整型輸出, %o以八進位制數形式輸出整數, %x以十六進位制數形式輸出整數,或輸出字串的地址。 %u以十進位制數輸出unsigned型資料(無符號數)。注意:%d與%u有無符號的數

day 4 - 2 資料型別練習

1. 在字串中數字相連的為一組,輸出數字共有幾組 如: 123sdf456sdf789  數字為:3組   info = input(">>>") for i in info: if i.isalpha(): info = info.r

mysql欄位資料型別設定

               下載LOFTER我的照片書  | 1、選項是可列舉的,設定成enum型別可以提高資料庫效能   &n

Python學習2——資料型別

整型 num01 = 100 num01 = 100 #十進位制 num02 = 0x6F #十六進位制 num03 = 0o41 #八進位制 print (num01) print (num02) print (num03) 打印出來的結果都是十進位制

《高效能MySQL》筆記——MySQL建表資料型別的選擇

前段時間看了《高效能MySQL》中的選擇優化的資料型別,這裡主要是做一下筆記。 首先資料選擇有幾個簡單原則: 更小的通常更好。一般情況下,應該儘量使用可以正確儲存資料的最小資料型別。例如只需要存 0~200,tinyint unsigned 更好。更小的資料型別通常更快,因為它們佔

MySQL欄位資料型別

欄位是列表中 的列名,列是表的重要組成部分,MySQL資料庫中,列中的每一個數據都需要指定其所屬型別,以確保資料的準確性和系統 的穩定性。 欄位資料型別分為三類:數值型別、字串型別、時間日期型別。 數值型: 整數: tinyint(1byte --> -128 —— 127 ) tin

MySQL的float資料型別注意

摘要: 公司專案資料庫中儲存金額欄位使用float型別,在金額達到10W時出現小數丟失,部分資料四捨五入的問題,將資料型別替換為DECIMAL後解決該問題。主要原因就是原來人員沒有搞清楚float的使用陷阱和使用場景,以下內容就是自己查詢部分同學的資料後實驗所得。 MySQ

2.資料型別

2.資料型別     1位元組=8位  例如:11111111=1*2^0+1*2^1+……+1*2^6+1*2^7 2.1    基本資料型別: 整型:byte(1)short(2)int(4)long(8) //整型:byte(

Mysql使用Blob資料型別存取圖片

一般情況下圖片的儲存在hdfs上,資料庫只儲存圖片的路徑,特殊情況採用這個方案。 資料庫方面: 實體方面採用byte陣列進行存取: private byte[] img; 我在本地磁碟放了一張圖片,現在進行讀取: public String save(){ //建立

mysql欄位資料型別選擇

選擇優化的資料型別 MySQL支援的資料型別非常多, 選擇正確的資料型別對於獲得高效能至關重要。 更小的通常更好 更小的資料型別通常更快, 因為它們佔用更少的磁碟、 記憶體和CPU快取, 並且處理時需要的CPU週期也更少。 簡單就好 簡單資料型別的操作通常需要更少的CPU週期。

mysql 和 Oracle 資料型別對照

MySQL與Oracle兩種資料庫在工作中,都是用的比較多的資料庫,由於MySQL與Oracle在資料型別上有部分差異,在我們遷移資料庫時,會遇上一定的麻煩,下面介紹MySQL與Oracle資料庫資料型別的對應關係。 一、常見資料型別在MySQL與Oracle資料庫中的表現形式  

《瘋狂Java講義》學習筆記(資料型別和運算子

1、註釋 Java語言的註釋一共有三種類型 單行註釋:用雙斜線 ”//” 表示 多行註釋:用 /*------------------*/ 表示 文件註釋:用 /**-----------------*/ 表示 如果編寫Java原始碼時添加了合適的文件註釋,然後通過JDK提供的jav

資料型別 String

一、Windows下操作 Redis 1、啟動服務 2、使用客戶端連線服務 二、String型別操作 String 是 redis 最基本的型別 redis 的 String 可以包含任何資料,包括jpg或者序列化物件 單個value值最大上限1G 操作

python 第資料型別之方法

# list # [element, , , ] element 數字 字串 列表 bool 等等都可以 # str 字串集合 list 容器 # 取範圍 得到list li = [1, 2, 3, 4, 5, 6, 7] print(li, li[1:3]) for item in li:

Mysql 選擇優化資料型別

原則: 更小的通常更好(一般情況下,儘量使用最小的資料型別) 簡單就好 儘量避免NULL 整數型別 實數型別 字串型別   VARCHAR:可變長字串。VARCHAR需要使用1或兩個額外位元組來記錄字串長度。所以VARCHAR型別最大長度不能超過  65535。(字元

MySQL的date資料型別轉換問題及兩個時間戳時間間隔的時間

由於更換資料庫的原因,MySQL遇到了各種坑。 在MySQL資料庫裡建表表欄位為COLLECT_TIME     TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 實際上該欄位是date。很奇怪, 然後在java裡面獲取該欄位值居然是英文的時間戳