Java之MySQL

數據庫引擎 InnoDB(默認) MYISAM

MYISAM INNODB
事物支持 不支持 支持
數據行鎖定 不支持 支持
外鍵約束 不支持 支持
全文索引 支持 不支持
表空間大小 較小 較大 約爲2倍

常規使用操作:

  • MYISAM 節約空間,速度較快
  • INNODB 安全性好,事務的處理,多表多用戶操作

在物理空間存在的位置:
所有的數據庫文件都存在data目錄下,本質還是文件的存儲,一個文件夾對應一個數據庫

MYSQL引擎在物理文件上的區別:

  • InnoDB在數據庫表中只有一個*.frm文件
  • MYISAM對應文件
    • *.frm 表結構的定義文件
    • *.MYD 數據文件
    • *.MYI 索引文件

修改表的字段
change用來字段重命名,不能修改字段類型和約束;
modify不用來字段重命名,只能修改字段類型和約束
ALTER TABLE student MODIFY age VARCHER(11) --修改約束
ALTER TABLE student CHANGE age newAge INT(1) --字段重命名

刪除表的字段
ALTER TABLE student DROP age

增加表的字段
ALTER TABLE student ADD age INT(1)

MySQL數據管理

外鍵

物理外鍵 CONSTRAINT不建議使用

最佳實踐:數據庫就是單純的表,只用來存數據,想用多張表的數據在程序中實現

DML語言 數據操作語言
  • insert
  • update
  • delete
添加
修改
UPDATE `student` SET `name` = 'wy' WHERE id = 1;
刪除
DELETE FROM `student`; //會全部刪除 避免這麼寫
DELETE FROM `student` where id =1;

TRUNCATE命令 完全清空一個數據庫,表的結構和索引約束不會變

TRUNCATE `student`;
TRUNCATE TABLE `student`;

DELETE 對比 TRUNCATE
相同點:都能刪除數據,都不會刪除表結構
不同點

  • TRUNCATE 重新設置自增列,計數器會清零
  • TRUNCATE不會影響事務

DQL數據查詢語言

查詢所有的學生 SELECT 字段 FROMSELECT * FROM student

查詢指定字段
SELECT `StudentNo`,`StudentName` FROM student

別名,給結果起一個名字 AS 可以給字段起別名 也可以給表起別名
SELECT `StudentNo` AS 學號,`StudentName` AS 學生姓名 FROM student AS a

函數 Concat(a,b)
SELECT CONCAT('姓名:',`StudentName`) AS 新名字 FROM student
新名字
姓名:wyh
查詢一下有哪些同學參加了考試 成績
SELECT * FROM result

查詢有哪些同學參加了考試
SELECT `StudentNo` From result 發現有重複數據 去重

去重 DISTINCT
SELECT DISTINCT `StudentNo` From result

SELECT VERSION() 查詢系統版本
SELECT 100*3-1 AS 計算結果

where條件子句 檢索數據中符合條件的值

SELECT `studentNo`,`studentResult` FROM result where studentResult>=95 AND studentResult<=100

SELECT `studentNo`,`studentResult` FROM result where studentResult BETWEEN 95 AND 100

SELECT `studentNo`,`studentResult` FROM result where studentNo!=1000

SELECT `studentNo`,`studentResult` FROM result where NOT studentNo=1000

在這裏插入圖片描述

模糊查詢
like

查詢姓劉的同學 like結合%0到任意個字符) _(一個字符)
SELECT `studentNo`,`studentName` FROM `student` WHERE studentName like '劉%'

查詢姓劉的同學 後面只有一個字的
SELECT `studentNo`,`studentName` FROM `student` WHERE studentName like '劉_'

查詢姓劉的同學 後面兩個字的
SELECT `studentNo`,`studentName` FROM `student` WHERE studentName like '劉__'、

查詢名字中有劉的同學
SELECT `studentNo`,`studentName` FROM `student` WHERE studentName like '%劉%'
in

查詢1001 1002 1003號學員
SELECT `studentNo`,`studentName` FROM `student` WHERE studentNo IN (1001,1002,1003)
聯表查詢

JOIN

七種JOIN理論
在這裏插入圖片描述
在這裏插入圖片描述

自連接

自己的表和自己的表連接,核心:一張表拆爲兩張一樣的表即可
在這裏插入圖片描述

分頁 limit和排序 order by
排序 升序ASC 降序 DESC

爲什麼要分頁? 緩解數據庫壓力,給人的體驗更好
在這裏插入圖片描述

查詢JAVA第一學年 課程排名前十的學生 並且分數要大於80的信息(學號 姓名 課程名稱 分數)

SELECT s.studentNo,studentName,subjectName,studentResult
From `student` s
inner join `result` r
on s.studentNo = r.student
inner join `subject` sub
on sub.subjectNo = r.subjectNo
where subjectName = 'JAVA第一學年' AND studentResult>=80
order by studentResult desc
limit 0,10
子查詢

where(這個值是計算出來的)
本質:在where語句中嵌套一個子查詢語句

查詢數據庫結構-1的所有考試成績(學號 科目編號 成績) 降序排列

方式一:

select studentNo,r.studentNo,studentResult
from `result` r
Inner join `subject` sub
on r.studentNo = sub.studentNo
where subjectName = '數據庫結構-1'
order by studentResult desc

方式二:

select studentNo,r.studentNo,studentResult
from `result` 
where studentNo = (select subjectNo from subject where subjectName='數據庫結構-1')
order by studentResult desc

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

MySQL函數
常用函數(不常用)

數學運算

SELECT ABS(-8) 絕對值
SELECT CEILING(9,4)向上取整
SELECT FLOOR)(9.4)向下取整
SELECT RAND()0-1的隨機數
SELECT SIGN(100)判斷一個數的符號 0-0 正數返回1 負數-1
SELECT CHAR_LENGTH('h') 字符串長度
SELECT CONCAT('w','g','d')拼接字符串
SELECT INSERT('我愛你',0,1,'你') 查詢替換 --->你愛你
SELECT LOWER('ZHUANXIAOXIE')
SELECT UPPER('zhuandaxie')
SELECT INSTR('abcdef','bcd')返回第一次出現的子串的索引
SELECT REPLACE('abcdefg','abc','aaa') -->aaadefg 替換出現的指定字符串
SELECT SUBSTR('abcdef',3,2) ---> cd 返回指定字符串 (源字符串 開始位置 截取的長度)
SELECT REVERSE('abcd')反轉 
SELECT CURRENT_DATE() 獲取當前日期
SELECT CURDATE()
SELECT NOW() 年月日時分秒
SELECT LOCALTIME() 本地時間
SELECT SYSDATE() 系統時間
SELECT USER()
SELECT VERSION()
聚合函數(常用)
COUNT()
SUM()
AVG()
MAX()
MIN()
SELECT COUNT(studentName) FROM STUDENT; COUNT字段 會忽略所有的NULLSELECT COUNT(*) FROM STUDENT; 不會忽略nullSELECT COUNT(1) FROM STUDENT; 不會忽略null值

查詢不同課程的平均分 最高分 最低分
核心:根據不同的課程分組
SELECT SubjectName,AVG(StudentResult) as 平均分,MAX(StudentResult),MIN(StudentResult)
FROM result r
INNER JOIN subject sub
ON r.subjectNo = sub.subjectNo
GROUP BY r.subjectNo
HAVING 平均分>80  分組之後需要用HAVING 不能用WHERE
數據庫級別的MD5加密

MD5不可逆,具體值的md5是一樣的

CREATE TABLE `testmd5`(
	`id` INT(4) NOT NULL,
	`name` VARCHAR(20) NOT NULL,
	`pwd` VARCHAR(50) NOT NULL,
	PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

// 明文密碼
INSERT INTO testmd5 VALUES(1,'a','123456'),(2,'b','123456'),(3,'c','123456')

// MD5加密
UPDATE testmd5 SET pwd = MD5(pwd)

// 插入的時候加密、
INSERT INTO testmd5 VALUES(4,'a',MD5('123456'))

// 如何校驗 將用戶傳遞進來的密碼進行md5加密,比對加密後的值

事務

什麼是事務

要麼都成功,要麼都失敗

事務的原則:ACID 原子性 一致性 隔離性 持久性

原子性

要麼都成功,要麼都失敗

一致性

事務前後的數據完整性要保證一致

持久性

事務一旦提交則不可逆,被持久化到數據庫中

隔離性

事務的隔離性是多個用戶併發訪問數據庫時,數據庫爲每一個用戶開啓的事務,不能被其他事務的操作所幹擾,事務之間相互隔離

隔離導致的問題:
髒讀:指一個事務讀取了另一個事務未提交的數據
不可重複讀:在一個事務內讀取表中的某一行數據,多次讀取結果不同
虛讀:在一個事務內讀取到了別的事務插入的數據,導致前後讀取不一致

執行事務
mysql是默認開啓事務自動提交的

手動處理事務

  • 關閉事務自動提交 SET autocommit = 0
  • 手動處理事務
    • ------事務開始------
    • START TRANSACTION 標記一個事務的開始 從這個之後的sql都在同一個事務中
    • INSERT XXXX
    • INSERT XXXX
    • 提交:持久化
    • COMMIT
    • 回滾
    • ROLLBACK
    • ------事務結束------
    • 開啓自動提交 SET autocommit = 1

SAVEPOINT 保存點名 ----設置一個事務的保存點
ROLLBACK TO 保存點名 -----回滾到保存點
RELEASE SAVEPOINT 保存點名 ----撤銷保存點

索引

MySQL索引背後的數據結構及算法原理

MySQL官方對索引的定義爲:索引(Index)是幫助MySQL高效獲取數據的數據結構。提取句子主幹,就可以得到索引的本質:索引是數據結構。

索引分類
  • 主鍵索引 (Primary Key)
  • 唯一索引(UNIQUE KEY)
  • 常規索引(KEY/INDEX)
  • 全文索引 (FULLText)

SHOW INDEX FROM student 顯示所有的索引信息

EXPLAIN 分析sql執行的狀況

索引原則
  • 索引不是越多越好
  • 不要對經常變動的數據加索引
  • 小數據量的表不需要加索引
  • 索引一般加在常用來查詢的字段上

索引的數據結構
Hash類型的索引
BTree:InnoDB的默認數據結構

權限管理和備份

SQL命令操作

用戶表:mysql.user
本質:對這張表增刪改查

創建用戶
create USER username IDENTIFIED BY 'password'

修改密碼(當前登陸的用戶密碼)
set PASSWORD = PASSWORD('password')
修改密碼(修改指定用戶密碼)
set PASSWORD FOR username = PASSWORD('password')

重命名
RENAME USER username TO newUsername

用戶授權 第一個*代表全部庫 第二個*代表全部表
GRANT ALL PRIVILEGES ON *.* TO username

查看權限
SHOW GRANTS FOR username

刪除用戶
DROP USER username
MySQL備份

MySQL備份方式

  1. 直接拷貝物理文件
  2. 使用命令行導出 mysqldump mysqldump -h 主機 -u 用戶名 -p 密碼 數據庫(表1 表2) > 物理位置/文件名
  3. 導入 登錄的情況下 切換到指定的數據庫 source 備份文件
三大範式
第一範式

要求數據庫表的每一列都是不可分割的原子數據項

第二範式

前提:滿足第一範式
確保數據庫表中的每一列都和主鍵相關,而不能只與主鍵的某一部分相關(每張表只描述一件事情)

第三範式

前提:一二範式
需要確保數據表中的每一列數據都和主鍵直接相關,不能間接相關

JDBC
數據庫驅動

在這裏插入圖片描述

SQL注入問題

sql存在漏洞,會被攻擊導致數據泄露 SQL被拼接or存在拼接情況
例如
希望用戶輸入username 和 password登錄
即 SELECT * FROM user WHERE name = username AND password = password;
結果被拼接成
SELECT * FROM user WHERE name = ‘’ or 1=1 AND password = ‘’ or 1=1; 永久成立
PreparedStatement可以解決這個問題 PreparedStatement先編譯sql,但不執行,用?佔位,直接傳參

PreparedStatement防止SQL注入的本質:把傳遞進來的參數當作字符,假設其中存在轉義字符,會被直接轉義

數據庫連接池

連接–釋放耗費資源
設置最小連接數,最大連接數,超過最大連接數排隊等待
開源數據源實現:
DBCP C3P0 Druid

實現的是DataSource接口

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章