mysql三-2:數據類型

1、介紹

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

詳細參考:mysql

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

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

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

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

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

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


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


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

2、數值類型

一、整數類型: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
=========有符號和無符號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 | #超過寬度限制仍然能夠存
+------+
5.6版本驗證

  5.7版本mysql,在插入數據超出數據類型範圍時,直接報錯。服務器

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

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

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

顯示寬度和存儲寬度區分:全部類型的存儲寬度都已經固定死了,可以修改的僅僅只是顯示寬度。優化

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

  無符號最大值爲:4294967296-1

  有符號最大值:2147483648-1

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

  最後:整形類型,其實沒有必要指定顯示寬度,使用默認的就ok。而除了整型類型外,其餘數據類型的寬度就是存儲寬度

二、浮點型

  定點數類型DEC等同於DECIMAL

  浮點類型:FLOAT   DOUBLE

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

(1)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

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

(2)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高,但也會變得不許確。

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

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

  精確度:隨着小數的增多,精度始終準確。

      對於精確計算時須要使用此類型。decimal可以存儲精確值的緣由在於其內部按照字符串存儲。

  缺點:數字總個數只有65.

mysql> create table t8(x float(255,30));
Query OK, 0 rows affected (0.01 sec)

mysql> create table t9(x double(255,30));      
Query OK, 0 rows affected (0.01 sec)

mysql> create table t10(x decimal(65,30));          
Query OK, 0 rows affected (0.02 sec)

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

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

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

mysql> select * from t8;    # 隨着小數的增多,精度降低
+----------------------------------+
| x                                |
+----------------------------------+
| 1.111111164093017600000000000000 |   
+----------------------------------+
1 row in set (0.00 sec)

mysql> select * from t9;   # 精度也會降低,比float強一點
+----------------------------------+
| x                                |
+----------------------------------+
| 1.111111111111111200000000000000 |
+----------------------------------+
1 row in set (0.00 sec)

mysql> select * from t10;  # 精度始終準確
+----------------------------------+
| x                                |
+----------------------------------+
| 1.111111111111111111111111111111 |
+----------------------------------+
1 row in set (0.00 sec)
浮點型測試驗證

3、日期類型 

  日期類型: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 年某時)
各類日期類型的時間範圍
mysql> create table student(
    -> id int,
    -> name char(6),    # 存儲寬度  
    -> born_year year,     # YEAR類型
    -> birth_date date,     # DATE類型   
    -> class_time time,     # TIME類型
    -> reg_time datetime       # DATETIME類型
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> insert into student values
    -> (1, 'egon', now(), now(), now(),now());
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> select * from student;
+------+------+-----------+------------+------------+---------------------+
| id   | name | born_year | birth_date | class_time | reg_time            |
+------+------+-----------+------------+------------+---------------------+
|    1 | egon |      2018 | 2018-05-10 | 16:13:49   | 2018-05-10 16:13:49 |
+------+------+-----------+------------+------------+---------------------+
1 row in set (0.00 sec)

mysql> insert into student values
    -> (2, 'alex', '1988', '1988-1-12', '12:12:12', "2017-12-12 12:12:12");   # 注意是分號結束
Query OK, 1 row affected (0.00 sec)

mysql> select * from student;
+------+------+-----------+------------+------------+---------------------+
| id   | name | born_year | birth_date | class_time | reg_time            |
+------+------+-----------+------------+------------+---------------------+
|    1 | egon |      2018 | 2018-05-10 | 16:13:49   | 2018-05-10 16:13:49 |
|    2 | alex |      1988 | 1988-01-12 | 12:12:12   | 2017-12-12 12:12:12 |
+------+------+-----------+------------+------------+---------------------+
2 rows in set (0.00 sec

  在多行輸入時,若是發現輸入錯誤想取消當前輸入,能夠在當前行輸入「\c」,若是前面有一個引號,能夠在\c前加一個對應的引號。

二、datetime與timestamp的區別

  在實際應用的不少場景中,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。

4、字符串類型

  官網詳解:https://dev.mysql.com/doc/refman/5.7/en/char.html

  注意:CHAR 和 VARCHAR 是最經常使用的兩種字符串類型。

一、char類型

  定長,簡單粗暴,浪費空間,存取速度快。

  字符長度範圍:0-255(一箇中文是一個字符,是utf8編碼的三個字節)

  存儲:

    存儲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)數據庫最好存放精簡數據,大文件存放在文件服務器中。

  檢索:

    尾部有空格會保存下來,在檢索或者說查詢時,也會正常顯示包含空格在內的內容。 

官網解釋以下:

    

測試前瞭解兩個函數:

  length:查看字節數

  char_length:查看字符數

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

mysql> create table t13(name char(5));
Query OK, 0 rows affected (0.02 sec)

mysql> create table t14(name varchar(5));
Query OK, 0 rows affected (0.02 sec)

mysql> insert into t13 value('李傑 ');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t14 values('李傑 ');
Query OK, 1 row affected (0.01 sec)

# 在檢索時char很不要臉地將本身浪費的2個字符給刪掉了,裝得好像本身沒浪費過空間同樣,而varchar很老實,存了多少就顯示多少
mysql> select char_length(name) from t13;   # char存的是五個字符,但查詢只顯示了2個
+-------------------+
| char_length(name) |
+-------------------+
|                 2 |
+-------------------+
1 row in set (0.01 sec)

mysql> select char_length(name) from t14;   # varchar是有幾個存幾個,所以應該是3個
+-------------------+
| char_length(name) |
+-------------------+
|                 3 |
+-------------------+
1 row in set (0.01 sec)

# 執行下面的命令,修改模式,讓char現出原形
mysql> SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';
Query OK, 0 rows affected, 1 warning (0.00 sec)

# 再次檢查,就會顯示char存的是五個字符
mysql> select char_length(name) from t13;
+-------------------+
| char_length(name) |
+-------------------+
|                 5 |
+-------------------+
1 row in set (0.00 sec)

mysql> select char_length(name) from t14;
+-------------------+
| char_length(name) |
+-------------------+
|                 3 |
+-------------------+
1 row in set (0.00 sec)

# mysql在比較時,無論末尾的空格
mysql> select name from t13 where name='李傑';  # 比較無論末尾空格
+-----------+
| name      |
+-----------+
| 李傑      |
+-----------+
1 row in set (0.00 sec)

mysql> select name from t13 where name='           李傑';   # 只會去掉末尾的空格
Empty set (0.00 sec)

# char類型:2箇中文字符+3個空格=2*3+3=9 Bytes
mysql> select name, length(name) from t13;
+-----------+--------------+
| name      | length(name) |
+-----------+--------------+
| 李傑      |            9 |
+-----------+--------------+
1 row in set (0.00 sec)

# varchar類型:2箇中文類型+1個空格=2*3+1=7 Bytes
mysql> select name, length(name) from t14;
+---------+--------------+
| name    | length(name) |
+---------+--------------+
| 李傑    |            7 |
+---------+--------------+
1 row in set (0.00 sec)
驗證操做實例

  點擊查看sql_mode詳細介紹

二、雖然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)

# like查詢的時候,就不會去掉末尾的空格了,必須保證是完整的
mysql> select name from t13 where name like '李傑 ';
Empty set (0.00 sec)

mysql> select name from t13 where name like '李傑  ';
Empty set (0.00 sec)

mysql> select name from t13 where name like '李傑   ';
+-----------+
| name      |
+-----------+
| 李傑      |
+-----------+
1 row in set (0.00 sec)
like查詢與空格填充驗證

三、總結

  (1)經常使用字符串系列:char與varchar對比

  char類型的優勢是簡單,存取速度都比較快,可是浪費空間。

  varchar類型優勢是更加節約空間,存取速度都比較慢,存須要先存頭再存數據,取須要先讀頭再取數據。

  由於如今設備的存儲空間已經再也不那麼緊缺,系統更在乎數據的存取速度,所以大部分狀況都是使用char類型。

  平時使用中,儘可能把定長的數據往前放,把變長的數據日後放。儘可能不要在一張表中char和varchar混用。

  (2)其餘字符串系列(效率: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.

5、枚舉類型和集合類型 

  字段的值只能在給定範圍中選擇,如單選框,多選框

  enum 單選 只能在給定的範圍內選一個值,如性別 sex 男male/女female

  set 多選 在給定的範圍內能夠選擇一個或一個以上的值(愛好1,愛好2,愛好3...)

mysql> create table consumer(
    -> id int,
    -> name char(16),
    -> sex enum('male', 'female', 'other'),     # 在範圍內多選一
    -> level enum('vip1', 'vip2', 'vip3'),
    -> hobbies set('play', 'music', 'read', 'run')    # 在範圍內多選多
    -> );
Query OK, 0 rows affected (0.02 sec)

mysql> insert into consumer values
    -> (1,'egon','male','vip2','music');
Query OK, 1 row affected (0.00 sec)

mysql> select * from consumer;
+------+------------------+------+-------+---------+
| id   | name             | sex  | level | hobbies |
+------+------------------+------+-------+---------+
|    1 | egon             | male | vip2  | music   |
+------+------------------+------+-------+---------+
1 row in set (0.00 sec)

mysql> insert into consumer values (2,'alex','xxx','vip2','music');    # 亂填的內容不會正常顯示     
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> select * from consumer;
+------+------------------+------+-------+---------+
| id   | name             | sex  | level | hobbies |
+------+------------------+------+-------+---------+
|    1 | egon             | male | vip2  | music   |
|    2 | alex             |      | vip2  | music   |
+------+------------------+------+-------+---------+
2 rows in set (0.00 sec)

mysql> insert into consumer values (3,'zuli','female','vip3','music,play');    
Query OK, 1 row affected (0.01 sec)

mysql> select * from consumer;
+------+------------------+--------+-------+------------+
| id   | name             | sex    | level | hobbies    |
+------+------------------+--------+-------+------------+
|    1 | egon             | male   | vip2  | music      |
|    2 | alex             |        | vip2  | music      |
|    3 | zuli             | female | vip3  | play,music |
+------+------------------+--------+-------+------------+
3 rows in set (0.00 sec)
枚舉和集合類型使用驗證
相關文章
相關標籤/搜索