MySQL數據類型


MySQL數據庫中的數據類型

數據類型(data_type)是指系統中所允許的數據的類型。MySQL 數據類型定義了列中可以存儲什么數據以及該數據怎樣存儲的規則。

數據庫中的每個列都應該有適當的數據類型,用於限制或允許該列中存儲的數據。例如,列中存儲的為數字,則相應的數據類型應該為數值類型。

如果使用錯誤的數據類型可能會嚴重影響應用程序的功能和性能,所以在設計表時,應該特別重視數據列所用的數據類型。更改包含數據的列不是一件小事,這樣做可能會導致數據丟失。因此,在創建表時必須為每個列設置正確的數據類型和長度。

MySQL 的數據類型有大概可以分為 5 種,分別是整數類型、浮點數類型和定點數類型、日期和時間類型、字符串類型、二進制類型等。

1.MySQL整數類型

整數類型又稱數值型數據,數值型數據類型主要用來存儲數字。

MySQL 提供了多種數值型數據類型,不同的數據類型提供不同的取值范圍,可以存儲的值范圍越大,所需的存儲空間也會越大。

MySQL 主要提供的整數類型有 TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT,其屬性字段可以添加 AUTO_INCREMENT 自增約束條件。
下表中列出了 MySQL 中的數值類型。

類型名稱 說明 存儲需求
TINYINT 很小的整數 1個字節
SMALLINT 小的整數 2個宇節
MEDIUMINT 中等大小的整數 3個字節
INT (INTEGHR) 普通大小的整數 4個字節
BIGINT 大整數 8個字節

從上表中可以看到,不同類型的整數存儲所需的字節數不相同,占用字節數最小的是 TINYINT 類型,占用字節最大的是 BIGINT 類型,占用的字節越多的類型所能表示的數值范圍越大。

根據占用字節數可以求出每一種數據類型的取值范圍。例如,TINYINT 需要 1 個字節(8bit)來存儲,那么 TINYINT 無符號數的最大值為 28-1,即 255;TINYINT 有符號數的最大值為 27-1,即 127。其他類型的整數的取值范圍計算方法相同,
如下表所示。

類型名稱 說明 存儲需求
TINYINT -128〜127 0 〜255
SMALLINT -32768〜32767 0〜65535
MEDIUMINT -8388608〜8388607 0〜16777215
INT (INTEGER) -2147483648〜2147483647 0〜4294967295
BIGINT -9223372036854775808〜9223372036854775807 0〜18446744073709551615
  • 測試int數據類型
#用utf8mb4創建world庫
mysql> CREATE DATABASE world CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
Query OK, 1 row affected (0.00 sec)

#建表;
mysql> use world;
Database changed

mysql> CREATE TABLE  t2(id int);
Query OK, 0 rows affected (0.17 sec)

#查看建表語句
mysql> show create table t2;
+-------+-----------------------------------------------------------------------------------------+
| Table | Create Table                                                                            |
+-------+-----------------------------------------------------------------------------------------+
| t2    | CREATE TABLE `t2` (
  `id` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
+-------+-----------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

#查看表結構
mysql> desc t2;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)

#插入數據
mysql> insert t2 values('-2147483647');
Query OK, 1 row affected (0.00 sec)

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

#插入的數據超出int類型范圍
mysql> insert t2 values('-2147483649');
ERROR 1264 (22003): Out of range value for column 'id' at row 1

#插入的數據超出int類型長度
mysql> insert t2 values('12321232112');
ERROR 1264 (22003): Out of range value for column 'id' at row 1

2.MySQL小數類型

MySQL 中使用浮點數和定點數來表示小數。

浮點類型有兩種,分別是單精度浮點數(FLOAT)和雙精度浮點數(DOUBLE);定點類型只有一種,就是 DECIMAL。

浮點類型和定點類型都可以用(M, D)來表示,其中M稱為精度,表示總共的位數;D稱為標度,表示小數的位數。

浮點數類型的取值范圍為 M(1~255)和 D(1~30,且不能大於 M-2),分別表示顯示寬度和小數位數。M 和 D 在 FLOAT 和DOUBLE 中是可選的,FLOAT 和 DOUBLE 類型將被保存為硬件所支持的最大精度。DECIMAL 的默認 D 值為 0、M 值為 10。

下表中列出了 MySQL 中的小數類型和存儲需求。

類型名稱 說明 存儲需求
FLOAT 單精度浮點數 4 個字節
DOUBLE 雙精度浮點數 8 個字節
DECIMAL (M, D) 壓縮的“嚴格”定點數 M+2 個字節

DECIMAL 類型不同於 FLOAT 和 DOUBLE。DOUBLE 實際上是以字符串的形式存放的,DECIMAL 可能的最大取值范圍與 DOUBLE 相同,但是有效的取值范圍由 M 和 D 決定。如果改變 M 而固定 D,則取值范圍將隨 M 的變大而變大。

從上表中可以看到,DECIMAL 的存儲空間並不是固定的,而由精度值 M 決定,占用 M+2 個字節。

FLOAT 類型的取值范圍如下:

  • 有符號的取值范圍:-3.402823466E+38~-1.175494351E-38。
  • 無符號的取值范圍:0 和 -1.175494351E-38~-3.402823466E+38。

DOUBLE 類型的取值范圍如下:

  • 有符號的取值范圍:-1.7976931348623157E+308~-2.2250738585072014E-308。
  • 無符號的取值范圍:0 和 -2.2250738585072014E-308~-1.7976931348623157E+308。

3.MySQL字符串類型

字符串類型用來存儲字符串數據,還可以存儲圖片和聲音的二進制數據。字符串可以區分或者不區分大小寫的串比較,還可以進行正則表達式的匹配查找。

MySQL 中的字符串類型有 CHAR、VARCHAR、TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT、ENUM、SET 等。

下表中列出了 MySQL 中的字符串數據類型,括號中的M表示可以為其指定長度。

類型名稱 說明 存儲需求
CHAR(M) 固定長度非二進制字符串 M 字節,1<=M<=255
VARCHAR(M) 變長非二進制字符串 L+1字節,在此,L< = M和 1<=M<=255
TINYTEXT 非常小的非二進制字符串 L+1字節,在此,L<2^8
TEXT 小的非二進制字符串 L+2字節,在此,L<2^16
MEDIUMTEXT 中等大小的非二進制字符串 L+3字節,在此,L<2^24
LONGTEXT 大的非二進制字符串 L+4字節,在此,L<2^32
ENUM 枚舉類型,只能有一個枚舉字符串值 1或2個字節,取決於枚舉值的數目 (最大值為65535)

VARCHAR 和 TEXT 類型是變長類型,其存儲需求取決於列值的實際長度(在前面的表格中用 L 表示),而不是取決於類型的最大可能尺寸。

例如,一個 VARCHAR(10) 列能保存一個最大長度為 10 個字符的字符串,實際的存儲需要字符串的長度 L 加上一個字節以記錄字符串的長度。對於字符 “abcd”,L 是 4,而存儲要求 5 個字節。

  • 測試char和varchar類型
#建表
mysql> CREATE TABLE t1(id int,name varchar(12));
Query OK, 0 rows affected (0.01 sec)

#插入數據
mysql> INSERT INTO t1 values('1','張三');
Query OK, 1 row affected (0.00 sec)

#字符超過數據類型的限制值
mysql> INSERT INTO t1 values('2','zhangsanlinsi');
ERROR 1406 (22001): Data too long for column 'name' at row 1

  • 測試enum類型
#建表
mysql> CREATE TABLE t3(id int,name varchar(10),sex enum('man','girl'));
Query OK, 0 rows affected (0.32 sec)

#插入數據
mysql> INSERT INTO t3 values('1','張三','man');
Query OK, 1 row affected (0.00 sec)

#枚舉類型,只能插入指定的值,不能插入額外的值
mysql> INSERT INTO t3 values('1','李四','nan');
ERROR 1265 (01000): Data truncated for column 'sex' at row 1

  • 建表測試
#建學生表
mysql> CREATE TABLE student(id int,name varchar(10),sex enum('男','女'),age tinyint,cometime datetime);
Query OK, 0 rows affected (0.01 sec)

#插入數據
mysql> INSERT INTO student values('1','張三','男','19',now());
Query OK, 1 row affected (0.01 sec)

#查看
mysql> select * from student;
+------+--------+------+------+---------------------+
| id   | name   | sex  | age  | cometime            |
+------+--------+------+------+---------------------+
|    1 | 張三   | 男   |   19 | 2021-09-28 11:13:11 |
+------+--------+------+------+---------------------+
1 row in set (0.00 sec)

4.建表的數據屬性

not null: 			非空
primary key: 		主鍵(唯一且非空的)
auto_increment: 	自增(此列必須是:primary key或者unique key)
unique key: 		唯一鍵(單獨的唯一的)
default: 			默認值
unsigned: 			非負數
comment:			注釋

  • 案例
#建表
mysql> CREATE TABLE student(
    -> id int unsigned primary key auto_increment comment '學生id',
    -> name varchar(10) not null comment '學會姓名',
    -> sex enum('男','女') default '男' comment '性別',
    -> age tinyint unsigned comment '年齡',
    -> cometime datetime default now() comment '入學時間',
    -> class varchar(12) not null comment '班級',
    -> status enum('0','1') default 1 comment '狀態');
Query OK, 0 rows affected (0.39 sec)

#查看建表語句
mysql> show create table student;      
| student | CREATE TABLE `student` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '學生id',
  `name` varchar(10) NOT NULL COMMENT '學會姓名',
  `sex` enum('男','女') DEFAULT '男' COMMENT '性別',
  `age` tinyint(3) unsigned DEFAULT NULL COMMENT '年齡',
  `cometime` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '入學時間',
  `class` varchar(12) NOT NULL COMMENT '班級',
  `status` enum('0','1') DEFAULT '0' COMMENT '狀態',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4                      |

1 row in set (0.00 sec)

#插入數據
mysql> INSERT INTO student(name,class) values('張三','高二3班');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO student(name,class) values('李四','高二3班');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO student(name,class) values('林五','高二3班');
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO student(name,sex,age,class) values('楊雪','女','16','高二3班');
Query OK, 1 row affected (0.01 sec)

#查看數據
mysql> select * from student;
+----+--------+------+------+---------------------+------------+--------+
| id | name   | sex  | age  | cometime            | class      | status |
+----+--------+------+------+---------------------+------------+--------+
|  1 | 張三   | 男   | NULL | 2021-09-28 11:26:42 | 高二3班    | 0      |
|  2 | 李四   | 男   | NULL | 2021-09-28 11:27:33 | 高二3班    | 0      |
|  3 | 林五   | 男   | NULL | 2021-09-28 11:28:11 | 高二3班    | 0      |
|  4 | 楊雪   | 女   |   16 | 2021-09-28 11:32:25 | 高二3班    | 0      |
+----+--------+------+------+---------------------+------------+--------+
4 rows in set (0.00 sec)

5.MySQL日期和時間

MySQL 中有多處表示日期的數據類型:YEAR、TIME、DATE、DTAETIME、TIMESTAMP。當只記錄年信息的時候,可以只使用 YEAR 類型。

每一個類型都有合法的取值范圍,當指定確定不合法的值時,系統將“零”值插入數據庫中。

下表中列出了 MySQL 中的日期與時間類型。

類型名稱 日期格式 日期范圍 存儲需求
YEAR YYYY 1901 ~ 2155 1 個字節
TIME HH:MM:SS -838:59:59 ~ 838:59:59 3 個字節
DATE YYYY-MM-DD 1000-01-01 ~ 9999-12-3 3 個字節
DATETIME YYYY-MM-DD HH:MM:SS 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 8 個字節
TIMESTAMP YYYY-MM-DD HH:MM:SS 1980-01-01 00:00:01 UTC ~ 2040-01-19 03:14:07 UTC 4 個字節
  • 案例
mysql> create table d1(id int,name char, date1 date, date2 time, date3 datetime, date4 timestamp,date5 year);
Query OK, 0 rows affected (0.12 sec)

mysql> insert into d1 values (1, '1', '2021-09-09','12:12:12','2021-09-09','2021-09-09','2021');
Query OK, 1 row affected (0.00 sec)

mysql> select * from d1;
+------+------+------------+----------+---------------------+---------------------+-------+
| id   | name | date1      | date2    | date3               | date4               | date5 |
+------+------+------------+----------+---------------------+---------------------+-------+
|    1 | 1    | 2021-09-09 | 12:12:12 | 2021-09-09 00:00:00 | 2021-09-09 00:00:00 |  2021 |
+------+------+------------+----------+---------------------+---------------------+-------+
1 row in set (0.00 sec)


datetime 和 timestamp 之間的區別?
  
  1、兩者的存儲方式不一樣
    對於TIMESTAMP,它把客戶端插入的時間從當前時區轉化為UTC(世界標准時間)進行存儲。查詢時,將其又轉化為客戶端當前時區進行返回。
    對於DATETIME,不做任何改變,基本上是原樣輸入和輸出。
    
  2、兩者所能存儲的時間范圍不一樣
    timestamp所能存儲的時間范圍為:‘1970-01-01 00:00:01.000000’ 到 ‘2038-01-19 03:14:07.999999’。
    datetime所能存儲的時間范圍為:‘1000-01-01 00:00:00.000000’ 到 ‘9999-12-31 23:59:59.999999’。
    
    mysql> insert into t1 values (1, '1', '2021-09-09','12:12:12','2221-09-09 12','2221-09-09','2021');
    1292 - Incorrect datetime value: '2221-09-09' for column 'date4' at row 1
    

6.MySQL二進制類型

MySQL 中的二進制字符串有 BIT、BINARY、VARBINARY、TINYBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB。

下表中列出了 MySQL 中的二進制數據類型,括號中的M表示可以為其指定長度。

類型名稱 說明 存儲需求
BIT(M) 位字段類型 大約 (M+7)/8 字節
BINARY(M) 固定長度二進制字符串 M 字節
VARBINARY (M) 可變長度二進制字符串 M+1 字節
TINYBLOB (M) 非常小的BLOB L+1 字節,在此,L<2^8
BLOB (M) 小 BLOB L+2 字節,在此,L<2^16
MEDIUMBLOB (M) 中等大小的BLOB L+3 字節,在此,L<2^24
LONGBLOB (M) 非常大的BLOB L+4 字節,在此,L<2^32
  • 案例
import pymysql

class BlobDataTestor:
    def __init__(self):
        self.conn = pymysql.connect(host='127.0.0.1', user='root', passwd='123456', db='db1', port=3306)

    def __del__(self):
        try:
            self.conn.close()
        except:
            pass

    def closedb(self):
        self.conn.close()

    def setup(self):
        cursor = self.conn.cursor()
        cursor.execute("""  
             CREATE TABLE IF NOT EXISTS `Dem_Picture` (  
             `ID` int(11) NOT NULL auto_increment,  
             `PicData` mediumblob,  
             PRIMARY KEY (`ID`)  
             ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;  
             """)


    def testRWBlobData(self):
        # 讀取源圖片數據
        f = open("D:\\1.jpg", "rb")
        b = f.read()
        f.close()

        # 將圖片數據寫入表
        cursor = self.conn.cursor()
        cursor.execute("INSERT INTO Dem_Picture (PicData) VALUES (%s)", (pymysql.Binary(b)))
        # self.conn.commit()

        # 讀取表內圖片數據,並寫入硬盤文件
        cursor.execute("SELECT PicData FROM Dem_Picture ORDER BY ID DESC limit 1")
        d = cursor.fetchone()[0]
        cursor.close()

        f = open("D:\\1.jpg", "wb")
        f.write(d)
        f.close()


# 下面一句的作用是:運行本程序文件時執行什么操作  
if __name__ == "__main__":

    test = BlobDataTestor()

    try:
        test.setup()
        test.testRWBlobData()
        # test.teardown()
    finally:
        test.closedb()

7.MySQL系統變量

在 MySQL 數據庫,變量分為系統變量和用戶自定義變量。系統變量以 @@ 開頭,用戶自定義變量以 @ 開頭。
服務器維護着兩種系統變量,即全局變量(GLOBAL VARIABLES)和會話變量(SESSION VARIABLES)。全局變量影響 MySQL 服務的整體運行方式,會話變量影響具體客戶端連接的操作。
每一個客戶端成功連接服務器后,都會產生與之對應的會話。會話期間,MySQL 服務實例會在服務器內存中生成與該會話對應的會話變量,這些會話變量的初始值是全局變量值的拷貝。

查看系統變量

#查看MySQL中所有的全局變量信息
mysql> SHOW GLOBAL VARIABLES; 

#查看與當前會話相關的所有會話變量以及全局變量。 其中SESSION關鍵字可以省略
mysql> SHOW SESSION VARIABLES;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM