MySQL 第四天
回顧
列屬性: 主鍵, 自增長, 唯一鍵
? ?
關系: 一對一,一對多和多對多
范式: 三層范式
1NF: 字段設計必須符合原子性
2NF: 不存在部分依賴(沒有復合主鍵)
3NF: 不存在傳遞依賴(實體單獨建表)
逆規范化: 效率與磁盤空間的博弈
? ?
高級數據操作
新增操作: 主鍵沖突(更新和替換), 蠕蟲復制
更新操作: 限制更新數量: limit
刪除操作: 限制刪除數量: limit, 清空表(truncate)
查詢操作: select選項, 字段別名, 數據源(單表,多表和子查詢[別名]),where子句(條件判斷:從磁盤),groupby子句(分組統計,統計函數,分組排序, 多字段分組, 回溯統計), having子句(判斷結果, 針對分組統計結果), orderby子句(排序, 多字段排序),limit子句(限制記錄數,分頁)
需求: 查詢出所有的學生,而且要求顯示學生所在的班級信息.
? ?
連接查詢
連接查詢: 將多張表(可以大于2張)進行記錄的連接(按照某個指定的條件進行數據拼接): 最終結果是: 記錄數有可能變化, 字段數一定會增加(至少兩張表的合并)
? ?
連接查詢的意義: 在用戶查看數據的時候,需要顯示的數據來自多張表.
? ?
連接查詢: join, 使用方式: 左表 join 右表
左表: 在join關鍵字左邊的表
右表: 在join關鍵字右邊的表
? ?
連接查詢分類
SQL中將連接查詢分成四類: 內連接,外連接,自然連接和交叉連接
? ?
? ?
交叉連接
交叉連接: cross join, 從一張表中循環取出每一條記錄, 每條記錄都去另外一張表進行匹配: 匹配一定保留(沒有條件匹配), 而連接本身字段就會增加(保留),最終形成的結果叫做: 笛卡爾積.
? ?
基本語法: 左表 cross join 右表; ===== from 左表,右表;
? ?
笛卡爾積沒有意義: 應該盡量避免(交叉連接沒用)
交叉連接存在的價值: 保證連接這種結構的完整性
? ?
內連接
內連接: [inner] join, 從左表中取出每一條記錄,去右表中與所有的記錄進行匹配: 匹配必須是某個條件在左表中與右表中相同最終才會保留結果,否則不保留.
? ?
基本語法
左表 [inner] join 右表 on 左表.字段 = 右表.字段; on表示連接條件: 條件字段就是代表相同的業務含義(如my_student.c_id和my_class.id)
? ?
字段別名以及表別名的使用: 在查詢數據的時候,不同表有同名字段,這個時候需要加上表名才能區分, 而表名太長, 通常可以使用別名.
? ?
內連接可以沒有連接條件: 沒有on之后的內容,這個時候系統會保留所有結果(笛卡爾積)
? ?
內連接還可以使用where代替on關鍵字(where沒有on效率高)
? ?
外連接
外連接: outer join, 以某張表為主,取出里面的所有記錄, 然后每條與另外一張表進行連接: 不管能不能匹配上條件,最終都會保留: 能匹配正確保留; 不能匹配,其他表的字段都置空NULL.
? ?
外連接分為兩種: 是以某張表為主: 有主表
Left join: 左外連接(左連接), 以左表為主表
Right join: 右外連接(右連接), 以右表為主表
? ?
基本語法: 左表 left/right join 右表 on 左表.字段 = 右表.字段;
? ?
左連接
? ?
右連接
? ?
雖然左連接和右連接有主表差異, 但是顯示的結果: 左表的數據在左邊,右表數據在右邊.
? ?
左連接和右連接可以互轉.
? ?
自然連接
自然連接: natural join, 自然連接, 就是自動匹配連接條件: 系統以字段名字作為匹配模式(同名字段就作為條件, 多個同名字段都作為條件).
? ?
自然連接: 可以分為自然內連接和自然外連接.
? ?
自然內連接: 左表 natural join 右表;
? ?
自然外連接: 左表 natural left/right join 右表;
? ?
? ?
其實, 內連接和外連接都可以模擬自然連接: 使用同名字段,合并字段
左表 left/right/inner join 右表 using(字段名); -- 使用同名字段作為連接條件: 自動合并條件
? ?
多表連接: A表 inner join B表 on 條件 left join C表 on條件 ...
執行順序: A表內連接B表,得到一個二維表, 左連接C表形成二維表...
? ?
? ?
PHP操作mysql
事實上: PHP本身不能操作mysql, 但是PHP有擴展可以實現操作mysql: PHP借助擴展來實現操作mysql.
? ?
PHP操作mysql的擴展還挺多: mysql, mysqli和PDO擴展.
? ?
Mysql擴展: 純面向過程, 里面都是函數,加載擴展后可以調用函數.(當前只能使用面向過程)
Mysqli擴展: 面向過程+面向對象,里面有函數也有類, 加載擴展后可以選擇調用函數或者調用類操作.
PDO: 純面向對象,只有類, 加載后只能調用類.
? ?
Mysql擴展在搭建服務器的時候就已經加載開啟.不再進行擴展加載.
? ?
PHP操作mysql
當PHP來對mysql進行操作之后: PHP的角色是mysql的一個客戶端.
? ?
客戶端操作服務端有必要的流程
數據庫連接資源 Mysql_connect(服務器地址包含端口, 用戶名, 用戶密碼);
? ?
默認的: mysql_connect會產生一個連接資源,即便是重新連接,也會返回原有的連接資源.
? ?
如果真的想產生多一個連接: 是新的,可以在mysql_connect函數的第四個參數控制: true
? ?
其實,根本不需要多個連接: 嚴重的資源浪費
? ?
Mixed Mysql_query(sql指令);
Boolean結果: SQL指令沒有返回值, 布爾結果只能代表SQL語句沒有語法錯誤, false就代表是SQL語句有語法錯誤: 主增刪改
Resource結果: 結果集資源, SQL指令有結果返回(show, select),結果集永遠為true: 主查詢
? ?
? ?
Mysql_fetch_array: 默認獲取混合數組,有一組關聯,有一組索引.
? ?
當前函數可以實現: 只獲取關聯數組或者索引數組,通過第二個參數限制: MYSQL_BOTH是默認的,MYSQL_ASSOC是關聯數組,MYSQL_NUM是索引數組.
關聯數組獲取: MYSQL_ASSOC
? ?
索引數組獲取:MYSQL_NUM
? ?
Mysql_fetch_assoc: 直接獲取關聯數組
? ?
Mysql_fetch_row: 獲取索引數組
? ?
不管是哪個fetch: 最終如果結果集指針移動到最后,返回都是false
Mysql_data_seek(結果集資源,位置從0開始);
Mysql_close(資源變量);
? ?
? ?
增刪改查
? ?
從計算機的角度出發: 增刪改都屬于寫, 查屬于讀.
? ?
寫操作
連接認證: 不一定連成功, 需要對結果進行判斷: 可以直接使用三目運算(邏輯或)來進行處理, 但是無法獲取錯誤信息. 如果要獲取錯誤信息,那么需要使用mysql提供的獲取錯誤的函數: mysql_errno()獲取錯誤編號, mysql_error()獲取錯誤信息.
? ?
在操作數據庫之前要進行相關初始化: 設置字符集,選擇數據庫
? ?
發現: 其實所有的SQL語句都有可能出錯: 將執行SQL語句,判斷錯誤信息的代碼進行封裝: 封裝成錯誤處理函數.
? ?
任何SQL語句的執行,都應該由my_error自定義函數來執行: 檢查錯誤
? ?
寫操作: 不符合人類的判斷意識: 根據人的需求, 對進行進行分類操作: 增和刪改
新增操作: 通常會獲取當前新增記錄的自增長id: mysql_insert_id(),直接獲取上次新增操作的自增長ID, 如果沒有自增長id獲得0
? ?
刪改操作: 通常都不能直接通過mysql_query的結果true來進行判斷: true不代表執行成功,只代表SQL語句沒有語法錯誤: 通過受影響的行數來判斷是否成功: mysql_affected_rows()獲取上次操作的受影響的行數(新增也有)
? ?
? ?
讀操作
無外乎從數據庫中查出所有數據, 最后在html里面顯示.
? ?
在HTML顯示數據
? ?
? ?
綜合應用
Mysql+PHP進行一個實際案例的綜合應用.(HTML+CSS)
? ?
需求: 學生信息管理系統, 是一個后臺管理系統, 顯示學生的信息(管理:增刪改), 分頁功能. 需要用戶登錄之后才能查看數據信息.
? ?
功能: 登錄功能, 分頁顯示數據功能
? ?
指導方針: 從用戶角度出發, 順著用戶的操作步驟逐步進行.
? ?
登錄功能
? ?
所有的html文件都是放在project/templates/文件夾下: 所有的html文件,瀏覽器都不允許直接訪問, 只允許訪問PHP文件.
? ?
分頁顯示數據功能
用戶登錄之后: 可以直接看到結果.
? ?
? ?
分頁功能
?---------------------------------------------------------------------------------------------------------------------
對應sql腳本:
-- 交叉連接 select * from my_student cross join my_class; -- my_student cross join my_class是數據源 ? -- 內連接 select * from my_student inner join my_class on my_student.c_id = my_class.id; select * from my_student inner join my_class on c_id = my_class.id; select * from my_student inner join my_class on c_id = id; -- 兩張表都有id字段 ? -- 字段和表別名 select s.*,c.name as c_name,c.room from -- 字段別名 my_student as s inner join my_class as c -- 表別名 on s.c_id = c.id; ? ? -- where代替on select s.*,c.name as c_name,c.room from -- 字段別名 my_student as s inner join my_class as c -- 表別名 where s.c_id = c.id; ? -- 左連接 select s.*,c.name as c_name,c.room from my_student as s left join my_class as c -- 左表為主表: 最終記錄數至少不少于左表已有的記錄數 on s.c_id = c.id; ? -- 右連接 select s.*,c.name as c_name,c.room from my_student as s right join my_class as c -- 右表為主表: 最終記錄數至少不少于右表已有的記錄數 on s.c_id = c.id; ? ? select s.*,c.name as c_name,c.room from my_class as c right join my_student as s -- 左表為主表: 最終記錄數至少不少于左表已有的記錄數 on s.c_id = c.id; ? -- 自然內連接 select * from my_student natural join my_class; ? -- 自然左外連接 select * from my_student natural left join my_class; ? -- 外連接模擬自然外連接: using select * from my_student left join my_class using(id); |
? ?
? ?
??
轉載于:https://www.cnblogs.com/Prozhu/p/5763558.html
總結
- 上一篇: css之属性部分
- 下一篇: codeforces 706B B. I