第三章 約束和修改數(shù)據(jù)表

回顧和概述

數(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ù)表更名(兩種方式)

小結(jié)#

Paste_Image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 1、約束概述 約束的目的是為了保證數(shù)據(jù)的完整性與一致性。 按照約束的范圍劃分:列級(jí)約束:只對(duì)一個(gè)數(shù)據(jù)列建立約束。既...
    黒貓閱讀 997評(píng)論 3 5
  • 1、MySQL啟動(dòng)和關(guān)閉(安裝及配置請(qǐng)參照百度經(jīng)驗(yàn),這里不再記錄。MySQL默認(rèn)端口號(hào):3306;默認(rèn)數(shù)據(jù)類型格式...
    強(qiáng)壯de西蘭花閱讀 677評(píng)論 0 1
  • 什么是數(shù)據(jù)庫(kù)? 數(shù)據(jù)庫(kù)是存儲(chǔ)數(shù)據(jù)的集合的單獨(dú)的應(yīng)用程序。每個(gè)數(shù)據(jù)庫(kù)具有一個(gè)或多個(gè)不同的API,用于創(chuàng)建,訪問,管理...
    chen_000閱讀 4,055評(píng)論 0 19
  • 生活就像蠟燭,你不去點(diǎn)燃,生命就會(huì)永遠(yuǎn)黑暗。可是一旦你點(diǎn)燃了,它也會(huì)慢慢流逝,化作一縷青煙緩緩逝去。 -題記 北京...
    淇水滺々閱讀 245評(píng)論 0 1
  • 汕頭的首次共修在昨天圓滿結(jié)束,由于太投入,感覺好像做了一小時(shí)的動(dòng)態(tài)靜心一般,身體累到不行了。這個(gè)過程中,有很多的覺...
    bef243e45c7f閱讀 630評(píng)論 1 5