MySQL索引、數(shù)據(jù)庫設(shè)計(jì)、事務(wù)與視圖使用最佳實(shí)踐
前言
在日常的后端開發(fā)中,MySQL 作為一款經(jīng)典的關(guān)系型數(shù)據(jù)庫,是我們數(shù)據(jù)存儲(chǔ)和管理的核心工具。想要讓 MySQL 發(fā)揮出最優(yōu)性能,同時(shí)保證數(shù)據(jù)的完整性、一致性和安全性,就必須深入掌握索引、數(shù)據(jù)庫設(shè)計(jì)、事務(wù)和視圖這些核心知識(shí)點(diǎn)。本文將結(jié)合實(shí)戰(zhàn)場(chǎng)景,詳細(xì)拆解這四大核心模塊的使用邏輯與最佳實(shí)踐。
一、索引:提升查詢效率的 “加速器”
索引是 MySQL 優(yōu)化查詢性能的關(guān)鍵手段,其本質(zhì)是一種特殊的數(shù)據(jù)結(jié)構(gòu)(如 B + 樹),能夠幫助數(shù)據(jù)庫快速定位到目標(biāo)數(shù)據(jù),避免全表掃描帶來的性能損耗。
1. 索引的核心類型
(1)普通索引
最基礎(chǔ)的索引類型,無唯一性約束,僅用于加速查詢。
- 創(chuàng)建方式:
-- 直接創(chuàng)建 CREATE INDEX idx_username ON user (username); -- 修改表結(jié)構(gòu)添加 ALTER TABLE user ADD INDEX idx_username (username); -- 創(chuàng)建表時(shí)指定 CREATE TABLE user ( id INT NOT NULL, username VARCHAR(16) NOT NULL, INDEX idx_username (username) );
- 刪除方式:
DROP INDEX idx_username ON user;
(2)唯一索引
索引列的值必須唯一(允許 NULL 值),適用于需要保證字段唯一性的場(chǎng)景(如手機(jī)號(hào)、郵箱)。
-- 創(chuàng)建唯一索引 CREATE UNIQUE INDEX idx_phone ON user (phone); -- 修改表結(jié)構(gòu)添加 ALTER TABLE user ADD UNIQUE idx_phone (phone);
(3)主鍵索引
特殊的唯一索引,默認(rèn)非空,是表中記錄的唯一標(biāo)識(shí),一張表只能有一個(gè)主鍵索引。
-- 創(chuàng)建表時(shí)指定主鍵 CREATE TABLE user ( id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, username VARCHAR(16) NOT NULL ); -- 修改表添加主鍵 ALTER TABLE user MODIFY id INT NOT NULL; ALTER TABLE user ADD PRIMARY KEY (id); -- 刪除主鍵 ALTER TABLE user DROP PRIMARY KEY;
2. 索引使用的注意事項(xiàng)
- 索引并非越多越好:過多的索引會(huì)增加 INSERT、UPDATE、DELETE 的開銷(因?yàn)樗饕枰礁拢?/span>
- 適合建索引的場(chǎng)景:查詢頻繁的字段、WHERE 條件常用的字段、JOIN 關(guān)聯(lián)的字段。
- 不適合建索引的場(chǎng)景:數(shù)據(jù)量小的表、頻繁更新的字段、重復(fù)率高的字段(如性別)。
- 查看索引信息:SHOW INDEX FROM user
;
二、數(shù)據(jù)庫設(shè)計(jì):遵循范式,兼顧性能
數(shù)據(jù)庫設(shè)計(jì)的核心目標(biāo)是保證數(shù)據(jù)的完整性和減少冗余,同時(shí)兼顧查詢性能。業(yè)界主流的設(shè)計(jì)規(guī)范是 “三大范式”,但實(shí)際開發(fā)中需靈活調(diào)整,避免過度設(shè)計(jì)。
1. 三大范式核心原則
(1)第一范式(原子性)
每一列的值必須是不可拆分的原子值。例如 “地址” 字段,若業(yè)務(wù)需要按 “省份、城市、詳細(xì)地址” 查詢,就不能直接存為 “安徽省合肥市廬陽區(qū) XX 路”,而應(yīng)拆分為province、city、detail_address三個(gè)字段。
(2)第二范式(唯一性)
在第一范式基礎(chǔ)上,確保表中的每一列都和主鍵完全相關(guān),而非僅和主鍵的一部分相關(guān)(針對(duì)聯(lián)合主鍵)。例如訂單表,若以 “訂單編號(hào) + 商品編號(hào)” 為聯(lián)合主鍵,就不能在訂單表中存儲(chǔ) “商品名稱、商品單價(jià)”(這些僅和商品編號(hào)相關(guān)),應(yīng)拆分出商品表,通過外鍵關(guān)聯(lián)。
(3)第三范式(直接相關(guān)性)
在第二范式基礎(chǔ)上,確保每一列都和主鍵直接相關(guān),而非間接相關(guān)。例如訂單表中,只需存儲(chǔ) “用戶 ID”(關(guān)聯(lián)用戶表),而非直接存儲(chǔ) “用戶名、用戶手機(jī)號(hào)”(這些屬于用戶表的屬性)。
2. 多表關(guān)系設(shè)計(jì)
實(shí)際業(yè)務(wù)中,表與表的關(guān)系主要分為三種:
- 一對(duì)多(如部門和員工):在 “多” 的一方(員工表)添加外鍵,指向 “一” 的一方(部門表)的主鍵。
- 多對(duì)多(如學(xué)生和課程):需創(chuàng)建中間表,包含兩個(gè)外鍵,分別指向兩張主表的主鍵。
- 一對(duì)一(如人和身份證):在任意一方添加唯一外鍵,指向另一方的主鍵。
3. 設(shè)計(jì)權(quán)衡:范式與冗余
嚴(yán)格遵循第三范式會(huì)減少數(shù)據(jù)冗余,但可能導(dǎo)致多表關(guān)聯(lián)查詢,降低性能。實(shí)際開發(fā)中可適當(dāng) “反范式”:例如在訂單表中冗余 “用戶名”,避免每次查詢都關(guān)聯(lián)用戶表,以空間換時(shí)間。
三、事務(wù):保證數(shù)據(jù)一致性的 “守護(hù)神”
事務(wù)是一組不可分割的數(shù)據(jù)庫操作,要么全部成功,要么全部失敗,是保證數(shù)據(jù)一致性的核心機(jī)制,尤其適用于轉(zhuǎn)賬、下單等關(guān)鍵業(yè)務(wù)場(chǎng)景。
1. 事務(wù)的四大特性(ACID)
- 原子性(Atomicity):事務(wù)中的所有操作要么全成,要么全回滾,無中間狀態(tài)。
- 一致性(Consistency):事務(wù)執(zhí)行前后,數(shù)據(jù)庫的完整性約束不變(如轉(zhuǎn)賬前后,雙方總金額不變)。
- 隔離性(Isolation):多個(gè)并發(fā)事務(wù)之間相互隔離,互不干擾。
- 持久性(Durability):事務(wù)提交后,修改永久生效,即使數(shù)據(jù)庫崩潰也不會(huì)丟失。
2. 事務(wù)的基本操作
MySQL 默認(rèn)自動(dòng)提交事務(wù)(一條 DML 語句即一個(gè)事務(wù)),可手動(dòng)控制事務(wù):
-- 創(chuàng)建賬戶表
CREATE TABLE account (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(10),
balance DOUBLE
);
INSERT INTO account(name, balance) VALUES ('張三', 1000), ('李四', 1000);
-- 開啟事務(wù)
START TRANSACTION;
-- 張三給李四轉(zhuǎn)賬500元
UPDATE account SET balance = balance - 500 WHERE name = '張三';
UPDATE account SET balance = balance + 500 WHERE name = '李四';
-- 無異常則提交事務(wù)
COMMIT;
-- 有異常則回滾
-- ROLLBACK;
3. 事務(wù)隔離級(jí)別
多個(gè)事務(wù)并發(fā)操作時(shí),可能出現(xiàn)臟讀、不可重復(fù)讀、幻讀等問題,可通過設(shè)置隔離級(jí)別解決:
- READ UNCOMMITTED(讀未提交):最低級(jí)別,允許讀取未提交的數(shù)據(jù),可能出現(xiàn)臟讀。
- READ COMMITTED(讀已提交):避免臟讀,只能讀取已提交的數(shù)據(jù)(Oracle 默認(rèn)級(jí)別)。
- REPEATABLE READ(可重復(fù)讀):避免臟讀、不可重復(fù)讀(MySQL 默認(rèn)級(jí)別)。
- SERIALIZABLE(串行化):最高級(jí)別,避免所有問題,但性能最差,相當(dāng)于單線程執(zhí)行。
查看 / 設(shè)置隔離級(jí)別:
-- 查看隔離級(jí)別 SELECT @@tx_isolation; -- 設(shè)置全局隔離級(jí)別 SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
四、視圖:簡(jiǎn)化查詢,保障安全的 “虛擬表”
視圖是基于 SQL 查詢結(jié)果的虛擬表,不存儲(chǔ)實(shí)際數(shù)據(jù),僅保存查詢邏輯,可簡(jiǎn)化復(fù)雜查詢、隱藏敏感數(shù)據(jù),提升數(shù)據(jù)訪問的安全性和便捷性。
1. 視圖的創(chuàng)建與使用
-- 創(chuàng)建視圖:查詢員工姓名、部門名稱(關(guān)聯(lián)員工表和部門表) CREATE VIEW v_emp_dept AS SELECT emp.name, dept.name AS dept_name FROM emp JOIN dept ON emp.dept_id = dept.id; -- 查詢視圖(和查詢普通表一致) SELECT * FROM v_emp_dept; -- 修改視圖 ALTER VIEW v_emp_dept AS SELECT emp.name, emp.salary, dept.name AS dept_name FROM emp JOIN dept ON emp.dept_id = dept.id; -- 刪除視圖 DROP VIEW v_emp_dept;
2. 視圖的核心價(jià)值
- 簡(jiǎn)化復(fù)雜查詢:將多表關(guān)聯(lián)、聚合等復(fù)雜邏輯封裝到視圖中,用戶只需查詢視圖即可。
- 數(shù)據(jù)安全:可隱藏敏感字段(如密碼、手機(jī)號(hào)),僅暴露必要數(shù)據(jù)給用戶。
- 數(shù)據(jù)獨(dú)立:源表結(jié)構(gòu)變化時(shí),可通過修改視圖適配,不影響前端查詢邏輯。
3. 視圖的注意事項(xiàng)
視圖并非萬能,以下場(chǎng)景視圖不可更新(INSERT/UPDATE/DELETE):
- 包含聚合函數(shù)(SUM/COUNT/AVG)、DISTINCT、GROUP BY、HAVING、LIMIT;
- 包含 UNION、子查詢;
- 多表關(guān)聯(lián)的視圖。
實(shí)際開發(fā)中,視圖主要用于查詢,不建議通過視圖修改數(shù)據(jù)。
總結(jié)
MySQL 的索引、數(shù)據(jù)庫設(shè)計(jì)、事務(wù)和視圖是相輔相成的核心知識(shí)點(diǎn):
- 索引是性能優(yōu)化的核心,需結(jié)合業(yè)務(wù)場(chǎng)景合理創(chuàng)建;
- 數(shù)據(jù)庫設(shè)計(jì)需遵循范式,同時(shí)兼顧性能,靈活取舍冗余;
- 事務(wù)是數(shù)據(jù)一致性的保障,需掌握 ACID 特性和隔離級(jí)別;
- 視圖是簡(jiǎn)化查詢、保障安全的工具,適合封裝復(fù)雜查詢邏輯。
在實(shí)際開發(fā)中,需結(jié)合業(yè)務(wù)場(chǎng)景靈活運(yùn)用這些知識(shí)點(diǎn),既保證數(shù)據(jù)的完整性和安全性,又能讓數(shù)據(jù)庫發(fā)揮出最優(yōu)性能。
到此這篇關(guān)于MySQL索引、數(shù)據(jù)庫設(shè)計(jì)、事務(wù)與視圖使用的文章就介紹到這了,更多相關(guān)MySQL索引、數(shù)據(jù)庫設(shè)計(jì)、事務(wù)與視圖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL服務(wù)無法啟動(dòng)且服務(wù)沒有報(bào)告任何錯(cuò)誤的解決辦法
在啟動(dòng)項(xiàng)目時(shí),發(fā)現(xiàn)昨天能夠跑的項(xiàng)目今天跑不了了,一看原來是mysql數(shù)據(jù)庫出現(xiàn)了問題,下面這篇文章主要給大家介紹了關(guān)于MySQL服務(wù)無法啟動(dòng)且服務(wù)沒有報(bào)告任何錯(cuò)誤的解決辦法,需要的朋友可以參考下2023-05-05
MySQL表的CURD操作(數(shù)據(jù)的增刪改查)
數(shù)據(jù)庫本質(zhì)上是一個(gè)文件系統(tǒng),通過標(biāo)準(zhǔn)的SQL語句對(duì)數(shù)據(jù)進(jìn)行CURD操作,下面這篇文章主要給大家介紹了關(guān)于MySQL表的CURD操作的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02
GDB調(diào)試Mysql實(shí)戰(zhàn)之源碼編譯安裝
今天小編就為大家分享一篇關(guān)于GDB調(diào)試Mysql實(shí)戰(zhàn)之源碼編譯安裝,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-02-02
MySQL中表復(fù)制:create table like 與 create table as select
這篇文章主要介紹了MySQL中表復(fù)制:create table like 與 create table as select,需要的朋友可以參考下2014-12-12

