數據庫引擎 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 字段 FROM 表
SELECT * 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
自連接
自己的表和自己的表連接,核心:一張表拆爲兩張一樣的表即可
分頁 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字段 會忽略所有的NULL值
SELECT COUNT(*) FROM STUDENT; 不會忽略null值
SELECT 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官方對索引的定義爲:索引(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備份方式
- 直接拷貝物理文件
- 使用命令行導出 mysqldump mysqldump -h 主機 -u 用戶名 -p 密碼 數據庫(表1 表2) > 物理位置/文件名
- 導入 登錄的情況下 切換到指定的數據庫 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接口