10.6 約束條件 10.61 not null 、default 10.62 unique mysql中存在一種專門的數據結構,叫 key,又稱為索引,通過該數據結構可以減少 i/o 次數,從而加速查詢效率 index key : 只有加速查詢的效果,沒有約束的功能 unique key:不僅有加 ...
10.6 約束條件
10.61 not null 、default
create table t15( id int, name char(16) not null, sex enum('male','female','other') not null default "male" ); #alter table t15 modify name char(16) not null; insert into t15(id,name) values (1,'egon1'), (2,'egon2'), (3,'egon3'); mysql> desc t15; +-------+-------------------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------------------------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | name | char(16) | NO | | NULL | | | sex | enum('male','female','other') | NO | | male | | +-------+-------------------------------+------+-----+---------+-------+ mysql> select * from t15; +------+-------+------+ | id | name | sex | +------+-------+------+ | 1 | egon1 | male | | 2 | egon2 | male | | 3 | egon3 | male | +------+-------+------+
10.62 unique
mysql中存在一種專門的數據結構,叫 key,又稱為索引,通過該數據結構可以減少 i/o 次數,從而加速查詢效率 index key : 只有加速查詢的效果,沒有約束的功能 unique key:不僅有加速查詢的效果,還附加了一種約束的功能 primary key:不僅有加速查詢的效果,還附加了一種約束的功能,並且innodb存儲引擎會按照主鍵欄位的值 來組織表中所有的數據,所以一種inndob表中必須有、而且只能有一個主鍵,通常為該表的id欄位
unique:限制欄位的值的唯一性,單從約束角度去看:唯一性約束
#單列唯一 create table t16( id int unique, name char(16) ); # 聯合唯一(不能完全相同) create table server( id int unique, ip char(15), port int, unique(ip,port) ); mysql> desc server; +-------+----------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+----------+------+-----+---------+-------+ | id | int(11) | YES | UNI | NULL | | | ip | char(15) | YES | MUL | NULL | | | port | int(11) | YES | | NULL | | +-------+----------+------+-----+---------+-------+ insert into server values(1,'1.1.1.1',3306),(2,'1.1.1.1',3307),(3,'1.1.1.2',3306); mysql> select * from server; +------+---------+------+ | id | ip | port | +------+---------+------+ | 1 | 1.1.1.1 | 3306 | | 2 | 1.1.1.1 | 3307 | | 3 | 1.1.1.2 | 3306 | +------+---------+------+
10.63 primary key
primary key:單單從約束角度去看,primary key就等同於 not null + unique 強調: 1、一張表中必須有,並且只能有一個主鍵 2、一張表中都應該有一個id欄位,而且應該把id欄位做成主鍵
create table t17( id int primary key, name char(16), age int, sex char(6) )engine=innodb; #聯合主鍵(不完全相同,但不能為空) create table t19( ip char(15), port int, primary key(ip,port) ); mysql> desc t19; +-------+----------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+----------+------+-----+---------+-------+ | ip | char(15) | NO | PRI | | | | port | int(11) | NO | PRI | 0 | | +-------+----------+------+-----+---------+-------+
10.64 auto_increment
只能給被約束成key的欄位加自增屬性,預設起始位置是1,步長也為1
# primary key auto_increment create table t20( id int primary key auto_increment, name char(16) )engine=innodb; mysql> insert t20(name) values('egon1'); mysql> insert t20(name) values('egon2'); mysql> select * from t20; +----+-------+ | id | name | +----+-------+ | 1 | egon1 | | 2 | egon2 | +----+-------+
10.7 表關係
10.71 多對一(foreign key)
1、把所有數據都存放於一張表的弊端:
-
表的組織結構複雜不清晰
-
浪費空間
-
擴展性極差
2、尋找表與表之間的關係的方法: 舉例:emp表 dep表 步驟一: part1: 1、先站在左表emp的角度 2、去找左表emp的多條記錄能否對應右表dep的一條記錄
part2: 1、站在右表dep的角度 2、去找右表dep的多條記錄能否對應左表emp的一條記錄 3、如何實現? 在emp表中新增一個dep_id欄位,該欄位指向dep表的id欄位
4、foreign key會帶來什麼樣的效果?
約束1:在創建表時,先建被關聯的表dep,才能建關聯表emp
create table dep( id int primary key auto_increment, dep_name char(10), dep_comment char(60) ); mysql> desc dep; +-------------+----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------+----------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | dep_name | char(10) | YES | | NULL | | | dep_comment | char(60) | YES | | NULL | | +-------------+----------+------+-----+---------+----------------+ create table emp( id int primary key auto_increment, name char(16), gender enum('male','female') not null default 'male', dep_id int, foreign key(dep_id) references dep(id) ); mysql> desc emp; +--------+-----------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------+-----------------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | char(16) | YES | | NULL | | | gender | enum('male','female') | NO | | male | | | dep_id | int(11) | YES | MUL | NULL | | +--------+-----------------------+------+-----+---------+----------------+
約束2:在插入記錄時,必須先插被關聯的表dep,才能插關聯表emp
insert into dep(dep_name,dep_comment) values ('sb教學部','sb輔導學生學習,教授python課程'), ('外交部','形象大使'), ('nb技術部','nb技術能力有限部門'); mysql> select * from dep; +----+-------------+-------------------------------------------+ | id | dep_name | dep_comment | +----+-------------+-------------------------------------------+ | 1 | sb教學部 | sb輔導學生學習,教授python課程 | | 2 | 外交部 | 形象大使 | | 3 | nb技術部 | nb技術能力有限部門 | +----+-------------+-------------------------------------------+ insert into emp(name,gender,dep_id) values ('alex','male',1), ('egon','male',2), ('lxx','male',1), ('wxx','male',1), ('wenzhou','female',3); mysql> select * from emp; +----+---------+--------+--------+ | id | name | gender | dep_id | +----+---------+--------+--------+ | 1 | alex | male | 1 | | 2 | egon | male | 2 | | 3 | lxx | male | 1 | | 4 | wxx | male | 1 | | 5 | wenzhou | female | 3 | +----+---------+--------+--------+
約束3:更新與刪除都需要考慮到關聯與被關聯的關係(不能直接改變dep表的id) 解決方案:
1、先刪除關聯表emp,再刪除被關聯表dep,準備重建 mysql> drop table emp; mysql> drop table dep; 2、重建:新增功能:同步更新,同步刪除 create table dep( #先建被參照的表 id int primary key auto_increment, dep_name char(10), dep_comment char(60)); create table emp( id int primary key auto_increment, name char(16), gender enum('male','female') not null default 'male', dep_id int, foreign key(dep_id) references dep(id) on update cascade on delete cascade); insert into dep(dep_name,dep_comment) values ('sb教學部','sb輔導學生學習,教授python課程'), ('外交部','形象大使'), ('nb技術部','nb技術能力有限部門'); mysql> select * from dep; +----+------------------+------------------------------ | id | dep_name | dep_comment | +----+------------------+------------------------------ | 1 | sb教學部 | sb輔導學生學習,教授python課程 | | 2 | 外交部 | 形象大使 | | 3 | nb技術部 | nb技術能力有限部門 | +----+------------------+------------------------------- insert into emp(name,gender,dep_id) values ('alex','male',1), ('egon','male',2), ('lxx','male',1), ('wxx','male',1), ('wenzhou','female',3); mysql> select * from emp; +----+------------------+--------+--------+ | id | name | gender | dep_id | +----+------------------+--------+--------+ | 1 | alex | male | 1 | | 2 | egon | male | 2 | | 3 | lxx | male | 1 | | 4 | wxx | male | 1 | | 5 | wenzhou | female | 3 | +----+------------------+--------+--------+ # 同步刪除 mysql> delete from dep where id=1; mysql> select * from dep; +----+------------------+------------------ | id | dep_name | dep_comment | +----+------------------+------------------ | 2 | 外交部 | 形象大使 | | 3 | nb技術部 | nb技術能力有限部門 | +----+------------------+------------------ mysql> select * from emp; +----+------------------+--------+--------+ | id | name | gender | dep_id | +----+------------------+--------+--------+ | 2 | egon | male | 2 | | 5 | wenzhou | female | 3 | +----+------------------+--------+--------+ #同步更新 mysql> update dep set id=200 where id =2; mysql> select * from dep; +-----+------------------+---------------- | id | dep_name | dep_comment | +-----+------------------+---------------- | 3 | nb技術部 | nb技術能力有限部| | 200 | 外交部 | 形象大使 | +-----+------------------+---------------- mysql> select * from emp; +----+------------------+--------+--------+ | id | name | gender | dep_id | +----+------------------+--------+--------+ | 2 | egon | male | 200 | | 5 | wenzhou | female | 3 | +----+------------------+--------+--------+View Code
10.72 多對多(foreign key)
1、什麼是多對多 兩張表之間是一個雙向的多對一關係,稱之為多對多 2、如何實現? 建立第三張表,該表中有一個欄位是fk左表的id,還有一個欄位是fk右表的id
create table author( id int primary key auto_increment, name char(16)); create table book( id int primary key auto_increment, bname char(16), price int); insert into author(name) values ('egon'), ('alex'), ('wxx'); mysql> select * from author; +----+------+ | id | name | +----+------+ | 1 | egon | | 2 | alex | | 3 | wxx | +----+------+ insert into book(bname,price) values ('python從入門到入土',200), ('葵花寶典切割到精通',800), ('九陰真經',500), ('九陽神功',100); mysql> select * from book; +----+-----------------------------+-------+ | id | bname | price | +----+-----------------------------+-------+ | 1 | python從入門到入土 | 200 | | 2 | 葵花寶典切割到精通 | 800 | | 3 | 九陰真經 | 500 | | 4 | 九陽神功 | 100 | +----+-----------------------------+-------+ create table author2book( id int primary key auto_increment, author_id int, book_id int, foreign key(author_id) references author(id) on update cascade on delete cascade, foreign key(book_id) references book(id) on update cascade on delete cascade); insert into author2book(author_id,book_id) values (1,3),(1,4),(2,2),(2,4),(3,