MySQL學習筆記:十、建立和管理表
1. 基礎知識
1.1 一條資料儲存的過程
儲存資料是處理資料的第一步
。只有正確地把資料儲存起來,我們才能進行有效的處理和分析。否則,只能是一團亂麻,無從下手。
那麼,怎樣才能把使用者各種經營相關的、紛繁複雜的資料,有序、高效地儲存起來呢? 在 MySQL 中,一個完整的資料儲存過程總共有 4 步,分別是建立資料庫、確認欄位、建立資料表、插入資料。
我們要先建立一個數據庫,而不是直接建立資料表呢?
因為從系統架構的層次上看,MySQL 資料庫系統從大到小依次是資料庫伺服器
、資料庫
、資料表
、資料表的行與列
。
MySQL 資料庫伺服器之前已經安裝。所以,我們就從建立資料庫開始。
1.2 識別符號命名規則
- 資料庫名、表名不得超過30個字元,變數名限制為29個
- 必須只能包含 A–Z, a–z, 0–9, _共63個字元
- 資料庫名、表名、欄位名等物件名中間不要包含空格
- 同一個MySQL軟體中,資料庫不能同名;同一個庫中,表不能重名;同一個表中,欄位不能重名
- 必須保證你的欄位沒有和保留字、資料庫系統或常用方法衝突。如果堅持使用,請在SQL語句中使用`(著重號)引起來
- 保持欄位名和型別的一致性:在命名欄位併為其指定資料型別的時候一定要保證一致性,假如資料型別在一個表裡是整數,那在另一個表裡可就別變成字元型了
1.3 MySQL中的資料型別
型別 | 型別舉例 |
---|---|
整數型別 | TINYINT、SMALLINT、MEDIUMINT、INT(或INTEGER) |
浮點型別 | FLOAT、DOUBLE |
定點數型別 | DECIMAL |
位型別 | BIT |
日期時間型別 | YEAR、TIME、DATE、DATETIME、TIMESTAMP |
文字字串型別 | CHAR、VARCHAR、TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT |
列舉型別 | ENUM |
集合型別 | SET |
二進位制字串型別 | BINARY、VARBINARY、TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB |
JSON型別 | JSON物件、JSON陣列 |
空間資料型別 | 單值:GEOMETRY、POINT、LINESTRING、POLYGON; |
集合:MULTIPOINT、MULTILINESTRING、MULTIPOLYGON、GEOMETRYCOLLECTION |
其中,常用的幾類型別介紹如下:
資料型別 | 描述 |
---|---|
INT | 從-231到231-1的整型資料。儲存大小為 4個位元組 |
CHAR(size) | 定長字元資料。若未指定,預設為1個字元,最大長度255 |
VARCHAR(size) | 可變長字元資料,根據字串實際長度儲存,必須指定長度 |
FLOAT(M,D) | 單精度,佔用4個位元組,M=整數位+小數位,D=小數位。 D<=M<=255,0<=D<=30,預設M+D<=6 |
DOUBLE(M,D) | 雙精度,佔用8個位元組,D<=M<=255,0<=D<=30,預設M+D<=15 |
DECIMAL(M,D) | 高精度小數,佔用M+2個位元組,D<=M<=65,0<=D<=30,最大取值範圍與DOUBLE相同。 |
DATE | 日期型資料,格式'YYYY-MM-DD' |
BLOB | 二進位制形式的長文字資料,最大可達4G |
TEXT | 長文字資料,最大可達4G |
2. 建立和管理資料庫
2.1 建立資料庫
-
方式1:建立資料庫
CREATE DATABASE 資料庫名;
-
方式2:建立資料庫並指定字符集
CREATE DATABASE 資料庫名 CHARACTER SET 字符集;
-
方式3:判斷資料庫是否已經存在,不存在則建立資料庫(
推薦
)CREATE DATABASE IF NOT EXISTS 資料庫名;
如果MySQL中已經存在相關的資料庫,則忽略建立語句,不再建立資料庫。
注意:DATABASE 不能改名。一些視覺化工具可以改名,它是建新庫,把所有表複製到新庫,再刪舊庫完成的。
2.2 使用資料庫
- 檢視當前所有的資料庫
SHOW DATABASES; #有一個S,代表多個數據庫
- 檢視當前正在使用的資料庫
```sql
SELECT DATABASE(); #使用的一個 mysql 中的全域性函式
-
檢視指定庫下所有的表
SHOW TABLES FROM 資料庫名;
-
檢視資料庫的建立資訊
SHOW CREATE DATABASE 資料庫名; 或者: SHOW CREATE DATABASE 資料庫名\G
-
使用/切換資料庫
USE 資料庫名;
注意:要操作表格和資料之前必須先說明是對哪個資料庫進行操作,否則就要對所有物件加上“資料庫名.”。
2.3 修改資料庫
-
更改資料庫字符集
ALTER DATABASE 資料庫名 CHARACTER SET 字符集; #比如:gbk、utf8等
2.4 刪除資料庫
-
方式1:刪除指定的資料庫
DROP DATABASE 資料庫名;
-
方式2:刪除指定的資料庫(
推薦
)DROP DATABASE IF EXISTS 資料庫名;
3. 建立表
3.1 建立方式1
-
必須具備:
- CREATE TABLE許可權
- 儲存空間
-
語法格式:
CREATE TABLE [IF NOT EXISTS] 表名( 欄位1, 資料型別 [約束條件] [預設值], 欄位2, 資料型別 [約束條件] [預設值], 欄位3, 資料型別 [約束條件] [預設值], …… [表約束條件] );
加上了IF NOT EXISTS關鍵字,則表示:如果當前資料庫中不存在要建立的資料表,則建立資料表;如果當前資料庫中已經存在要建立的資料表,則忽略建表語句,不再建立資料表。
-
必須指定:
- 表名
- 列名(或欄位名),資料型別,長度
-
可選指定:
- 約束條件
- 預設值
-
建立表舉例1:
-- 建立表 CREATE TABLE emp ( -- int型別 emp_id INT, -- 最多儲存20箇中英文字元 emp_name VARCHAR(20), -- 總位數不超過15位 salary DOUBLE, -- 日期型別 birthday DATE );
DESC emp;
MySQL在執行建表語句時,將id欄位的型別設定為int(11),這裡的11實際上是int型別指定的顯示寬度,預設的顯示寬度為11。也可以在建立資料表的時候指定資料的顯示寬度。
-
建立表舉例2:
CREATE TABLE dept( -- int型別,自增 deptno INT(2) AUTO_INCREMENT, dname VARCHAR(14), loc VARCHAR(13), -- 主鍵 PRIMARY KEY (deptno) );
DESCRIBE dept;
在MySQL 8.x版本中,不再推薦為INT型別指定顯示長度,並在未來的版本中可能去掉這樣的語法。
3.2 建立方式2
-
使用 AS subquery 選項,將建立表和插入資料結合起來
-
指定的列和子查詢中的列要一一對應
-
通過列名和預設值定義列
CREATE TABLE emp1 AS SELECT * FROM employees; CREATE TABLE emp2 AS SELECT * FROM employees WHERE 1=2; -- 建立的emp2是空表
CREATE TABLE dept80 AS SELECT employee_id, last_name, salary*12 ANNSAL, hire_date FROM employees WHERE department_id = 80;
DESCRIBE dept80;
3.3 檢視資料表結構
在MySQL中建立好資料表之後,可以檢視資料表的結構。MySQL支援使用DESCRIBE/DESC
語句檢視資料表結構,也支援使用SHOW CREATE TABLE
語句檢視資料表結構。
語法格式如下:
SHOW CREATE TABLE 表名\G
使用SHOW CREATE TABLE語句不僅可以查看錶建立時的詳細語句,還可以檢視儲存引擎和字元編碼。
4. 修改表
修改表指的是修改資料庫中已經存在的資料表的結構。
使用 ALTER TABLE 語句可以實現:
-
向已有的表中新增列
-
修改現有表中的列
-
刪除現有表中的列
-
重新命名現有表中的列
4.1 追加一個列
語法格式如下:
ALTER TABLE 表名 ADD 【COLUMN】 欄位名 欄位型別 【FIRST|AFTER 欄位名】;
舉例:
ALTER TABLE dept80
ADD job_id varchar(15);
4.2 修改一個列
-
可以修改列的資料型別,長度、預設值和位置
-
修改欄位資料型別、長度、預設值、位置的語法格式如下:
ALTER TABLE 表名 MODIFY 【COLUMN】 欄位名1 欄位型別 【DEFAULT 預設值】【FIRST|AFTER 欄位名2】;
-
舉例:
ALTER TABLE dept80 MODIFY last_name VARCHAR(30);
ALTER TABLE dept80 MODIFY salary double(9,2) default 1000;
-
對預設值的修改隻影響今後對錶的修改
-
此外,還可以通過此種方式修改列的約束。這裡暫先不講。
4.3 重新命名一個列
使用 CHANGE old_column new_column dataType子句重新命名列。語法格式如下:
ALTER TABLE 表名 CHANGE 【column】 列名 新列名 新資料型別;
舉例:
ALTER TABLE dept80
CHANGE department_name dept_name varchar(15);
4.4 刪除一個列
刪除表中某個欄位的語法格式如下:
ALTER TABLE 表名 DROP 【COLUMN】欄位名
舉例:
ALTER TABLE dept80
DROP COLUMN job_id;
5. 重命名錶
-
方式一:使用RENAME
RENAME TABLE emp TO myemp;
-
方式二:
ALTER table dept RENAME [TO] detail_dept; -- [TO]可以省略
-
必須是物件的擁有者
6. 刪除表
-
在MySQL中,當一張資料表
沒有與其他任何資料表形成關聯關係
時,可以將當前資料表直接刪除。 -
資料和結構都被刪除
-
所有正在執行的相關事務被提交
-
所有相關索引被刪除
-
語法格式:
DROP TABLE [IF EXISTS] 資料表1 [, 資料表2, …, 資料表n];
IF EXISTS
的含義為:如果當前資料庫中存在相應的資料表,則刪除資料表;如果當前資料庫中不存在相應的資料表,則忽略刪除語句,不再執行刪除資料表的操作。
-
舉例:
DROP TABLE dept80;
-
DROP TABLE 語句不能回滾
7. 清空表
-
TRUNCATE TABLE語句:
- 刪除表中所有的資料
- 釋放表的儲存空間
-
舉例:
TRUNCATE TABLE detail_dept;
-
TRUNCATE語句不能回滾,而使用 DELETE 語句刪除資料,可以回滾
-
對比:
SET autocommit = FALSE; DELETE FROM emp2; #TRUNCATE TABLE emp2; SELECT * FROM emp2; ROLLBACK; SELECT * FROM emp2;
阿里開發規範:
【參考】TRUNCATE TABLE 比 DELETE 速度快,且使用的系統和事務日誌資源少,但 TRUNCATE 無事務且不觸發 TRIGGER,有可能造成事故,故不建議在開發程式碼中使用此語句。
說明:TRUNCATE TABLE 在功能上與不帶 WHERE 子句的 DELETE 語句相同。
8. 內容拓展
拓展1:阿里巴巴《Java開發手冊》之MySQL欄位命名
-
【
強制
】表名、欄位名必須使用小寫字母或數字,禁止出現數字開頭,禁止兩個下劃線中間只出現數字。資料庫欄位名的修改代價很大,因為無法進行預釋出,所以欄位名稱需要慎重考慮。- 正例:aliyun_admin,rdc_config,level3_name
- 反例:AliyunAdmin,rdcConfig,level_3_name
-
【
強制
】禁用保留字,如 desc、range、match、delayed 等,請參考 MySQL 官方保留字。 -
【
強制
】表必備三欄位:id, gmt_create, gmt_modified。- 說明:其中 id 必為主鍵,型別為BIGINT UNSIGNED、單表時自增、步長為 1。gmt_create, gmt_modified 的型別均為 DATETIME 型別,前者現在時表示主動式建立,後者過去分詞表示被動式更新
-
【
推薦
】表的命名最好是遵循 “業務名稱_表的作用”。- 正例:alipay_task 、 force_project、 trade_config
-
【
推薦
】庫名與應用名稱儘量一致。 -
【參考】合適的字元儲存長度,不但節約資料庫表空間、節約索引儲存,更重要的是提升檢索速度。
拓展2:如何理解清空表、刪除表等操作需謹慎?!
表刪除
操作將把表的定義和表中的資料一起刪除,並且MySQL在執行刪除操作時,不會有任何的確認資訊提示,因此執行刪除操時應當慎重。在刪除表前,最好對錶中的資料進行備份
,這樣當操作失誤時可以對資料進行恢復,以免造成無法挽回的後果。
同樣的,在使用 ALTER TABLE
進行表的基本修改操作時,在執行操作過程之前,也應該確保對資料進行完整的備份
,因為資料庫的改變是無法撤銷
的,如果添加了一個不需要的欄位,可以將其刪除;相同的,如果刪除了一個需要的列,該列下面的所有資料都將會丟失。
拓展3:MySQL8新特性—DDL的原子化
在MySQL 8.0版本中,InnoDB表的DDL支援事務完整性,即DDL操作要麼成功要麼回滾
。DDL操作回滾日誌寫入到data dictionary資料字典表mysql.innodb_ddl_log(該表是隱藏的表,通過show tables無法看到)中,用於回滾操作。通過設定引數,可將DDL操作日誌列印輸出到MySQL錯誤日誌中。
分別在MySQL 5.7版本和MySQL 8.0版本中建立資料庫和資料表,結果如下:
CREATE DATABASE mytest;
USE mytest;
CREATE TABLE book1(
book_id INT ,
book_name VARCHAR(255)
);
SHOW TABLES;
(1)在MySQL 5.7版本中,測試步驟如下:
刪除資料表book1和資料表book2,結果如下:
mysql> DROP TABLE book1,book2;
ERROR 1051 (42S02): Unknown table 'mytest.book2'
再次查詢資料庫中的資料表名稱,結果如下:
mysql> SHOW TABLES;
Empty set (0.00 sec)
從結果可以看出,雖然刪除操作時報錯了,但是仍然刪除了資料表book1。
(2)在MySQL 8.0版本中,測試步驟如下:
刪除資料表book1和資料表book2,結果如下:
mysql> DROP TABLE book1,book2;
ERROR 1051 (42S02): Unknown table 'mytest.book2'
再次查詢資料庫中的資料表名稱,結果如下:
mysql> show tables;
+------------------+
| Tables_in_mytest |
+------------------+
| book1 |
+------------------+
1 row in set (0.00 sec)
從結果可以看出,資料表book1並沒有被刪除。