回顧和概述
數(shù)據(jù)類型
- 整型
- 浮點(diǎn)型
- 字符型
- 日期時(shí)間型
數(shù)據(jù)表操作
- 如何創(chuàng)建數(shù)據(jù)表
- PRIMARY KEY(主鍵約束)
- UNIQUE KEY (唯一約束)
- DEFAULT(默認(rèn)約束)
- NOT NULL(非空約束)
- 記錄插入
- 查找記錄
外鍵約束的要求解析
約束
1.約束保證數(shù)據(jù)的完整性和一致性
2.約束分為表級(jí)約束和列級(jí)約束
3.約束類型包括
- NOT NULL(非空約束)
- PRIMARY KEY(主鍵約束)
- UNIQUE KEY(唯一約束)
- DEFAULT(默認(rèn)約束)
- FOREIGN KEY(外鍵約束)
根據(jù)約束的字段多少定義列級(jí)約束和表級(jí)約束
列級(jí)約束:約束只針對(duì)于某一個(gè)字段使用
表級(jí)約束:約束針對(duì)于兩個(gè)或兩個(gè)以上的字段使用
外鍵約束:FOREIGN KEYp
- 保持?jǐn)?shù)據(jù)一致性,完整性
- 實(shí)現(xiàn)一對(duì)多或一對(duì)一的關(guān)系
外鍵約束的要求:
1.父表和子表必須使用相同的存儲(chǔ)引擎,而且禁止使用臨時(shí)表。
2.數(shù)據(jù)表的存儲(chǔ)引擎只能為InoDB。
3.外鍵列和參照列必須具有相似的數(shù)據(jù)類型。其中數(shù)字的長(zhǎng)度或是否有符號(hào)位必須相同;而字符的長(zhǎng)度可以不同。
4.外鍵列和參照列必須創(chuàng)建索引。如果外鍵列不存在索引,MySQL將自動(dòng)創(chuàng)建索引。
父表:子表所參照的表
子表:具有外鍵列的表
外鍵列:曾經(jīng)加過外鍵關(guān)鍵詞的列
參照列:外鍵所參照的列
參照列如果沒有索引會(huì)自動(dòng)創(chuàng)建,外鍵列沒有索引不會(huì)自動(dòng)創(chuàng)建
編輯數(shù)據(jù)表的默認(rèn)存儲(chǔ)引擎
找到配置文件my.ini,打開修改成如下:
default-storage-engine=INNODB
修改完成后需要重啟mysql服務(wù)
外鍵約束例子:
創(chuàng)建省份表
CREATE TABLE provinces(
id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
pname VARCHAR(20) NOT NULL
);
使用SHOW CREATE TABLE provinces;
查看一下存儲(chǔ)引擎
創(chuàng)建用戶表:
CREATE TABLE users(
id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(10) NOT NULL,
pid BIGINT,
FOREIGN KEY (pid) PEFERENCES provinces (id)
);
會(huì)報(bào)錯(cuò),因?yàn)閜id的類型和provinces表的id不一樣
CREATE TABLE users(
id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(10) NOT NULL,
pid SMALLINT,
FOREIGN KEY (pid) PEFERENCES provinces (id)
);
同樣報(bào)錯(cuò),因?yàn)樵瓉硎菬o符號(hào)的,數(shù)字類型的類型必須一樣,包括符號(hào)
CREATE TABLE users(
id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(10) NOT NULL,
pid SMALLINT UNSIGNED,
FOREIGN KEY (pid) PEFERENCES provinces (id)
);
父表:provinces
子表:users
主鍵會(huì)自動(dòng)創(chuàng)建索引
顯示proviences的索引:SHOW INDEXES FROM proviences;
以網(wǎng)格形式顯示:SHOW INDEXES FROM proviences\G;
顯示id已經(jīng)創(chuàng)建索引
以網(wǎng)格形式顯示users的索引:SHOW INDEXES FROM proviences\G;
有兩個(gè)索引,一個(gè)是id字段是主鍵,自動(dòng)加上了索引,系統(tǒng)為pid字段自動(dòng)創(chuàng)建了索引
此時(shí)查看users表:
SHOW CREATE TABLE users;
看到系統(tǒng)加了一個(gè)KEY `pid` (`pid`)
外鍵約束的參照操作
1.CASCADE:從父表刪除或更新且自動(dòng)刪除或跟新子表中匹配的行
2.SET NULL:從父表刪除或更新行,并設(shè)置子表中的外鍵列為NULL。如果使用該選項(xiàng),必須保證子表列沒有指定NOT NULL
3.RESTRICT:拒絕對(duì)父表的刪除或更新操作
4.NO ACTION:標(biāo)準(zhǔn)SQL的關(guān)鍵字,在MySQL中與RESTRICT相同
CASCADE例:
創(chuàng)建users1表
CREATE TABLE users(
id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(10) NOT NULL,
pid SMALLINT UNSIGNED,
FOREIGN KEY (pid) PEFERENCES provinces (id) ON DELETE CASCADE
);
在省份表中插入三條數(shù)據(jù):
INSERT provinces(pname) VALUES('A');
INSERT provinces(pname) VALUES('B');
INSERT provinces(pname) VALUES('C');
在users1表中插入一條數(shù)據(jù)
INSERT users1(username,pid) VALUES('Tom',3);#正確
INSERT users1(username,pid) VALUES('John',7);#錯(cuò)誤,因?yàn)閜rovinces表中沒有id為7的值
INSERT users1(username,pid) VALUES('John',1);#正確
INSERT users1(username,pid) VALUES('Rose',3);#正確
此時(shí)用SELECT * FROM users1;
查看表記錄,發(fā)現(xiàn)插入的id為134而不是123,因?yàn)榈诙l雖然沒有插入成功,但是id還是會(huì)自動(dòng)增長(zhǎng)
現(xiàn)在,把provinces表中的id=3的記錄刪除,此時(shí)再查看proviences表和ueses1表發(fā)現(xiàn)provinces表中的id=3的記錄被刪除,users1表中的pid=3的值也一同被刪除了,因?yàn)閯偛胚x擇的外鍵約束參照是ON DELETE CASCADE,此處只演示刪除操作,更新操作同樣也會(huì)更新子表中的數(shù)據(jù)
*在實(shí)際開發(fā)中,很少使用物理外鍵約束,通常使用邏輯外鍵約束,因?yàn)槲锢硗怄I約束只有innodb存儲(chǔ)引擎支持,在其他存儲(chǔ)引擎如:MyISAM上是不支持的,所以如果想使用MyISAM存儲(chǔ)引擎,通常不會(huì)定義外鍵約束,所謂邏輯約束是指在創(chuàng)建表時(shí)不會(huì)使用FOREIGN關(guān)鍵詞,而是在定義兩張表的時(shí)候按照存在著某種結(jié)構(gòu)的方式去定義
表級(jí)約束與列級(jí)約束
按照參照數(shù)目的多少,可以分為表級(jí)約束和列級(jí)約束
表級(jí)約束與列級(jí)約束
- 對(duì)一個(gè)數(shù)據(jù)列建立的約束,稱為列級(jí)約束
- 對(duì)多個(gè)數(shù)據(jù)列建立的約束,稱為表級(jí)約束
- 列級(jí)約束既可以在列定義時(shí)聲明,也可以在列定以后聲明
- 表級(jí)約束只能在列定義后聲明
CREATE TABLE users(
id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(10) NOT NULL,
pid SMALLINT UNSIGNED,
FOREIGN KEY (pid) PEFERENCES provinces (id) ON DELETE CASCADE #列定義后聲明約束,放在同一行為定義時(shí)同時(shí)聲明
);
實(shí)際開發(fā)中,列級(jí)約束用的較多,表級(jí)約束很少用到。并不是所有約束都存在列級(jí)約束和表級(jí)約束之分,NOT NULL 和 DEFAULT 這兩個(gè)就只有列級(jí)約束,主鍵,唯一,外鍵約束才存在列級(jí)約束和表級(jí)約束,還有一個(gè)CHEACK約束,但是不起作用,所以沒有提到,了解一下就行了
修改數(shù)據(jù)表-添加刪除列
修改數(shù)據(jù)表
添加單列
ALTER TABLE tbl_name ADD [COLUMN] col_name column_definition [FIRST | AFTER col_name]
COLUMN可以省略,F(xiàn)IRST 插入的列在所有列的最前方,AFTER clo_name插入的列在某一列的后邊,如果不寫則默認(rèn)在所有列的最后邊
添加列:
ALTER TABLE user1 ADD age TINYINT UNSIGNED NOT NULL DEFAULT 10;#添加的列在所有列的最后邊
ALTER TABLE user1 ADD password VARCHAR(32) NOT NULL AFTER username;#添加的列在username列的后邊
ALTER TABLE user1 ADD truename VARCHAR(20) NOT NULL FIRST;#添加的列在所有列的最前邊
添加多列
ALTER TABLE tbl_name ADD [COLUMN] (col_name column_defination,...)
添加單列時(shí)列不需要加小括號(hào),可以指定添加列的位置,添加多列時(shí)不能指定添加位置,只能默認(rèn)放到所有列的后邊
刪除列
ALTER TABLE tbl_name DROP [COLUMN] col_name
刪除列:
ALTER TABLE users1 DROP truename;#刪除truename字段
ALTER TABLE users2 DROP password,DROP age;#password字段和age字段同時(shí)被刪除
也可以刪除的同時(shí)新增一列
修改數(shù)據(jù)表-添加約束
添加主鍵約束
ALTER TABLE tbl_name ADD [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,...)
CONSTRAINT 可以不寫,如果寫可以為主鍵起名字
index_type索引類型,兩種:HASH索引,BTREE索引。默認(rèn)為BTREE。
例:
創(chuàng)建無用的表users2
CREATE TABLE users2(
username VARCHAR(10) NOT NULL,
pid SMALLINT UNSIGNED
);
增加主鍵
ALTER TABLE users2 ADD id SMALLINT UNSIGNED;#增加一列
ALTER TABLE users2 ADD C ONSTRAINT PK_users2_id PRIMARY KEY (id);#將id字段設(shè)置為主鍵
使用SHOW COLUMNS FROM users2;
查看表結(jié)構(gòu)可以看到id被設(shè)置成了主鍵
添加唯一約束
ALTER TABLE tbl_name ADD [CONSTRAINT [symbol]] UNIQUE [INDEX | KEY] [index_name] [index_type] (index_col_naem,...)
和主鍵約束不同的是唯一約束可以有多個(gè),而主鍵約束只能有一個(gè)
為username添加唯一約束例:
ALTER TABLE users2 ADD UNIQUE (username);
使用SHOW COLUMNS FROM users2;
查看表結(jié)構(gòu)可以看到username被設(shè)置了唯一約束
添加外鍵約束
ALTER TABLE tbl_name ADD [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name,...) reference_definition
要求users2的pid參照provinces表中的id
例:
ALTER TABLE users2 ADD FOREIGN KEY (pid) REFERENCES provinces (id);#為pid添加provinces表中的id外鍵約束,
使用SHOW COLUMNS FROM users2;
查看表結(jié)構(gòu)可以看到為pid添加了外鍵約束
添加/刪除默認(rèn)約束
ALTER TABLE tbl_name ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}
添加/刪除默認(rèn)約束:
ALTER TABLE users2 ADD age TINYINT UNSIGNED NOT NULL;#添加一列
ALTER TABLE users2 ALTER age SET DEFAULT 15;#為age字段添加默認(rèn)約束
ALTER TABLE users2 ALTER age DROP DEFAULT;#刪除age字段的默認(rèn)約束
修改數(shù)據(jù)表-刪除約束#
刪除主鍵約束##
ALTER TABLE tbl_name DROP PRIMARY KEY
刪除主鍵約束
ALTER TABLE users2 DROP PRIMARY KEY;#刪除主鍵約束
不用加主鍵的列名,因?yàn)橐粡埍砭鸵粋€(gè)主鍵
刪除唯一約束##
ALTER TABLE tbl_name DROP {INDEX | KEY} index_name
ALTER COLUMNS FROM users2 DROP INDEX username;
刪除users2表中的username索引
使用SHOW INDEX FROM users2\G;#以網(wǎng)格形式查看索引
看到username的索引被刪除了
不是刪除字段,只刪除索引約束
刪除外鍵約束##
ALTER TABLE tbl_name DROP FOREIGN KEY fk_symbol
使用SHOW CREATE TABLE users2;
查看外鍵約束名稱
可以看到系統(tǒng)設(shè)置的外鍵名稱users2_ibfk_1
ALTER TABLE users2 DROP FOREIGN KEY users2_ibfk_1;#刪除外鍵約束
查看表結(jié)構(gòu)看到外鍵已經(jīng)被刪除,還存在一個(gè)索引
使用ALTER TABLE users2 DROP INDEX pid;#刪除索引
再查看表結(jié)構(gòu),看到索引也被刪除了
修改數(shù)據(jù)表-修改列定義和更名數(shù)據(jù)表#
修改列定義:數(shù)據(jù)列名字沒問題,但是類型和位置可能有問題
ALTER TABLE tbl_name MODIFY [COLUMN] col_name column_definition [FIRST | AFTER col_name]
例:剛才的users2表,id不在第一個(gè)位置(在哪個(gè)位置無所謂,但是習(xí)慣上把id放到第一個(gè)位置)
ALTER TABLE users2 MODIFY id SMALLINT UNSIGNED NOT NULL FIRST;#把id字段放到第一個(gè)位置
使用SHOW COLUMNS FROM users2;
看到id已經(jīng)放到了第一個(gè)位置
ALTER TABLE users2 MODIFY id TINYINT UNSIGNED NOT NULL;#把id變成TINYINT類型
由大類型改成小類型有可能造成數(shù)據(jù)丟失
修改列名稱##
ALTER TABLE tbl_name CHANGE [COLUMN] old_col_name new_col_name column_definition [FIRST | AFTER col_name]
同時(shí)修改類型和名稱:
ALTER TABLE users2 CHANGE pid p_id TINYINT UNSIGNED NOT NULL;#把pid的名稱改成p_id同時(shí)把類型改成TINYINT
數(shù)據(jù)表更名##
- 方法一:
ALTER TABLE tbl_name RENAME [TO | AS] new_tbl_name
- 方法二:
RENAME TABLE tbl_name TO new_tbl_name [,tbl_name2 TO new_tbl_name2]...
使用方法2可以為多張數(shù)據(jù)表更名
ALTER TABLE users2 RENAME users3;#把數(shù)據(jù)表users2的表名改成users3
使用SHOW TABLES
查看所有數(shù)據(jù)表看到users2被改成了users3
RENAME TABLE users3 TO users2;#把數(shù)據(jù)表users3的表名改成users2
盡量少使用數(shù)據(jù)列和數(shù)據(jù)表的更名,因?yàn)楫?dāng)我們以后創(chuàng)建了索引或者創(chuàng)建了視圖或存儲(chǔ)過程表名和列名被引用了如果更名會(huì)導(dǎo)致存儲(chǔ)過程或視圖無法使用
本節(jié)知識(shí)點(diǎn)##
- 約束
- 按功能劃分:NOT NULL,PRIMARY KEY,UNIQUE KEY,DEFAULT,FOREIGN KEY
- 按數(shù)據(jù)列的數(shù)目劃分:表級(jí)約束,列級(jí)約束
- 修改數(shù)據(jù)表
- 針對(duì)字段的操作:添加/刪除字段、修改列定義,修改列名稱等
- 針對(duì)約束的操作:添加/刪除各種約束
- 針對(duì)數(shù)據(jù)表的操作:數(shù)據(jù)表更名(兩種方式)