MySQL基礎知識(二)——資料表和約束
一.資料表
1.概述
資料表(或稱表)是資料庫最重要的組成部分之一,是其他物件的基礎。
2.使用資料庫
建立資料表之前要開啟資料庫,並使用資料庫(命令:USE database_name;)
可以使用命令:SELECT DATABASE(); 展示當前使用的資料庫。
3.建立資料表
語法:CREATE TABLE [IF NOT EXISTS] table_name (column_name data_type,...)
# 建立一個簡單的使用者表 CREATE TABLE IF NOT EXISTS user( username VARCHAR(20), age TINYINT UNSIGNED );
4.檢視資料表列表
SHOW TABLES [FROM db_name][LIKE 'pattern' | WHERE expr]
# 檢視當前資料庫下的表
SHOW TABLES;
# 檢視mysql資料庫下的表,不會切換使用的庫
SHOW TABLES FROM mysql;
5.檢視資料表結構
- SHOW COLUMNS FROM tbl_name;
- DESC tbl_name;
6.插入資料
語法:INSERT [INTO] tbl_name [(col_name,...)] VALUES (val,...)
# 不寫欄位名稱則必須給所有欄位賦值 INSERT USER VALUES ('kim',18); # 寫欄位名稱可以只賦對應欄位值 INSERT USER(username) VALUES ('kimtian');
7.空值與非空
- NULL,欄位值可以為空
- NOT NULL 欄位值禁止為空
8.自動編號AUTO_INCREMENT
- 自動編號,且必須與主鍵組合使用
- 預設情況下,起始值為1,每次的增量為1
自動編號欄位可以是整數或是浮點數,浮點數的小數位一定為0。
自動編號的欄位一定得是主鍵,但主鍵不一定是AUTO_INCREMENT。
二.約束
約束可以保證資料的完整性和一致性;約束分為表級約束和列級約束。
1.PRIMARY KEY主鍵約束
- 每張資料表只能存在一個主鍵
- 主鍵保證記錄的唯一性
- 主鍵自動為NOT NULL
# 自增主鍵,使用 PRIMARY KEY
CREATE TABLE IF NOT EXISTS user4(id INT(2) UNSIGNED AUTO_INCREMENT PRIMARY KEY,username VARCHAR(20) UNIQUE KEY,age TINYINT UNSIGNED,salary FLOAT(9,2) UNSIGNED);
# 自增主鍵,直接使用 KEY也是OK的,但建議直接使用 PRIMARY KEY,可讀性好,比較統一
CREATE TABLE IF NOT EXISTS user5(id INT(2) UNSIGNED AUTO_INCREMENT KEY,username VARCHAR(20) UNIQUE KEY,age TINYINT UNSIGNED,salary FLOAT(9,2) UNSIGNED);
# 非自增主鍵
CREATE TABLE IF NOT EXISTS user6(id INT(2) UNSIGNED PRIMARY KEY,username VARCHAR(20) UNIQUE KEY,age TINYINT UNSIGNED,salary FLOAT(9,2) UNSIGNED);
建立完成後,可以使用desc tablename;命令,查看錶結構,主鍵是否增加成功。
如圖所示可以看到主鍵建立成功。
2.UNIQUE KEY 唯一約束
- 唯一約束可以保證記錄的唯一性;
- 唯一約束的欄位可以為NULL;
- 每張資料表可以存在多個唯一約束。
# 為username欄位 設定唯一約束
CREATE TABLE IF NOT EXISTS user4(id INT(2) UNSIGNED AUTO_INCREMENT PRIMARY KEY,username VARCHAR(20) UNIQUE KEY,age TINYINT UNSIGNED,salary FLOAT(9,2) UNSIGNED);
建立完成後,可以使用命令desc tablename;,查看錶結構,唯一約束是否增加成功。
如圖所示可以看到唯一約束建立成功。
設定唯一約束的元素要有唯一性不能重複。如果username重複資料庫會報錯:
ERROR 1062 (23000): Duplicate entry 'kimtian' for key 'username'
3.DEFAULT 預設約束
- 預設值;
- 當插入記錄時,如果沒有明確為欄位賦值,則自動賦予預設值。
# 為sex性別欄位設定預設值,1表示男,2表示女,3表示保密,不傳時候預設為3
CREATE TABLE tbl(id INT(2) UNSIGNED AUTO_INCREMENT PRIMARY KEY,age TINYINT UNSIGNED,sex ENUM('1','2','3') DEFAULT '3');
向表table中插入一條資料:
# 只給年齡賦值了
insert tbl (age) VALUES (18);
我們沒並沒有給性別賦值。查看錶資料,可以看到性別預設被填寫了3。
4.NOT NULL 非空約束
# area地域欄位不能為空
CREATE TABLE tbl1(id INT(2) UNSIGNED AUTO_INCREMENT PRIMARY KEY,age TINYINT UNSIGNED,sex ENUM('1','2','3') DEFAULT '3',area varchar(20) NOT NULL);
area地域欄位不能為空,所以我們在插入資料時候,必須給area欄位賦值,否則會報錯:ERROR 1364 (HY000): Field 'area' doesn't have a default value
同樣如果給area賦值NULL也會報這個錯誤:
5.FOREIGN KEYp 外來鍵約束
- 保證資料一致性,完整性;
- 實現一對一或一對多關係。
建立外來鍵約束的要求:
- 父表和子表必須使用相同的儲存引擎,而且禁止使用臨時表;
- 資料表的儲存引擎只能為InnoDB;
- 外建列和參照列必須具有相似的資料型別。其中數字長度或是否有符號位必須相同,而字元的長度則可以不同;
- 外來鍵列和參照列必須建立索引,如果外來鍵列不存在索引的話,MySQL將會自動建立索引。
如下,建立兩張表,一張省份表,一張城市表,城市表有個外來鍵pid,參照省份表的id列。
# 省份表--參照表,也稱作父表,id為參照列。
CREATE TABLE provinces(id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,pname VARCHAR(20) NOT NULL);
# 城市表--子表,pid為外來鍵列。
CREATE TABLE citys(id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,cityname VARCHAR(20) NOT NULL,pid SMALLINT UNSIGNED, FOREIGN KEY (pid) REFERENCES provinces(id));
外來鍵約束的參照條件:
CASCADE | 從父表刪除或更新時,自動刪除和更新子表中匹配的行。 |
SET NULL | 從父表刪除或更新行時,設定子表中的外來鍵列為NULL,如果使用該選項,必須保證子表外來鍵列沒有指定NOT NULL。 |
RESTRICT | 拒絕對父表的更新或刪除操作。 |
NO ACTION | 標準SQL的關鍵字,在MySQL中與RESTRICT相同。 |
預設 | 拒絕對父表的更新或刪除操作。 |
用法如下:
# ON DELETE CASCADE 刪除時,自動刪除和更新子表中匹配的行。
CREATE TABLE citys1(id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,cityname VARCHAR(20) NOT NULL,pid SMALLINT UNSIGNED, FOREIGN KEY (pid) REFERENCES provinces(id) ON DELETE CASCADE);
使用命令SHOW CREATE TABLE tbl_name;
可以檢視到以下資訊:
(1)ENGINE=InnoDB引擎是InnoDB。
(2)KEY `pid` (`pid`)。外來鍵列pid已經被自動建立了索引。
(3)CONSTRAINT `citys_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `provinces` (`id`)外來鍵索引被成功建立,外來鍵索引名稱為citys_ibfk_1。
也可以使用命令SHOW INDEX FROM tab_name;查看錶中索引情況。
6.表級約束與列級約束
表級約束 | 列級約束 |
對多個數據列建議的約束,稱為表級約束。 | 對一個數據列建立的約束,稱為列級約束。 |
只能在列定義後生命 | 可以在列定義時宣告,也可以在列定義後宣告。 |
很少使用。 |
常用。 |
只支援外來鍵約束,主鍵約束,唯一約束。不支援非空約束 和 預設約束。 |
外來鍵約束,主鍵約束,唯一約束,非空約束,預設約束全都支援。 |
三.修改資料表
1.新增和刪除列
(1)新增單列
語法:ALTER TABLE tbl_name ADD [COLUMN] col_name column_definaition [FIRST | AFTER col_name]
如果後面[FIRST | AFTER col_name]這部分省略,則新增欄位預設加在所有列的後面。
#testalter1欄位加在了最前面
ALTER TABLE citys ADD testalter1 varchar(20) FIRST;
#testalter2欄位加在了cityname欄位的後面
ALTER TABLE citys ADD testalter2 varchar(20) AFTER cityname ;
#後面省略預設加在所有列的最後面
ALTER TABLE citys ADD testalter3 varchar(20);
再查看錶結構可以看到新增了3個欄位,位置和我們要求的一致。
(2)新增多列
語法:ALTER TABLE tbl_name ADD [COLUMN] (col_name column_definaition,...)
# 多列不能指定位置,預設加在所有列的最後面
ALTER TABLE citys ADD (testalter4 varchar(20),testalter5 varchar(20) );
(3)刪除列
語法:ALTER TABLE tbl_name DROP [COLUMN] col_name
# 刪除單列
ALTER TABLE citys DROP testalter1;
# 刪除多列
ALTER TABLE citys DROP testalter2, DROP testalter3, DROP testalter4;
# 刪除某列,並增加num列
ALTER TABLE citys DROP testalter5 , ADD num int(20) AFTER cityname;
2.新增和刪除主鍵約束
(1)新增主鍵約束
ALTER TABLE tbl_name ADD [CONSTARAINT [symbol]] PRIMARY KEY [index_type] (index_col_name)
# [CONSTARAINT [symbol]] 表示約束的名稱
# [index_type]表示索引的型別,有hash樹和B樹索引,現在預設是B樹
# 建立user表,未給任何約束
CREATE TABLE IF NOT EXISTS user(id INT(2) UNSIGNED ,username VARCHAR(20),age TINYINT UNSIGNED,salary FLOAT(9,2) UNSIGNED);
# 新增主鍵約束
ALTER TABLE user ADD CONSTRAINT pk_user_id PRIMARY KEY(id);
使用命令desc user;查看錶結構,可以看到id欄位加了PRIMARY KEY.
(2)刪除主鍵約束
語法:ALTER TABLE tbl_name DROP PRIMARY KEY
# 刪除主鍵約束,並不用指定名稱,因為任何一個數據表有且只有一個主鍵
ALTER TABLE user DROP PRIMARY KEY;
再次使用命令desc user;查看錶結構,可以看到id欄位的主鍵約束已經被刪除。
3.新增和刪除唯一約束
(1)新增唯一約束
ALTER TABLE tbl_name ADD [CONSTARAINT [symbol]] UNIQUE [INDEX | KEY] [index_name] [index_type](index_col_name,...)
# 新增唯一約束,唯一約束可以有多個
ALTER TABLE user ADD UNIQUE(username);
使用命令desc user;查看錶結構,可以看到username欄位加了UNIQUE KEY.
(2)刪除唯一約束
ALTER TABLE tbl_name DROP {INDEX | KEY} index_name
# 刪除唯一約束,唯一約束要指定名稱,因為可能有多個唯一約束
ALTER TABLE user DROP INDEX username;
4.新增和刪除外來鍵約束
(1)新增外來鍵約束
ALTER TABLE tbl_name ADD [CONSTARAINT [symbol]] FOREIGN KEY [index_name] (index_col_name,...) reference_definition
# 建立一個城市表
CREATE TABLE citys(id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,cityname VARCHAR(20) NOT NULL,pid SMALLINT UNSIGNED);
# 新增外來鍵約束
ALTER TABLE citys ADD FOREIGN KEY(pid) REFERENCES provinces(id);
使用命令SHOW CREATE TABLE citys ;可以看到加上了外來鍵約束。
(2)刪除外來鍵約束
ALTER TABLE tbl_name DROP FOREIGN KEY fk_symbol
# 刪除外來鍵約束
ALTER TABLE citys DROP FOREIGN KEY citys_ibfk_1;
# 刪除索引(外來鍵約束刪除後MySQL自動加的索引依然存在,需要的話可以繼續刪除索引)
ALTER TABLE citys DROP INDEX pid;
5.新增和刪除預設約束
(1)新增預設約束
ALTER TABLE tbl_name ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}
# 新增預設約束,給age欄位預設值為15
ALTER TABLE user ALTER age SET DEFAULT 15;
使用命令desc user;查看錶結構,可以看到age欄位加了Default預設值15。
(2)刪除預設約束
ALTER TABLE tbl_name ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}
# 刪除預設約束
ALTER TABLE user ALTER age DROP DEFAULT;
使用命令desc user;查看錶結構,可以看到age欄位的預設值被刪除。
6.修改列定義
(1)修改列定義
ALTER TABLE tbl_name MODIFY [COLUMN] col_name column_definaition [FIRST | AFTER col_name]
# 列名字不存在問題,但定義型別和順序有問題使用MODIFY
# 修改位置,欄位型別不變
ALTER TABLE user MODIFY salary FLOAT(9,2) UNSIGNED AFTER username;
# 修改型別.要注意大型別改到小型別有可能造成資料的丟失。
ALTER TABLE user MODIFY age INT(2) UNSIGNED AFTER id;
7.資料表和資料列更名
儘量少使用資料表更名和資料列名更名。因為建立了索引,或曾經使用過檢視和儲存過程的情況下,修改可能會導致某些檢視和儲存過程無法正常工作。
(1)修改列名稱
ALTER TABLE tbl_name CHANGE [COLUMN] old_col_name new_col_name column_definaition [FIRST | AFTER col_name]
# 修改列定義和列名稱
ALTER TABLE user CHANGE id user_id TINYINT(2) FIRST;
(2)修改表名稱
方法一:
ALTER TABLE tbl_name RENAME [TO | AS] new_tbl_name
方法二:
RENAME TABLE tbl_name TO new_tbl_name [,tbl_name2 TO new_tbl_name]
# 修改表名稱--方法一
ALTER TABLE user RENAME user10;
# 修改表名稱--方法二,可以多張表更名
RENAME TABLE user1 TO user11,user2 TO user12;