1. 程式人生 > 實用技巧 >section_2.約束\索引\儲存引擎

section_2.約束\索引\儲存引擎

一、約束

"""
unsigned       無符號
not null       不為空
default        設定預設值
unique         唯一約束,資料唯一不重複
primary key    主鍵,標記資料的唯一特徵(唯一且不為空)
auto_increment 自增加1(一般配合主鍵使用, 或 unique進行自增)
zerofill       零填充(配合整型int使用) int(11) , 位數不夠11位,拿0補充
foreign key    外來鍵,把多張表通過一個關聯欄位聯合在一起,(這個欄位可以加外來鍵)
"""

1、unsigned 無符號

create
table t3(id int unsigned); insert into t3 values(100); insert into t3 values(-100); error

2、not null 不為空

create table t4(id int not null , name varchar(255));
insert into t4 values(1,"aaa");
insert into t4 values(null,"aaa"); error
insert into t4(name) values('abc');   error

3、default 設定預設值

create table
t5(id int not null,name varchar(255) default '高雪峰'); insert into t5 values(1,null); insert into t5(id) values(2);

4、unique 唯一約束,資料唯一不重複

"""
索引:相當於字典的目錄,通過索引可以加快查詢的速度
UNI 唯一索引,允許插入NULL空值
"""
create table t6(id int unique , name varchar(255) default '戈隆');
insert into t6(id) values(1);
insert into
t6(id) values(1); error insert into t6(id) values(null); ok insert into t6(id) values(null); ok

5、primary key 主鍵,標記資料的唯一特徵(唯一且不為空)

"""PRI 主鍵 非空且唯一 在一個表裡只能有一個主鍵"""
create table t7(id int not null unique , name varchar(255) default '戈隆');
insert into t7 values(1,"1122")
insert into t7 values(null,"1122")

# primary key 建立主鍵
create table t8(id int primary key , name varchar(255) default '戈隆' );
insert into t8 values(1,"ppp")

# 兩者同時存在 (優先顯示primary key 作為主鍵,另一個設定成UNI 唯一索引)
create table t9(id int primary key , name char(3) not null unique);

# 一個表裡只能有一個主鍵
create table t10(id int primary key , name char(3) primary key); error

5.1、auto_increment 自增加1(一般配合主鍵使用, 或 unique進行自增)

create table t11(id int primary key auto_increment , name varchar(255) default '孫致和')
insert into t11 values(1,"李博倫")
insert into t11 values(null,"李亞")
insert into t11(id) values(null)    
# 使用預設值自動插入
insert into t11 values()

# delete 只刪除資料,id號保留
delete from t11 ;
# truncate 刪除所有資料 + 重置id
truncate table t11;

6、zerofill 零填充(配合整型int使用) int(11) , 位數不夠11位,拿0補充

create table t12(id int(8) zerofill);
insert into t12 values(2)
insert into t12 values(123456789)

7、關於約束的新增和刪除

-- 1 新增/刪除 約束 not null
    -- alter table 表名 modify 欄位名 型別
    alter table t1 modify id int not null
    alter table t1 modify id int

-- 2 新增/刪除 unique 唯一索引
    -- alter table 表名 add unique(id)
    alter table t1 add unique(id)
    alter table t1 drop index id
    
-- 3 新增/刪除 primary key
    -- alter table 表名 add primary key(id);
    alter table t1 add primary key(id);
    alter table t1 drop primary key;
    
-- 4 新增/刪除 foreign key 外來鍵 (show create table student1 找到外來鍵名字,然後再刪)
    alter table student1 drop foreign key student1_ibfk_1; -- 刪除
    alter table student1 add foreign key(classid) references class1(id) -- 新增

二、索引

"""
主鍵索引 PRI  唯一索引 UNI  普通索引 MUL
"""

1、聯合唯一索引(欄位都設定成not null + unique 顯示PRI , 聯合在一起表達一種唯一性)

"""unique(欄位1,欄位2,欄位3 ... ) 把多個欄位拼在一起表達唯一的資料"""
create table t1_server(id int , server_name varchar(255) not null,ip char(15) not null,port int not null , unique(ip,port));
insert into t1_server values(1,"aaa","192.168.65.135",3306);
insert into t1_server values(1,"aaa","192.168.65.135",3306); error
insert into t1_server values(1,"aaa","192.168.65.135",443); 
insert into t1_server values(1,"aaa","192.168.65.130",443); 

2、聯合唯一約束(欄位不設定成not null)

create table t2_server(id int , server_name varchar(255) not null,ip char(15) ,port int , unique(ip,port));
insert into t2_server values(1,"aaa","192.168.65.135",3306);
insert into t2_server values(1,"aaa",null,null); -- 注意點,允許插入多個空值;

3、聯合唯一索引 和 主鍵 之間是否可以同時存在?

create table t3_server(id int , server_name varchar(255) not null,ip char(15) not null,port int not null , unique(ip,port));
alter table t3_server add primary key(id);

"""
unique(ip,port)      聯合唯一索引
primary key(ip,port) 聯合主鍵
這兩個用法一模一樣
區別:前者(unique)可以繼續新增一個主鍵,後者(primary key)不能再額外新增主鍵
主鍵可以是單個欄位,也可以是聯合主鍵,設定多個 單欄位 做主鍵不行的.    
"""

4、foreign key

"""
外來鍵,把多張表通過一個關聯欄位聯合在一起,(這個欄位可以加外來鍵) [可設定成聯級更新和刪除]
外來鍵所關聯的其他欄位必須具有唯一屬性 unique 或者 primary key
"""

4.1、建立一個班級與學生的關聯關係

4.1.1、建立班級表
-- 建立class1
create table class1(id int , classname varchar(255))

-- 刪除索引
alter table class1 drop index id
-- 新增索引
alter table class1 add unique(id);

-- 建立student1
create table student1(
id int primary key auto_increment, 
name varchar(255), 
age int , 
classid int,
foreign key(classid) references class1(id)
);

4.1.2、建立學生表
-- 建立student1
create table student1(
id int primary key auto_increment, 
name varchar(255), 
age int , 
classid int,
foreign key(classid) references class1(id)
);

4.1.3、向班級表插入資料

插入資料:

insert into class1 values(1,"python1");
insert into class1 values(2,"python2");    
insert into class1 values(3,"python3");
插入語句

4.1.4、向學生表插入資料

插入資料:

insert into student1 values(null,"ywz",88,2);
insert into student1 values(null,"lhl",99,2);
insert into student1 values(null,"ww",18,3);
插入語句

4.2、刪除資料

-- 刪除class1裡面的python31這個班級  (報錯刪不掉,因為有其他資料關聯該班級)
delete from class1 where id = 2;
-- 需要先把關聯的其他資料都刪掉之後再刪,才能成功
delete from student1 where id = 1;
delete from student1 where id = 2;

4.3、聯級刪除、聯級更新

"""
聯級刪除 on delete cascade
聯級更新 on update cascade
"""
delete from class2 where id = 2
-- 聯級更新
update class2 set id = 100  where classname = "python3";
-- cascade 級聯方式
-- cascade 方式 在父表上update/delete 級聯是,同步update/delete掉子表的匹配
-- 記錄外來鍵的級聯刪除;如果父表中的記錄被刪除,則字表中對應的記錄自動刪除
FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
    ON DELETE CASCADE

-- set null 方式
-- set null 在父表上update/delete 記錄是,將子表上匹配的記錄設為null
-- 例如 刪除父表的一個教師,不應該把子表中該教師對應的學生都刪除。
FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
    ON DELETE SET NULL

5、測試索引

--建立表
create table t1(id int,name varchar(20));

--儲存過程
--指定結束符以什麼結尾
delimiter $$
-- procedure 關鍵字 儲存過程 autoinsert定義函式
BEGIN
declare i int default 1;
while(i<500000)do
insert into t1 values(i,'kxq');
set i=i+1;
end while;
END$$

delimiter ;
call autoinsert();

-- 新增索引
create index index_name on t1(id);

三、儲存引擎:儲存資料的一種結構方式

show engines;  -- 檢視所有的儲存引擎

關於表級鎖\行級鎖\事務簡單概念

"""
表級鎖: 如果有人修改當前這個表,會直接上鎖,其他使用者無法進行修改,不能進行高併發.
行級鎖: 如果有人修改當前這個表中的一條記錄,當前這條資料會被鎖定,其他資料仍然可以被修改,速度快,允許高併發
事務處理: 執行sql語句時,必須所有的操作全部成功,最終提交資料,否則資料回滾,回到剛開始沒操作的那個狀態.

begin : 開啟事務
commit: 提交資料
rollback: 回滾資料
"""

關於儲存引擎基本特性

MyISAM : 支援表級鎖(5.6版本前預設儲存引擎)
InnoDB : 事務處理,行級鎖,外來鍵(5.6版本後預設儲存引擎)
MEMORY : 把資料放在記憶體中,做一個臨時的快取
BLACKHOLE : 黑洞,產生binlog日誌,不產生真實資料
            用來同步主從資料庫中的資料,場景發生在多伺服器叢集中 (一主一從,一主多從,主資料庫:增刪改,從資料庫:查)

使用不同儲存引擎建立表結構

create table myisam1(id int , name varchar(255)) engine = MyISAM;

-- myisam1.frm  表結構
-- myisam1.MYD  表資料
-- myisam1.MYI  表索引

create table innodb1(id int , name varchar(255)) engine = InnoDB;
-- innodb1.frm  表結構
-- innodb1.ibd  表資料 + 表索引

create table memory1(id int , name varchar(255)) engine = MEMORY;
-- memory1.frm 表結構
-- 沒有資料檔案的,因為所有的資料都臨時儲存在記憶體之中

create table blackhole1(id int , name varchar(255)) engine = BLACKHOLE;
-- blackhole1.frm 表結構
-- 記憶體中不儲存任何值