1. 程式人生 > 其它 >MySQL學習筆記:十、建立和管理表

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)
、BIGINT
浮點型別 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並沒有被刪除。