1. 程式人生 > >MySQL基礎知識(二)——資料表和約束

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;