python必坑知識點04
1.關系型和非關系型數據庫區別
關系型:支持常用的sql語句,本質相當于一個二維表模型,表之間可以有關聯、外鍵等
非關系型:可以有多種的狀態的命令,k、v鍵值對等,支持高并發,效率高,可用于集群的分布式均衡負載
2.MySQL數據庫事務特性有哪些?
四大特性:
原子性:不可分割,要么都成功,要么都失敗回滾
一致性:事務執行前后數據完整性一致
隔離性:事務執行中,不受到外界的干擾
持久性:事務執行結束,數據持久到數據庫中
3.通俗地講一下三個范式
范式一:記錄的原子性,不可拆分
范式二:唯一性
范式三:冗余性
為了建立冗余較小、結構合理的數據庫,設計數據庫時必須遵循一定的規則。在關系型數據庫中這種規則就稱為范式。范式是符合某一種設計要求的總結。要想設計一個結構合理的關系型數據庫,必須滿足一定的范式。
在實際開發中最為常見的設計范式有三個:
1.第一范式(確保每列保持原子性)
第一范式是最基本的范式。如果數據庫表中的所有字段值都是不可分解的原子值,就說明該數據庫表滿足了第一范式。
第一范式的合理遵循需要根據系統的實際需求來定。比如某些數據庫系統中需要用到“地址”這個屬性,本來直接將“地址”屬性設計成一個數據庫表的字段就行。但是如果系統經常會訪問“地址”屬性中的“城市”部分,那么就非要將“地址”這個屬性重新拆分為省份、城市、詳細地址等多個部分進行存儲,這樣在對地址中某一部分操作的時候將非常方便。這樣設計才算滿足了數據庫的第一范式,如下表所示。
上表所示的用戶信息遵循了第一范式的要求,這樣在對用戶使用城市進行分類的時候就非常方便,也提高了數據庫的性能。
2.第二范式(確保表中的每列都和主鍵相關)
第二范式在第一范式的基礎之上更進一層。第二范式需要確保數據庫表中的每一列都和主鍵相關,而不能只與主鍵的某一部分相關(主要針對聯合主鍵而言)。也就是說在一個數據庫表中,一個表中只能保存一種數據,不可以把多種數據保存在同一張數據庫表中。
比如要設計一個訂單信息表,因為訂單中可能會有多種商品,所以要將訂單編號和商品編號作為數據庫表的聯合主鍵,如下表所示。
訂單信息表
這樣就產生一個問題:這個表中是以訂單編號和商品編號作為聯合主鍵。這樣在該表中商品名稱、單位、商品價格等信息不與該表的主鍵相關,而僅僅是與商品編號相關。所以在這里違反了第二范式的設計原則。
而如果把這個訂單信息表進行拆分,把商品信息分離到另一個表中,把訂單項目表也分離到另一個表中,就非常完美了。如下所示。
這樣設計,在很大程度上減小了數據庫的冗余。如果要獲取訂單的商品信息,使用商品編號到商品信息表中查詢即可。
3.第三范式(確保每列都和主鍵列直接相關,而不是間接相關)
第三范式需要確保數據表中的每一列數據都和主鍵直接相關,而不能間接相關。
比如在設計一個訂單數據表的時候,可以將客戶編號作為一個外鍵和訂單表建立相應的關系。而不可以在訂單表中添加關于客戶其它信息(比如姓名、所屬公司等)的字段。如下面這兩個表所示的設計就是一個滿足第三范式的數據庫表。
這樣在查詢訂單信息的時候,就可以使用客戶編號來引用客戶信息表中的記錄,也不必在訂單信息表中多次輸入客戶信息的內容,減小了數據冗余。
4.主鍵、外鍵和索引的區別
(1)概念
主鍵:唯一標識一條記錄,不能有重復,不允許為空。
外鍵:表的外鍵是另一表的主鍵,外鍵可以有重復,可以是空值。
索引:該字段沒有重復值,但可以有一個空值。
(2)作用
主鍵:用來保證數據完整性
外鍵:用于和其他表建立聯系用的
索引:提高查詢排序的速度
(3)個數
主鍵:主鍵只能有一個
外鍵:一個表可以有多個外鍵
索引:一個表可以有多個唯一索引
5.commit和rollback的理解
commit:sql執行成功,數據提交到數據庫中
rollback:sql執行失敗,不會提交到數據庫,數據回滾到執行sql之前
6.SQL語句查詢優化有哪些方法
建立索引并命中索引,在查詢的時候,要盡量讓數據庫引擎使用索引。加入explain執行計劃
1.盡量避免使用select *
2.盡量避免使用!=
3.盡量避免使用or
優化方式:可以用union代替or。如下:
SELECT * FROM t WHERE username="hkw"
UNION
SELECT * FROM t WHERE nickname="jon"
4.盡量避免使用in和not in
優化方式:如果是連續數值,可以用between代替
如果是子查詢,可以用exists代替。如下:
SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t2 WHERE t1.username = t2.username)
5.盡量避免在字段開頭模糊查詢
SELECT * FROM t WHERE username LIKE '%li%'
優化方式:盡量在字段后面使用模糊查詢。如下:
SELECT * FROM t WHERE username LIKE 'li%'
6.盡量避免進行null值的判斷
SELECT * FROM t WHERE score IS NULL
優化方式:可以給字段添加默認值0,對0值進行判斷。如下:
SELECT * FROM t WHERE score = 0
7.盡量避免在where條件中等號的左側進行表達式、函數操作
SELECT * FROM t2 WHERE score/10 = 9
SELECT * FROM t2 WHERE SUBSTR(username,1,2) = 'li'
優化方式:可以將表達式、函數操作移動到等號右側。如下:
SELECT * FROM t2 WHERE score = 10*9
SELECT * FROM t2 WHERE username LIKE 'li%'
7.SQL
學生表:student(學號,學生姓名,出生年月,性別)
成績表:score(主鍵,學號,課程號,成績)
課程表:course(課程號,課程名稱,教師號)
教師表:teacher(教師號,教師姓名)
(1)學生表和成績表的建表語句(根據需求定義字段類型,外鍵約束等)
create table student(
sid int not null primary key auto_increment,
sname varchar(32) not null,
ctime datetime not null,
gender varchar(8) not null
);
create table score(
id int not null primary key auto_increment,
student_id int,
course_id int,
num int,
constraint fk_score_student foreign (student_id) references student(sid),
constraint fk_score_course foreign (course_id) references course(cid)
);
create table course(
cid int not null primary key auto_increment,
cname varchar(32) not null,
teacher_id int,
constraint fk_course_teacher foreign (teacher_id) references teacher(tid)
);
create table teacher(
tid int not null primary key auto_increment,
tname varchar(32)
);
(2)查姓王的學生名單
select * from student where sname like "王%";
(3)查男同學年齡從小到大排列,第6到第10位同學的所有信息(學生表信息)
select * from student where gender = "F" order by ctime asc;
(4)查姓張老師的個數
select count(*) from teacher where tname like "張%";
(5)查詢數學課(課程號001)平均成績
select avg(score.num) from score
left join course on score.course_id=course.cid
where
course.cid=001
select course_id, avg(num) from score group by course_id having course_id=1;
(6)查每門課程選課人數
select count(*) from score
left join course on score.course_id=course.cid
group by
score.course_cid
select course_id,count(student_id) from score group by course_id;
(7)查各科成績最高和最低分
select max(num),min(num) from score
left join course on score.course_id=course.cid
group by course_id
select course_id, min(num), max(num) from score group by course_id;
(8)查詢課程成績小于60分學生的學號、姓名
select student.sid,student.sname from score
left join course on score.course_id=course.cid
left join student on score.student_id=student.sid
where
score.num < 60
group by
course.cid
select * from score inner join student on score.student_id=student.sid where score.num>80;

浙公網安備 33010602011771號