一、數值類型
1. 整數類型
類型 | 字節 | 有符號范圍 | 無符號范圍 | 操作注意事項 |
---|---|---|---|---|
TINYINT | 1 | -128 ~ 127 | 0 ~ 255 | 默認有符號,UNSIGNED 定義無符號 |
SMALLINT | 2 | -32768 ~ 32767 | 0 ~ 65535 | 無符號需顯式聲明 |
INT | 4 | -2^31 ~ 2^31-1 | 0 ~ 2^32-1 | 推薦優先使用INT |
BIGINT | 8 | -2^63 ~ 2^63-1 | 0 ~ 2^64-1 | 存儲超長整數時使用 |
示例:
CREATE TABLE tt2(num TINYINT UNSIGNED); -- 無符號TINYINT
INSERT INTO tt2 VALUES(255); -- 有效
INSERT INTO tt2 VALUES(-1); -- 報錯:越界
2. 小數類型
類型 | 特點 | 語法示例 | 精度對比 |
---|---|---|---|
FLOAT | 單精度,約7位有效數字 | FLOAT(M, D) | 快速計算但精度低 |
DOUBLE | 雙精度,約15位有效數字 | DOUBLE(M, D) | 精度高于FLOAT |
DECIMAL | 精確小數,高精度計算 | DECIMAL(M, D) | 精確存儲(如金額) |
示例:
CREATE TABLE tt8 (salary FLOAT(10,8), salary2 DECIMAL(10,8));
INSERT INTO tt8 VALUES(23.12345612, 23.12345612);
SELECT * FROM tt8;
-- 結果:FLOAT顯示23.12345695,DECIMAL顯示23.12345612(精度更高)
3. BIT類型
- 語法:
BIT(M)
,M范圍1~64,默認1。 - 顯示規則:按ASCII碼顯示。
- 適用場景:存儲二進制標志(如性別0/1)。
示例:
CREATE TABLE tt5(gender BIT(1)); -- 存儲0或1
INSERT INTO tt5 VALUES(0), (1); -- 有效
INSERT INTO tt5 VALUES(2); -- 報錯:越界
二、字符串類型
1. CHAR與VARCHAR對比
類型 | 特點 | 最大長度 | 存儲方式 | 適用場景 |
---|---|---|---|---|
CHAR | 定長,固定占用空間 | 255字符 | 預先分配空間 | 身份證、MD5值 |
VARCHAR | 變長,按需分配空間 | 65535字節 | 動態分配空間 | 姓名、地址 |
示例:
CREATE TABLE tt10(name VARCHAR(6) CHARSET=utf8); -- UTF8下最大21844字符
INSERT INTO tt10 VALUES('我愛你,中國'); -- 6個字符(UTF8每個漢字3字節)
2. BLOB與TEXT
- BLOB:存儲二進制數據(如圖片、文件)。
- TEXT:存儲大文本,不支持全文索引和默認值。
三、時間日期類型
類型 | 格式 | 范圍 | 占用空間 | 特點 |
---|---|---|---|---|
DATE | YYYY-MM-DD | 1000-01-01 ~ 9999-12-31 | 3字節 | 僅日期 |
DATETIME | YYYY-MM-DD HH:MM:SS | 1000-01-01 ~ 9999-12-31 | 8字節 | 日期+時間 |
TIMESTAMP | YYYY-MM-DD HH:MM:SS | 1970-01-01 ~ 2038-01-19 | 4字節 | 自動更新為當前時間 |
示例:
CREATE TABLE birthday (t1 DATE, t2 DATETIME, t3 TIMESTAMP);
INSERT INTO birthday(t1,t2) VALUES('2000-01-01', '2023-10-01 12:00:00');
UPDATE birthday SET t1='2005-05-05'; -- t3自動更新為當前時間
四、ENUM與SET類型
1. ENUM(單選)
- 語法:
ENUM('選項1', '選項2', ...)
,存儲對應數字(1,2,…)。 - 示例:
CREATE TABLE votes(gender ENUM('男','女')); INSERT INTO votes VALUES('男'), (2); -- 2對應'女'
2. SET(多選)
- 語法:
SET('選項1', '選項2', ...)
,存儲對應數字(1,2,4,8,…)。 - 查詢:使用
FIND_IN_SET
函數。CREATE TABLE votes(hobby SET('登山','游泳','籃球')); INSERT INTO votes VALUES('登山,游泳'); SELECT * FROM votes WHERE FIND_IN_SET('登山', hobby); -- 查詢包含"登山"的記錄
五、關鍵注意事項
- 數值類型選擇:
- 優先使用
DECIMAL
存儲精確小數(如金額)。 - 避免使用
UNSIGNED
,直接升級類型(如INT
→BIGINT
)更安全。
- 優先使用
- 字符串類型優化:
CHAR
適合定長數據(如手機號),VARCHAR
適合變長數據(如地址)。
- 時間類型自動更新:
TIMESTAMP
字段在數據更新時會自動刷新為當前時間。
- ENUM/SET查詢技巧:
- 避免直接使用數字插入,優先用可讀字符串。
一、約束類型概覽
約束類型 | 作用 | 關鍵字 | 特點 |
---|---|---|---|
空屬性約束 | 控制字段是否允許為NULL | NOT NULL | 強制字段必須有值 |
默認值約束 | 指定字段的默認值 | DEFAULT | 插入數據時可選使用默認值 |
列描述約束 | 為字段添加注釋 | COMMENT | 僅描述作用,不影響數據 |
零填充約束 | 數字顯示時自動填充前導零 | ZEROFILL | 僅影響顯示,不改變存儲值 |
主鍵約束 | 唯一標識表中的記錄 | PRIMARY KEY | 唯一、非空,一張表只能有一個 |
自增長約束 | 自動生成遞增的整數值 | AUTO_INCREMENT | 需與主鍵/唯一鍵搭配使用 |
唯一鍵約束 | 確保字段值唯一(允許NULL) | UNIQUE KEY | 可多個,NULL不參與唯一性檢查 |
外鍵約束 | 強制關聯主表的主鍵或唯一鍵 | FOREIGN KEY | 維護表間數據一致性 |
二、核心約束詳解
1. 空屬性約束(NOT NULL)
- 語法:
CREATE TABLE 表名 (字段名 數據類型 NOT NULL);
- 示例:
CREATE TABLE myclass (class_name VARCHAR(20) NOT NULL,class_room VARCHAR(10) NOT NULL );
- 操作細節:
- 插入數據時,若未給
NOT NULL
字段賦值,會報錯:ERROR 1364 (HY000): Field 'class_room' doesn't have a default value
- 插入數據時,若未給
2. 默認值約束(DEFAULT)
- 語法:
CREATE TABLE 表名 (字段名 數據類型 DEFAULT 默認值);
- 示例:
CREATE TABLE tt10 (name VARCHAR(20) NOT NULL,age TINYINT UNSIGNED DEFAULT 0,sex CHAR(2) DEFAULT '男' );
- 操作細節:
- 插入時省略字段,自動填充默認值:
INSERT INTO tt10(name) VALUES('張三'); -- age=0, sex='男'
- 插入時省略字段,自動填充默認值:
3. 列描述約束(COMMENT)
- 語法:
CREATE TABLE 表名 (字段名 數據類型 COMMENT '注釋內容');
- 查看注釋:
SHOW CREATE TABLE 表名\G
4. 零填充約束(ZEROFILL)
- 語法:
CREATE TABLE 表名 (字段名 INT(顯示長度) ZEROFILL);
- 示例:
ALTER TABLE tt3 CHANGE a a INT(5) UNSIGNED ZEROFILL;
- 效果:
- 存儲值
1
→ 顯示為00001
,實際存儲仍為1
。
- 存儲值
5. 主鍵約束(PRIMARY KEY)
- 語法:
-- 單字段主鍵 CREATE TABLE 表名 (字段名 數據類型 PRIMARY KEY);-- 復合主鍵 CREATE TABLE 表名 (字段1 數據類型, 字段2 數據類型, PRIMARY KEY(字段1, 字段2));
- 示例:
CREATE TABLE tt14 (id INT UNSIGNED,course CHAR(10),PRIMARY KEY(id, course) -- 復合主鍵 );
- 操作細節:
- 插入重復主鍵報錯:
ERROR 1062 (23000): Duplicate entry '1-123' for key 'PRIMARY'
- 刪除主鍵:
ALTER TABLE 表名 DROP PRIMARY KEY;
- 插入重復主鍵報錯:
6. 自增長約束(AUTO_INCREMENT)
- 語法:
CREATE TABLE 表名 (字段名 INT PRIMARY KEY AUTO_INCREMENT);
- 示例:
CREATE TABLE tt21 (id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,name VARCHAR(10) NOT NULL DEFAULT '' );
- 操作細節:
- 插入時省略自增長字段,自動生成遞增值:
INSERT INTO tt21(name) VALUES('a'); -- id=1 INSERT INTO tt21(name) VALUES('b'); -- id=2
- 獲取最后插入的ID:
SELECT LAST_INSERT_ID();
- 插入時省略自增長字段,自動生成遞增值:
7. 唯一鍵約束(UNIQUE KEY)
- 語法:
CREATE TABLE 表名 (字段名 數據類型 UNIQUE KEY);
- 示例:
CREATE TABLE student (id CHAR(10) UNIQUE COMMENT '學號',name VARCHAR(10) );
- 操作細節:
- 允許插入多個
NULL
值,但非NULL
值必須唯一:INSERT INTO student VALUES(NULL, '張三'); -- 允許 INSERT INTO student VALUES('001', '李四'); -- 重復則報錯
- 允許插入多個
8. 外鍵約束(FOREIGN KEY)
- 語法:
CREATE TABLE 從表名 (字段名 數據類型,FOREIGN KEY (從表字段) REFERENCES 主表名(主表字段) );
- 示例:
-- 主表 CREATE TABLE myclass (id INT PRIMARY KEY, name VARCHAR(30) NOT NULL);-- 從表 CREATE TABLE stu (id INT PRIMARY KEY,class_id INT,FOREIGN KEY (class_id) REFERENCES myclass(id) );
- 操作細節:
- 插入無效外鍵值報錯:
ERROR 1452 (23000): Cannot add or update a child row
- 允許外鍵為NULL:
INSERT INTO stu VALUES(102, NULL); -- 允許未分配班級
- 插入無效外鍵值報錯:
三、綜合案例解析
場景:設計商店數據庫(商品、客戶、購買表)
-- 商品表
CREATE TABLE goods (goods_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '商品編號',goods_name VARCHAR(32) NOT NULL COMMENT '商品名稱',unitprice INT NOT NULL DEFAULT 0 COMMENT '單價(分)',category VARCHAR(12) COMMENT '分類',provider VARCHAR(64) NOT NULL COMMENT '供應商'
);-- 客戶表
CREATE TABLE customer (customer_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '客戶編號',name VARCHAR(32) NOT NULL COMMENT '姓名',email VARCHAR(64) UNIQUE KEY COMMENT '郵箱',sex ENUM('男','女') NOT NULL COMMENT '性別',card_id CHAR(18) UNIQUE KEY COMMENT '身份證'
);-- 購買表(外鍵關聯)
CREATE TABLE purchase (order_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '訂單號',customer_id INT COMMENT '客戶編號',goods_id INT COMMENT '商品編號',nums INT DEFAULT 0 COMMENT '購買數量',FOREIGN KEY (customer_id) REFERENCES customer(customer_id),FOREIGN KEY (goods_id) REFERENCES goods(goods_id)
);
四、關鍵注意事項
- 主鍵與業務無關:推薦使用自增ID,避免業務調整影響主鍵。
- 外鍵性能:外鍵約束可能影響插入/更新性能,高頻寫入場景需謹慎使用。
- 唯一鍵與NULL:唯一鍵允許NULL,但多個NULL不視為重復。
- 自增長字段:僅支持整數類型,且一張表只能有一個自增長字段。
MySQL基本查詢操作
1. Create(增)
- 語法:
INSERT INTO 表名 [(列名,...)] VALUES (值列表)[, (值列表)...];
- 操作細節:
- 全列插入:值與表結構列順序一致,可省略列名。
INSERT INTO students VALUES (100, 10000, '唐三藏', NULL);
- 指定列插入:插入部分列,未指定列使用默認值或NULL。
INSERT INTO students (id, sn, name) VALUES (102, 20001, '曹孟德');
- 沖突處理:
- 更新重復鍵:
ON DUPLICATE KEY UPDATE
INSERT INTO students (id, sn, name) VALUES (100, 10010, '唐大師') ON DUPLICATE KEY UPDATE sn = 10010, name = '唐大師';
- 替換重復鍵:
REPLACE
(刪除舊記錄后插入新記錄)。REPLACE INTO students (sn, name) VALUES (20001, '曹阿晴');
- 更新重復鍵:
- 全列插入:值與表結構列順序一致,可省略列名。
2. Retrieve(查)
- 語法:
SELECT [DISTINCT] 列名 FROM 表名 [WHERE ...] [ORDER BY ...] [LIMIT ...];
- 操作細節:
-
基礎查詢:
- 全列查詢(不推薦):
SELECT * FROM exam_result;
- 指定列查詢:
SELECT id, name FROM exam_result;
- 表達式查詢:
SELECT name, math + 10 AS math_plus FROM exam_result;
- 別名:
SELECT name, chinese + math + english 總分 FROM exam_result;
- 去重:
SELECT DISTINCT math FROM exam_result;
- 全列查詢(不推薦):
-
條件過濾(WHERE):
- 比較運算符:
>
,=
,<=>
,BETWEEN
,IN
,LIKE
(%
匹配任意字符,_
匹配單個字符)。 - 邏輯運算符:
AND
,OR
,NOT
。 - 案例:
-- 英語不及格 SELECT name, english FROM exam_result WHERE english < 60; -- 姓孫的同學 SELECT name FROM exam_result WHERE name LIKE '孫%'; -- 總分 < 200(WHERE中不能使用別名) SELECT name, chinese + math + english 總分 FROM exam_result WHERE chinese + math + english < 200;
- 比較運算符:
-
排序(ORDER BY):
- 默認升序(ASC),降序用DESC。
- 多字段排序:按書寫順序優先級。
SELECT name, math, english FROM exam_result ORDER BY math DESC, english;
-
分頁(LIMIT):
- 語法:
LIMIT n OFFSET s
(從s開始取n條,s起始為0)。-- 第2頁(每頁3條) SELECT * FROM exam_result ORDER BY id LIMIT 3 OFFSET 3;
- 語法:
-
3. Update(改)
- 語法:
UPDATE 表名 SET 列名=值 [WHERE ...] [ORDER BY ...] [LIMIT ...];
- 操作細節:
- 單列更新:
UPDATE exam_result SET math = 80 WHERE name = '孫悟空';
- 多列更新:
UPDATE exam_result SET math = 60, chinese = 70 WHERE name = '曹孟德';
- 表達式更新:
-- 總分倒數前三的數學加30分 UPDATE exam_result SET math = math + 30 ORDER BY chinese + math + english LIMIT 3;
- 慎用全表更新:無WHERE條件時更新全表。
- 單列更新:
4. Delete(刪)
- 語法:
DELETE FROM 表名 [WHERE ...] [ORDER BY ...] [LIMIT ...];
- 操作細節:
- 刪除指定數據:
DELETE FROM exam_result WHERE name = '孫悟空';
- 清空表:
DELETE FROM 表名
:逐行刪除,自增值保留。TRUNCATE 表名
:快速清空,重置自增值,不可回滾。
- 刪除指定數據:
5. 高級操作
-
聚合函數:
COUNT
,SUM
,AVG
,MAX
,MIN
,支持DISTINCT
。-- 統計數學成績種類數 SELECT COUNT(DISTINCT math) FROM exam_result; -- 計算平均總分 SELECT AVG(chinese + math + english) 平均總分 FROM exam_result;
-
GROUP BY 分組:
- 按部門統計平均工資:
SELECT deptno, AVG(sal) FROM EMP GROUP BY deptno;
HAVING
過濾分組:SELECT deptno, AVG(sal) FROM EMP GROUP BY deptno HAVING AVG(sal) < 2000;
- 按部門統計平均工資:
6. 注意事項
- 執行順序:
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT
。 - NULL處理:
= NULL
不安全,需用IS NULL
或<=>
。- 聚合函數忽略NULL(如
COUNT(qq)
僅統計非NULL值)。
- 性能提示:
- 避免全列查詢(
SELECT *
)。 - 分頁時建議用
LIMIT
防止全表掃描。
- 避免全列查詢(
7. 實戰技巧
- 去重插入:通過臨時表實現原子操作。
CREATE TABLE no_duplicate_table LIKE duplicate_table; INSERT INTO no_duplicate_table SELECT DISTINCT * FROM duplicate_table; RENAME TABLE duplicate_table TO old_table, no_duplicate_table TO duplicate_table;
- 分頁優化:按主鍵分頁,避免
OFFSET
過大時性能問題。