回顧
列屬性:主鍵,自增長,唯一鍵
關(guān)系:一對(duì)一,一對(duì)多和多對(duì)多
范式:三層范式
1NF:字段設(shè)計(jì)必須符合原子性
2NF:不存在部分依賴(沒有復(fù)合主鍵)
3NF:不存在傳遞依賴(實(shí)體類單獨(dú)存在)
逆規(guī)范化:效率與磁盤空間的博弈
高級(jí)的數(shù)據(jù)操作
新增操作:主鍵沖突(更新和替換),蠕蟲復(fù)制
更新操作:限制更新數(shù)量:limit
刪除操作:限制刪除數(shù)量:limit,清空表(truncate)
查詢操作:select選項(xiàng),字段別名,數(shù)據(jù)源(單表,多表和子查詢[表名]),where子句(條件判斷:從磁盤),group by子句(分組統(tǒng)計(jì),統(tǒng)計(jì)
函數(shù),分組排序,多字段分組,回溯統(tǒng)計(jì)),having子句(判斷結(jié)果:針對(duì)分組統(tǒng)計(jì)的結(jié)果進(jìn)行判斷),order by子句(排序,多字段排序),limit
子句(限制記錄數(shù),分頁)
需求:查詢出所有的學(xué)生,而且要求顯示學(xué)生所在的班級(jí)信息
連接查詢
連接查詢:將多張表(可以大于2張)進(jìn)行記錄的連接(按照某個(gè)指定的條件進(jìn)行數(shù)據(jù)拼接),最終的結(jié)果是:記錄數(shù)有可能變化,字段數(shù)一定會(huì)增加(至
少兩張表的合并)
連接查詢的意義:在用戶查看數(shù)據(jù)的時(shí)候,需要顯示的數(shù)據(jù)來自多張表
連接查詢:join,使用方法: 左表 join 右表
左表:在join關(guān)鍵字左邊的表
右表:在join關(guān)鍵字右邊的表
連接查詢分類
SQL中將連接查詢分成四類:內(nèi)連接,外連接,自然連接和交叉連接
交叉連接
交叉連接:cross join,從一張表中循環(huán)取出每一條記錄,每條記錄都去另外一張表進(jìn)行匹配;匹配一定保留(沒有條件匹配),而連接本身字段就會(huì)增加
(保留),最終會(huì)形成的結(jié)果叫做:笛卡爾積
基本語法:左表 cross join 右表; <-----> from 左表, 右表;
笛卡爾積沒有意義:應(yīng)該盡量避免(交叉連接沒用)
交叉連接的價(jià)值:保證連接這種結(jié)構(gòu)的完整性
內(nèi)連接
內(nèi)連接:[inner] join,從左表中取出每一條記錄,去右表中與所有的記錄進(jìn)行匹配:匹配必須是某個(gè)條件在左表中與右表中相同最終結(jié)果才會(huì)保留,否則不保留
基本語法
左表 [inner] join 右表 on 左表.字段 = 右表.字段; on表示連接條件:條件字段就是代表相同的業(yè)務(wù)含義(如my_studnent.c_id和my_class.id)
字段別名以及表別名的使用:在查詢數(shù)據(jù)的時(shí)候,不同表有同名字段,這個(gè)時(shí)候需要加上表名才能區(qū)分,而表名太長,通常可以使用別名
內(nèi)連接可以沒有連接條件:在on之后的內(nèi)容,這個(gè)時(shí)候系統(tǒng)會(huì)自動(dòng)保留所有結(jié)果(笛卡爾積)
內(nèi)連接還可以使用where代替on關(guān)鍵字(where 沒有 on的效率高)
外連接
外連接:outer join,以某張表為主,取出里面的所有記錄,然后每條與另外一張表進(jìn)行連接:不管能不能匹配上條件,最終都會(huì)保留:能匹配,正確保留,不能
匹配,其他表的字段都置空NULL
外連接分為兩種:是以某張表為主:有主表
left join:左外連接(左連接):以左表為主
right join:右外連接(右連接):以右表為主
基本語法:左表 left/right join 右表 on 左表.字段 = 右表.字段;
左連接
右連接
雖然左連接和右連接有主表差異,但是顯示的結(jié)果:左表的數(shù)據(jù)在左邊,右表的數(shù)據(jù)在右邊,左連接和右連接可以互轉(zhuǎn)
自然連接
自然連接:natural join,自然連接,就是自動(dòng)匹配連接條件:系統(tǒng)以字段名作為匹配模式(同名字段就作為條件,多個(gè)同名字段都作為條件)
自然連接:可以分為自然內(nèi)連接和自然外連接
自然內(nèi)連接:左表 natural join 右表;
自然外連接:左表 natural left/right join 右表;
其實(shí),內(nèi)連接和外連接都可以模擬自然連接,使用同名字段,合并字段
左表 left/right/ inner join 右表 using(字段名); -- 使用同名字段作為連接條件:自動(dòng)合并條件
PHP操作mysql
事實(shí)上:PHP本身不能操作mysql,但是PHP有擴(kuò)展可以實(shí)現(xiàn)操作mysql:PHP借助擴(kuò)展來實(shí)現(xiàn)操作mysql
PHP操作mysql的擴(kuò)展包括:mysql,mysqli和PDO擴(kuò)展
mysql擴(kuò)展:純面向過程,里面都是函數(shù),加載擴(kuò)展后可以調(diào)用函數(shù)
mysqli擴(kuò)展:面向過程+面向?qū)ο螅锩嬗泻瘮?shù)也有類,加載后可以選擇調(diào)用函數(shù)或者調(diào)用類操作
PDO:純面向?qū)ο螅挥蓄悾虞d后只能調(diào)用類
PHP操作mysql
當(dāng)PHP來對(duì)mysql進(jìn)行操作之后:PHP的角色是mysql的一個(gè)客戶端
客戶端操作服務(wù)端有必要的流程
- 連接認(rèn)證:連接和認(rèn)證
數(shù)據(jù)庫連接資源 mysql_connect(服務(wù)器地址包含端口,用戶名,用戶名);
默認(rèn)的:mysql_connect會(huì)產(chǎn)生一個(gè)連接資源,即便是重新連接,也會(huì)返回原有的資源連接
如果真的想產(chǎn)生多一個(gè)連接:是新的,可以在mysql_connect函數(shù)的第四個(gè)參數(shù)控制:true
其實(shí),根本不需要多個(gè)連接:嚴(yán)重的資源浪費(fèi)
PHP發(fā)送SQL指令(等待執(zhí)行結(jié)果)
mysql服務(wù)器端接受指令,執(zhí)行指令,返回結(jié)果
PHP接收結(jié)果
mixed mysql_query(sql指令);
bollean結(jié)果:SQL指令沒有返回值,布爾結(jié)果只能代表SQL語句沒有語法錯(cuò)誤,false就代表SQL語句有語法錯(cuò)誤:主要針對(duì)增刪改
resource結(jié)果:結(jié)果集資源,SQL指令有結(jié)果返回(show, select),結(jié)果集永遠(yuǎn)為true:主要針對(duì)查詢
- PHP沒有辦法直接使用結(jié)果集:需要解析結(jié)果集,mysql擴(kuò)展提供了一系列函數(shù):my_fetch系列:任何操作都是指針操作:操作完就會(huì)指針下移
mysql_fetch_array:默認(rèn)獲取混合數(shù)組,有一組關(guān)聯(lián),有一組索引
當(dāng)前函數(shù)可以實(shí)現(xiàn):只獲取關(guān)聯(lián)數(shù)組或者索引數(shù)組,通過第二個(gè)參數(shù)限制:MYSQL_BOTH是默認(rèn)的,MYSQL_ASSOC是關(guān)聯(lián)數(shù)組,MYSQL_NUM是索引數(shù)組
關(guān)聯(lián)數(shù)組獲取:MYSQL_ASSOC
索引數(shù)組獲取:MYSQL_NUM
mysql_fetch_assoc:直接獲取關(guān)聯(lián)數(shù)組
mysql_fetch_row:直接獲取索引數(shù)組
不管是哪個(gè)fetch:最終如果結(jié)果集指針移動(dòng)到最后,返回都是false
- 如果指針已經(jīng)移動(dòng)到最后,那么需要重置指針實(shí)現(xiàn)其他操作
mysql_data_seek(結(jié)果集資源, 位置從0開始);
- 獲取的數(shù)據(jù)往往只有一行:實(shí)際上查多少是為了顯示全部:解析全部:循環(huán)遍歷來實(shí)現(xiàn)
- 釋放資源:mysql資源通常不需要釋放(腳本執(zhí)行周期不會(huì)太長,但是數(shù)據(jù)庫的操作是貫穿整個(gè)腳本的)
mysql_close(資源變量);
增刪改查
從計(jì)算機(jī)的角度出發(fā):增刪改都屬于寫,查屬于讀
寫操作
連接認(rèn)證:不一定成功,需要對(duì)結(jié)果進(jìn)行判斷:可以直接使用三目運(yùn)算(邏輯或)來進(jìn)行處理,但是無法獲取到錯(cuò)誤信息,如果要獲取到錯(cuò)誤信息,那么需要
使用mysql提供的獲取錯(cuò)誤的函數(shù):mysql_errno()獲取錯(cuò)誤編號(hào),mysql_error()獲取錯(cuò)誤信息
在操作數(shù)據(jù)庫之前要進(jìn)行相關(guān)初始化:設(shè)置字符集,選擇數(shù)據(jù)庫
發(fā)現(xiàn)其實(shí)所有的SQL語句都可能出錯(cuò):將執(zhí)行SQL語句,判斷語句錯(cuò)誤信息的代碼進(jìn)行封裝:封裝成錯(cuò)誤處理函數(shù)
任何SQL語句執(zhí)行,都應(yīng)該由my_error自定義函數(shù)來執(zhí)行:檢查錯(cuò)誤
寫操作:不符合人類的判斷意識(shí):根據(jù)人的需求,對(duì)其進(jìn)行分類操作:增和刪改
新增操作:通常會(huì)獲取當(dāng)前新增記錄的自增長id:mysql_insert_id(),直接獲取上次新增操作的自增長ID,如果沒有自增長id獲得0
刪改操作:通常不能通過mysql_query的結(jié)果true來進(jìn)行判斷:true不代表執(zhí)行成功,只代表SQL語句沒有語法錯(cuò)誤:通過受影響的行數(shù)來判斷是
否成功:mysql_affected_row()獲取上次操作的受影響行數(shù)(新增也有)
讀操作
無外乎從數(shù)據(jù)庫中查處所有數(shù)據(jù),最后在html里面顯示
在html里顯示數(shù)據(jù)
綜合應(yīng)用
mysql+PHP進(jìn)行一個(gè)實(shí)際案例的綜合應(yīng)用(HTML+CSS)
需求:學(xué)生信息管理系統(tǒng),是一個(gè)后臺(tái)管理系統(tǒng),顯示學(xué)生的信息(管理:增刪改),分頁功能,需要用戶登錄之后才能查看數(shù)據(jù)信息。
功能:登錄功能,分頁顯示數(shù)據(jù)功能
指導(dǎo)方針:從用戶角度出發(fā),順著用戶的操作步驟逐步進(jìn)行
登錄功能
- 從用戶角度來說:用戶需要看到一個(gè)登錄頁面:登錄表單是HTML文件
所有的HTML文件都是放在project/templates/文件夾下:所有的html文件,瀏覽器都不允許直接訪問,只允許訪問PHP文件
- 給用戶增加一個(gè)可以訪問的連接:是php文件,能夠顯示登錄表單信息
- 用戶會(huì)選擇輸入用戶信息,提交:確定表單提交對(duì)象,/project/templates/login.html
- 用戶在輸入信息之后,就會(huì)選擇提交:提交之后都是由服務(wù)器的login.php進(jìn)行處理:login.php應(yīng)該選擇性進(jìn)行處理:做出不同的響應(yīng)
- 獲取用戶提交的數(shù)據(jù)
- 合法性驗(yàn)證:驗(yàn)證數(shù)據(jù)是否滿足驗(yàn)證的基本條件:用戶名和密碼都不為空
- 存在亂碼,中文問題:header解決
- 用戶在輸入的過程中很有可能輸入了空格且不是真實(shí)需求:所以應(yīng)該獲取用戶信息的時(shí)候就去掉空格:trim
- 合理性驗(yàn)證:合法的數(shù)據(jù)是否最終與數(shù)據(jù)庫的數(shù)據(jù)匹配:搭建數(shù)據(jù)庫環(huán)境
- 操作數(shù)據(jù)庫:進(jìn)入到數(shù)據(jù)庫admin表中,查詢用戶名和密碼對(duì)應(yīng)是否存在,操作數(shù)據(jù)庫的位置很多,都需要進(jìn)行初始化操作:將數(shù)據(jù)庫的初始化操作封裝到
一個(gè)單獨(dú)的文件中:mysql.php
- 在登錄驗(yàn)證用戶信息的時(shí)候,調(diào)用公共數(shù)據(jù)庫文件:然后操作數(shù)據(jù)庫/project/login.php
- 跳轉(zhuǎn)代碼是重復(fù)代碼:封裝成獨(dú)立的函數(shù)來實(shí)現(xiàn):在公共文件夾中創(chuàng)建一個(gè)新的公共文件:public.php
- 任何一個(gè)被用戶請求的php文件都應(yīng)該加載public.php文件
- 在任何需要跳轉(zhuǎn)的地方調(diào)用跳轉(zhuǎn)函數(shù)
- SQL注入問題:用戶通過程序的漏洞(程序直接拼湊用戶輸入的信息到SQL語句),輸入一些特殊字符(引號(hào)’)來改變原來的SQL語句的執(zhí)行機(jī)制:如何
防止?想辦法組織引號(hào):addslashes()增加轉(zhuǎn)義符號(hào)
- 用戶登陸成功,應(yīng)該進(jìn)入后臺(tái)首頁
分頁顯示數(shù)據(jù)功能
用戶登錄之后,可以直接看到結(jié)果
- 增加一個(gè)顯示數(shù)據(jù)的表單
- 首頁是登陸之后跳轉(zhuǎn)過去:跳轉(zhuǎn)到index.php文件
- 獲取數(shù)據(jù),設(shè)計(jì)數(shù)據(jù)庫
- 調(diào)用數(shù)據(jù)庫初始化文件,從數(shù)據(jù)表中獲取所有的學(xué)生信息
- 在模板中顯示所有的數(shù)據(jù)
分頁功能
- 給用戶增加一個(gè)可以點(diǎn)擊的上一頁,下一頁,首頁,末頁的功能
- 確定a鏈接的href對(duì)象,請求對(duì)象是index.php
- 分頁效果:點(diǎn)擊上一頁,應(yīng)該是在當(dāng)前頁的基礎(chǔ)上減掉一頁,如果是首頁應(yīng)該是第一頁:要傳一個(gè)頁碼參數(shù)
- 想辦法取出一些跟分頁相關(guān)的數(shù)據(jù)
- 求出上一頁的頁碼以及下一頁的頁碼
- 獲取總記錄數(shù),求出總頁碼
- 將求出來的數(shù)據(jù)放到對(duì)應(yīng)的頁碼位置