內容概要 約束條件 表與表之間建立關係(約束) 修改表的完整語法 複製表 約束條件 default預設值 """ # 補充:在插入數據的時候可以指定欄位 create table t1 ( id int, name varchar(16) ); insert into t1 (name, id) v ...
內容概要
- 約束條件
- 表與表之間建立關係(約束)
- 修改表的完整語法
- 複製表
約束條件
default預設值
""" # 補充:在插入數據的時候可以指定欄位 create table t1 ( id int, name varchar(16) ); insert into t1 (name, id) values ('samuel', 1); create table t2 ( id int, name varchar(16), gender enum('male', 'female', 'others') default 'male' ); insert into t2 (id, name) values (1, 'samuel'); insert into t2 values (2, 'nagase', 'female'); """
unique唯一
""" # 單列唯一 create table t3 ( id int unique, name varchar(16) ); insert into t3 values (1, 'samuel'), (1, 'nagase'); insert into t3 values (1, 'samuel'), (2, 'nagase'); # 聯合唯一 # ip和port,單個可以重覆,但是加在一起必須是唯一的 create table t4 ( id int, ip varchar(16), port int, unique (ip, port) ); insert into t4 values (1, '192.168.1.1', 8000); insert into t4 values (2, '192.168.1.1', 8001); insert into t4 values (3, '192.168.1.2', 8000); insert into t4 values (4, '192.168.1.1', 8000); """
primary key主鍵
""" # 單單從約束效果上來看,primary key等價於not null + unique # 非空且唯一!!! create table t5 ( id int primary key ); insert into t5 values (null); insert into t5 values (1), (1); insert into t5 values (1), (2); # 它除了有約束效果之外,它還是Innodb存儲引擎在組織數據的依據。 # Innodb存儲引擎在創建表的時候必須有primary key # 因為它類似於書的目錄,能夠幫助提升查詢效率,並且也是建表的依據 # 1、一張表中,有且只有一個主鍵,如果沒有設置主鍵,那麼會從上至下搜索,直到遇到一個非空且唯一的欄位將其升級為primary key create table t6 ( id int, name varchar(16), age int not null unique, addr varchar(32) not null unique ); # 2、如果表中沒有主鍵也沒有其他任何的非空且唯一欄位,那麼Innodb會採用自己內部提供的一個隱藏欄位作為primary key,隱藏意味著你無法使用它,進而就無法提升查詢效率 # 3、一張表中通常都應該有一個主鍵欄位,並且通常將id作為主鍵 # 單個欄位主鍵 create table t7 ( id int primary key, name varchar(16) ); # 聯合主鍵(多個欄位聯合起來作為表的主鍵,本質還是一個主鍵) create table t7 ( ip varchar(16), port int, primary key (ip, port) ); """
auto_increment自增
""" # 當編號特別多的時候,人為的去維護太過繁瑣,因此這就涉及到了自增 create table t8 ( id int primary key auto_increment, name varchar(16) ); insert into t8 (name) values ('samuel'), ('nagase'), ('matthew'); # 註意:auto_increment通常都是加在primary key鍵上,不能給普通欄位加 """
補充:刪除表的兩種方法
""" delete from 表名 truncate 表名 """
兩種方法的區別:delete from 表名這種方法,在刪除表中數據的時候,主鍵的自增不會停止,會繼續編號
然而,truncate 表名這種方式,除了清空數據表之外還會重置主鍵的自增,使其從1重新開始
表與表之間建立關係
""" # 定義了一張員工表 表中有很多欄位 # id name gender dep_name dep_desc # 分析目前的表所存在的問題: # 1、該表的組織結構不是很清晰 # 2、浪費磁碟空間 # 3、數據的擴展性極差 # 那麼該如何優化呢?那麼多的欄位全部寫在了一張表裡,那就相當於把所有的代碼全部寫在一個文件中,這樣是有極大問題的。 # 因此我們應該將該表拆分為:員工表和部門表 """
外鍵約束
# 外鍵就是用來幫助我們建立表與表中間關係的 foreign key
表與表之間的關係
# 表與表之間的關係只有4種 # 一對多關係 # 註意:在MySQL中,沒有多對一關係這麼一說,一對多、多對一 ,都是一對多 # 多對多關係 # 一對一關係 # 沒有關係
一對多關係
""" 判斷表與表中間關係的時候,一定要一步一步的判斷,使用正確的方法,那就是 “換位思考”分別站在兩張表的角度考慮問題 比如:員工表與部門表 先站在員工表 思考一個員工能夠對應多個部門------不能!!! 再站在部門表 思考一個部門可以不可以包含多個員工-------可以!!! 得出結論: 員工表與部門表表示單向的一對多,所以表關係就是一對多。 """
foreign key 【原則1】一對多關係的表 外鍵欄位要建立在多的那一方 【原則2】在創建表的時候,一定要先創建被關聯的那一方 # SQL語句 create table dep ( id int primary key auto_increment, dep_name varchar(16), dep_desc varchar(32) ); create table emp ( id int primary key auto_increment, name varchar(16), gender enum('male', 'female', 'others') default 'male', dep_id int, foreign key (dep_id) references dep (id) ); insert into dep (dep_name, dep_desc) values ('教學部', '教書育人'), ('技術部', '技術能力有限'), ('外交部', '外交'); insert into emp (name, dep_id) values ('samuel', 2), ('nagase', 1), ('matthew', 1), ('garnet', 3); # 修改dep表的id欄位 update dep set id = 200 where id = 2; 操作失敗 # 刪除dep表裡的數據 delete from dep; 操作失敗 以上兩個語句都失敗了,是因為dep表被emp表所引用,因此,dep表不可以被刪除。解決辦法如下: # 1、先刪除教學部對應的員工數據,之後再刪除部門 這樣做太過繁瑣 # 2、真正做到數據之間有關係,更新就同步更新,刪除就同步刪除 # 那也就是級聯更新、級聯刪除,那麼如何做到呢??? # 解決辦法:在創建表的時候添加額外的約束 create table dep ( id int primary key auto_increment, dep_name varchar(16), dep_desc varchar(32) ); create table emp ( id int primary key auto_increment, name varchar(16), gender enum('male', 'female', 'others') default 'male', dep_id int, foreign key(dep_id) references dep(id) on update cascade on delete cascade );
多對多關係
""" 判斷表與表之間關係的時候,一定要使用正確的方法,那就是“換位思考”,分別站在兩張表的角度考慮 例如:圖書表與作者表 先站在圖書表的角度考慮,思考一個圖書可不可以有多個作者-----可以!!! 再站在作者表的角度考慮,思考一個作者可不可以出版多本圖書----可以!!! 得出結論: 圖書表與作者表是雙向的一對多,所以表關係就是“多對多”關係 """
create table book ( id int primary key auto_increment, title varchar(32), price int, author_id int, foreign key(author_id) references author(id) on update cascade on delete cascade ); create table author ( id int primary key auto_increment, name varchar(32), age int, book_id int, foreign key(book_id) references book(id) on update cascade on delete cascade ); # 如果按照以上的語句創建表,結果是:::失敗的!!! 回想我們的兩大原則: 【原則1】針對於一對多關係的表,外鍵欄位要建立在多的那一方 【原則2】在創建表的時候,一定要先創建被關聯的那一方 針對於圖書表與作者表,圖書表引用了作者表的id,對於圖書表來說,作者表是被關聯的那一方;那麼反過來,對於作者表來說,圖書表是被關聯的那一方,如此一來,雙方都是被關聯的那一方,那,,,,怎麼辦。。。雙方就這麼拖著。。。於是乎兩張表均創建失敗!!! # 其實我們只是想記錄圖書與作者的關係 # 針對多對多的關係,不能在兩張原表中創建外鍵 # 我們需要單獨創建一張表出來專門用於存儲兩張表之間的關係 create table book ( id int primary key auto_increment, title varchar(16), price int ); create table author ( id int primary key auto_increment, name varchar(16), age int ); create table book2author ( id int primary key auto_increment, book_id int, author_id int, foreign key(book_id) references book(id) on update cascade on delete cascade, foreign key(author_id) references author(id) on update cascade on delete cascade );
一對一關係
""" id name age gender addr phone hobby email... 如果一張表的欄位特別多,每次查詢又不是所有的欄位都能用到,於是我們將表一分為二 用戶表 id name age 用戶詳情表 id addr phone hobby email... “換位思考”的方法: 先站在用戶表的角度考慮:一個用戶能否對應多個用戶詳情----不可以!!! 再站在用戶詳情的角度考慮:一個用戶詳情是否屬於多個用戶---不可以!!! 得出結論:單向的一對多都不成立,那麼這個時候兩者之間的關係要麼就是一對一的關係要麼就是沒有關係 註意,針對於一對一的關係,外鍵欄位要建立在查詢頻率高的那張表中 """
create table user_detail ( id int primary key auto_increment, phone int, addr varchar(64) ); create table user ( id int primary key auto_increment, name varchar(16), age int, user_detail_id int unique, foreign key(user_detail_id) references user_detail(id) on update cascade on delete cascade );
總結
""" 表關係的創建需要用到foreign key 一對多 外鍵欄位建立在多的一方 多對多 自己開設第三張表 一對一 建立在任意一張表中都可以,但是建議在查詢頻率高的表中建立 建立表之間關係的方式 換位思考!!! 員工 與 部門 圖書 與 作者 用戶 與 用戶詳情 """
修改表
# MySQL對大小寫是不敏感的 # 1、修改表名 alter table 表名 rename 新表名; # 2、增加欄位 alter table 表名 add 欄位名 欄位類型(寬度) 約束條件; # 預設是加在表的最後 alter table 表名 add 欄位名 欄位類型(寬度) 約束條件 first; # 加在表的開頭 alter table 表名 add 欄位名 欄位類型(寬度) 約束條件 after 欄位名; # 手動說明要加在哪裡 # 3、刪除欄位 alter table 表名 drop 欄位名; # 4、修改欄位 alter table 表名 modify 欄位名 欄位類型(寬度) 約束條件; alter table 表名 change 舊欄位名 新欄位名 欄位類型(寬度) 約束條件;
複製表
# 我們在執行SQL語句的時候,顯示的結果是一張虛擬的表 create table 新表名 select * from 表名; # 但是不可以複製主鍵、外鍵、索引...只是複製了結構和數據而已