一、 三大范式, 設(shè)計(jì)數(shù)據(jù)數(shù)據(jù)庫(kù)的一個(gè)原則
1. 對(duì)于屬性(字段)必須是原子性的,不可再進(jìn)行分割
2. 對(duì)于記錄的唯一性,要求記錄有唯一標(biāo)識(shí),
? ? 數(shù)據(jù)表中都要求主鍵,而且主鍵盡量不要是業(yè)務(wù)字段,單獨(dú)拿個(gè)字段來(lái)做主鍵
? ? 字段與主鍵要有直接關(guān)系,不是間接關(guān)系, 確保一張表中只能存儲(chǔ)一種類型的數(shù)據(jù),不能存儲(chǔ)多種
3. 對(duì)于字段的冗余性,要求任何字段不能由其他字段派生過(guò)來(lái),要求字段沒(méi)有冗余性
二、外鍵
? ?當(dāng)我們進(jìn)行表關(guān)聯(lián)的時(shí)候,我們可以通過(guò)外鍵約束一下
? 1. 創(chuàng)建表的時(shí)候直接添加
?? Create table 表名(字段 類型,字段 類型,..., constraint [外鍵名稱] foreign key(外鍵字段) references 父表(主鍵字段))
?? create table stu(id int primary key auto_increment, name varchar(20), card_id varchar(10),clazz_id int,constraint fk_clazz_id_id foreign key(clazz_id) references clazz(id));
? 2. 通過(guò)alert進(jìn)行修改 (外鍵起名要有一個(gè)命名規(guī)則)
?? Alter table 表名 add [constraint 外鍵名字] foreign key(外鍵字段) references 父表(主鍵字段);
?? alter table stu add constraint fk_clazz_id_id foreign key(clazz_id) references clazz(id);
? ?3. 刪除外鍵
?? alter table [表名] drop foreign key [外鍵名稱];
?? alter table stu drop foreign key fk_clazz_id_id;
? 4. 查詢外鍵
?? show create table [表名]
? 5. 級(jí)聯(lián)操作 (級(jí)聯(lián)更新,級(jí)聯(lián)刪除)
? ? ?級(jí)聯(lián)更新 , 當(dāng)父表主鍵發(fā)生變化變化的時(shí)候,從表中外鍵也跟著更新
?? alter table stu add constraint fk_clazz_id_id foreign key(clazz_id) references clazz(id) on update cascade;
? ? ?級(jí)聯(lián)刪除 ,當(dāng)父表中記錄被刪除時(shí)候,字表外鍵相關(guān)的記錄全部被刪除
? ?? alter table stu add constraint fk_clazz_id_id foreign key(clazz_id) references clazz(id) on delete cascade;
? ? ?級(jí)聯(lián)更新和級(jí)聯(lián)刪除可以一起使用,默認(rèn)情況下不帶級(jí)聯(lián)更新和級(jí)聯(lián)刪除的
6. 表連接查詢
?? 查詢出表中所有的記錄? ? ? ? select * from stu, clazz (笛卡爾積 3*3=9行記錄)?
?? 添加關(guān)聯(lián)條件(不使用)? ? ? select * from stu, clazz where stu.clazz_id = clazz.id
?? 連接查詢
? ? ?? 內(nèi)連接? inner join?? (on 是關(guān)聯(lián)條件)?? 兩張表中符合條件的交集
? ? ?? 左連接? left join? 把左表中內(nèi)容都列出來(lái),右表有匹配的就匹配,沒(méi)有匹配的直接為空
? ? ?? 右連接? right join 把右表內(nèi)容都列出來(lái),左表中有匹配的就匹配,沒(méi)有匹配的直接為空
7.子查詢
一個(gè)查詢的結(jié)果是另外一個(gè)查詢的條件
select name from clazz where id in (select clazz_id from stu where name = 'zhangsan');
8.別名(as)
?通過(guò)as 可以給表起別名, 也可以給字段起別名
select s.name as sname, c.name as cname, c.number cnumber from stu as s inner join clazz as c on s.clazz_id = c.id;
?as 可以省略掉
select s.name sname, c.name cname, c.number cnumber from stu s inner join clazz c on s.clazz_id = c.id.
# 學(xué)生表(姓名,年齡,性別)
? create table stu2 (id int primary key auto_increment,name varchar(20),age tinyint, gender char(1));
? insert into stu2(name,age,gender) value ('wang',20,'m'),('li',19,'m'),('h',16,'m'),('h',20,'g'), ('j',19,'g'),('a',19,'g'),('q',19,'g'),('z',16,'g');
? # 1.查詢出男生有多少人,女生有多少個(gè)人
? select gender, count(gender) gcount from stu2? group by gender;
? # 2. 查詢出18歲以上的男生有多少人,18歲以上的女生有多少人 (年齡大于18歲) (where 分組之前執(zhí)行過(guò)濾)
? select gender ,count(gender) gcount from stu2 where age > 18 group by gender;
? # 3. 查詢出18歲以上的男生,人數(shù)大于3個(gè)的性別才加入統(tǒng)計(jì)(having 分組出結(jié)果之后,過(guò)濾結(jié)果)
? select gender ,count(gender) gcount from stu2 where age > 18 group by gender having gcount > 3;