mysql總結與複習
技術標籤:MySQL
mysql
資料庫引擎
-
innodb(預設使用)
-
myisam(早些年使用的)
innodb | myisam | |
---|---|---|
事務支援(跟spring遇到的是一個意思) | 支援 | 不支援 |
資料行鎖定 | 支援 | 不支援 |
外來鍵約束 | 支援 | 不支援 |
全文索引 | 不支援 | 支援 |
表空間大小 | 較大,約為myisam的兩倍 | 較小 |
-
myisam 節約空間,速度較快
-
innodb 安全,事務的處理,多表多使用者操作
-
共同點 儲存位置,資料庫檔案都在data目錄下
在檔案上面的區別
-
innodb 在資料庫對應資料夾中只有一個.frm檔案,以及上級目錄下的ibdata1檔案
-
myisam 對應位置有.frm檔案(表結構),.myd檔案(資料檔案),.myi檔案(索引檔案)
ps:跟在設定資料庫引擎後的DEFAULT charset=8是設定表的預設字符集編碼,不設定的話是mysql的預設字符集編碼(Latin1,不支援中文),my.ini可以設定預設的編碼:character-set-server=utf8(不建議)
-
新學的命令
show create database xxx
檢視建立資料庫的語句
檢視某個資料表的語句
desc xxx
顯示錶的結構
複習
查詢(important)
select [all | distinct] {* | table.* | [table.field1[as 別名1],table.field2[as 別名2],...],...} from table [as 表別名] [left | right | inner join table2 on 條件] --聯合查詢 [where ...] --結果需要滿足的條件 [group by ...] --結果按照哪些欄位分組 [having ...] --group by需要滿足的次要條件 [order by ...] --結果按照條件(一般是一些欄位)排序 [limit {[offset,]row_count | row_count_offset offset}]; --指定結果從哪條到哪條 ps:[]代表可選,{}代表必選,where和on的結果差不多,可以寫一個也可以兩個都寫
- 指定了INNER關鍵字的連線是內連線,內連線是系統預設的,可以省略INNER關鍵字。使用內連線後仍可使用WHERE子句指定條件。
- left和right都是外連線,決定了查詢結果中哪個表裡的值為null
- 乾貨
- inner join使用on或where結果是一樣的,區別就是join on是連線查詢(利於閱讀),where是等值查詢。where與join兩種方式
- left/right join用on或where的區別:區別
- on 條件是在生成臨時表時使用的條件,where 條件是在臨時表生成好後,再對臨時表進行過濾的條件(使用where之後就沒有 left join 的含義了,即必須返回左邊表的記錄),條件不為真的就全部過濾掉。
- 自連線(瞭解即可),一張表拆為兩張一樣的表即可
記一個解題思路:如果查詢多張表,先查詢兩張表,然後增加(增加join on語句)
資料庫
unsigned(非負的意思):
- 無符號的整數
- 聲明瞭該列不能為負數
zerofill:
- 0填充
- 不足的位數使用0填充。int(3) 5 -> 005
null和not null
- not null 不賦值就會報錯
- null 不填寫值,預設為null
default
- 預設值 sex default ‘男’
create database xxx character set utf8 collate utf _8_general_ci --建立資料庫,很多時候都是用的navicat建立的,這個是設定字符集的語句
- collate 表示核對
create table `xxx` (
…
)engine = innodb default charset = utf8
- 設定字符集時與建立資料庫時的語句稍有不一樣
聚合函式(important)
-
COUNT()
計數
- COUNT(指定列欄位名) 根據列名計數,會忽略所有的null值
- COUNT(*) 包含所有列,不會忽略列值為null的
- COUNT(1) 忽略所有的列,用1代表程式碼行,不會忽略null值
-
SUM(‘列名’)
對某個列的值總和
其他,略
資料表
-
修改表名
alter table 原名 rename as 新名
-
增加欄位
alter table teacher add age int(11)
-
修改表的欄位(重新命名,修改約束)
修改約束,原來是int,現在改成varchar
alter table teacher modify age varchar(11)
欄位重新命名
alter table teacher change age age2 int(1)
-
刪除表的欄位
alter table teacher drop age2
-
刪除表
drop table teacher
if exists :如果表存在再刪除,避免報錯(若沒有該表上面的語句會報錯,下面的就不會)
drop table if exists teacher
ps:
- 表名稱和欄位名儘量用``包裹,為了安全,防止出錯(防止被誤認為是關鍵字)
表資料
-
刪除表資料(delete)
delete from 表名 where條件
delete from `student` where id = 1
-
專業清空表資料(truncate)
完全清空表,表結構和索引不會變,不建議使用delete清空
truncate `student`
與delete相比:
- 相同點 完全清空表,表結構不會變
- 區別 truncate會重新設定自增列(從零開始),不會影響事務;delete刪除後接著自增(不歸零),但是如果資料庫引擎是innodb,net start mysql之後,自增列會歸零(因為是存在記憶體當中的,斷電即失)
jdbc
一段感興趣的程式碼
InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
--
Properties properties = new Properties();
properties.load(in);
String driver = properties.getProperty("driver");
ps:若此處配置資料庫連線池的是xml檔案,則不需要讀取程式碼
感興趣的一個區別:
java.sql.Date 資料庫的;使用 :java.sql.Date(new Date().getTime());
util.Date Java的 new Date().getTime() 獲得時間戳
statement物件,兩個方法
- executeQuery()執行查詢語句,返回ResultSet物件
- executeUpdate()執行增刪改語句,返回整數
sql注入問題(拼接字串,針對statement物件;而PreparedStatement物件就可以防止sql注入)
意思是web應用程式對使用者輸入資料的合法性沒有判斷或者過濾不嚴,攻擊者可以在web應用程式中事先定義好的查詢語句的結尾新增額外的sqsl語句,以此來實現欺騙資料庫伺服器執行非授權的任意查詢(把所有的使用者名稱密碼都查出來),從而進一步得到相應的資訊,上文參考百度百科,即sql存在漏洞,會被攻擊,導致資料洩露。輸入的時候sql被拼接 or
select * from users where `name` = '' or '1=1' and `password` = '' or '1=1'
--' or '1=1是拼接上去的;' or '1=1也是拼接上去的
PreparedStatement物件(防止sql注入)
原理:預編譯會在引數外面加引號並且過濾特殊字元(轉義字元),原來的注入語句就會變成下面這樣:
where name = '\'test\' or 1=1' --mysql的SQL文日誌
自然不會被注入
略(與statement物件類似,executeQuery()執行查詢語句,executeUpdate()執行增刪改語句)
資料庫連線池
資料庫連線的連線和釋放是十分浪費系統資源的
池化技術:預先準備一些資源,使用預先準備好的
-
最小連線數:10 根據常用的來
-
最大連線數:15 最高業務承載上限 超過15就排隊等待
-
等待超時:100ms 直接斷掉
-
…
編寫連線池需要實現一個介面:DataSource
開源的實現類
- DBCP
- C3P0
- Druid
使用不同的資料來源匯入不同的包就行
常用函式(不包括聚合函式)
數學函式
-
ABS()
絕對值
-
CEILING()
向上取整
-
FLOOR()
向下取整
-
RAND()
隨機數,0~1之間的隨機數
-
SIGN
判斷一個數的符號,0返回0,負數返回-1,正數返回1
字串函式
-
CHAR_LENGTH()
字串長度
-
CONCAT(‘啦’,‘啦’,‘啦’)
合併字串
-
INSERT()
在指定位置插入字串,也可以有替換的功能
-
LOWER()、UPPER()
轉換為小、大寫
-
INSTR(‘yyh’,‘h’)
返回第一次出現的子串索引
-
REPLACE(‘hhhlll’,‘hl’,‘yyh’)
替換出現的指定字串,hl -> yyh
-
SUBSTR(‘hhhlll’,4,6)
返回指定的子字串,4開始,擷取6個
-
REVERSE(‘hhhlll’)
字串反轉
時間和日期函式 這個個人用得還比較多
-
CURRENT_DATE()/CURDATE()
當前日期
-
NOW()
當前時間,包含時分秒
-
LOCALTIME()
本地時間
-
SYSDATE()
返回函式執行時間,系統時間
-
YEAR/MONTH/DAY/HOUR/MINUTE/SECOND()
不用多說
系統
-
SYSTEM_USER()/USER()
當前使用者
-
VERSION()
版本
資料庫的MD5加密(即MD5(),一個函式)
MD5:MD5叫資訊摘要演算法,MD5由MD4、MD3、MD2改進而來,主要增強演算法複雜度和不可逆性。MD5演算法因其普遍、穩定、快速的特點,仍廣泛應用於**普通資料的加密保護領域 ** ,1996年後該演算法被證實存在弱點,可以被加以破解,對於需要高度安全性的資料,專家一般建議改用其他演算法,如SHA-2。
應用:
- 密碼管理 可以將任意長度的輸入串經過計算得到固定長度的輸出,而且只有在明文相同的情況下,才能等到相同的密文,這樣就可以把使用者的密碼以MD5值的方式儲存起來,使用者註冊的時候,系統是把使用者輸入的密碼計算成 MD5 值,然後再去和系統中儲存的 MD5 值進行比較,如果密文相同,就可以認定密碼是正確的,否則密碼錯誤。
- 電子簽名 MD5 演算法還可以作為一種電子簽名的方法來使用,使用 MD5演算法就可以為任何檔案(不管其大小、格式、數量)產生一個獨一無二的“數字指紋”,藉助這個“數字指紋”,通過檢查檔案前後 MD5 值是否發生了改變,就可以知道原始檔是否被改動。
- 垃圾郵件篩選 在電子郵件使用越來越普遍的情況下,可以利用 MD5 演算法在郵件接收伺服器上進行垃圾郵件的篩選,以減少此類郵件的干擾。
總結:MD5不可逆,只有在明文相同的情況下,才能等到相同的密文
事務(只看加粗的就行)
ACID原則:原子性,一致性,隔離性,永續性
事務就是多條sql,要麼都ok,要麼都回滾
產生一些問題:髒讀,幻讀
-
原子性
a:800元,給b:200元,轉賬200兩個步驟
800-200
200+200
這兩個步驟(sql)要麼都ok,要麼都回滾
-
一致性
最終一致性:a和b的總價值一定是1000元(事務前後的資料要一致)
-
永續性
事務一旦提交就不可逆
事務結束後資料不隨著外界原因導致資料丟失
操作前:a 800,b 200
操作後:a 600,b 400
若在操作前(事務還沒有提交),伺服器宕機或斷電,那麼重啟資料庫後,應該是:a 800,b 200(恢復到原狀)
若在操作後(事務已經提交),伺服器宕機或斷電,那麼重啟資料庫後,應該是:a 600,b 400(事務一旦提交就不可逆)
-
隔離性
排除其他事務對本次事務的影響
如:a(800)給b(200)轉200,c(1000)給b(200)轉100,多個使用者操作有個隔離的關係
隔離失敗就會有問題:
- 髒讀 一個事務讀取了另一個事務未提交的資料
- 不可重複讀(不一定是錯誤,可能是場合不對) 在一個事務內讀取表中的某一行資料,多次讀取結果不同。比如在第二次讀取的時候b有人轉賬進來300
- 虛讀(幻讀) 在一個事務內讀取到了別的事務插入的資料(一般是行影響,多了一行)
mysql是預設開啟事務自動提交的。
關閉:
set autocommit = 0
開啟(預設):
set autocommit = 1
手動處理事務
先關閉前面的自動提交,然後下面
-
事務開啟
start transaction
從這之後的sql都在同一個事務內
sql語句; sql語句; sql語句;
-
提交(ok,不可逆,也就是持久化)
commit;
-
回滾(fail,回到原來的樣子)
rollback;
-
事務結束(開啟自動提交)
set autocommit = 1
;
ps:整個過程中可以設定儲存點(瞭解):
savepoint 儲存點名 --設定儲存點
rollback to savepoint 儲存點名 --回滾到儲存點
release savepoint 儲存點名 --撤銷儲存點
索引
官方原話:
索引(index)是幫助mysql高效獲取資料的資料結構。 0.5s -> 0.000001s(大大的節省了時間)
索引是資料結構,對於大量的資料正常查詢可能要查詢好多條記錄,索引只需要一條,非常快
-
分類
-
主鍵索引 primary key navicat中索引選項中不顯示主鍵索引
唯一的標識,主鍵不可重複
-
唯一索引 unique key
避免重複的列出現(兩列叫同一個名字肯定是不行的)
-
常規索引 key/index
預設的(不寫就有)
-
全文索引 fulltext
在特定的資料庫引擎才有(以前是myisam才有),快速定位資料。
現在應該都有了,不只是myisam
ps:主鍵索引只能有一個,唯一索引可以有多個(多個列可以標識為唯一索引,列名可以不同)
-
-
命令
- 顯示錶的索引資訊
show index from xxx
-
增加一個全文索引(改表的語句)
alter table `表名` add fulltext index `索引名`(`欄位名`);
索引名:給索引起名字
ps:還有兩種建立索引的方式,一個是建表的時候,另一個如下(常規索引)
create index 索引名 on `表名`('欄位名'); --索引名:id_表名_欄位名
-
分析sql執行的狀況 explain
explain select * from `表名`; --非全文索引,會查很多行
explain select * from `表名` where match(`欄位名`) against('字串'); --全文索引的使用,只查了一行,資料量比較少會沒有用
-
寫函式之前必須的標誌(mysql的sql程式設計,瞭解)
delimiter $$ --寫函式之前必須的標誌 create function mock_data() returns int begin --開始寫函式體 end;
-
索引原則
- 索引不是越多越好
- 不要對經常變動的資料加索引
- 小資料量的表不需要加索引
- 索引一般加在常用來查詢的欄位上
許可權管理
sql命令操作(navicat,略)
系統使用者表:mysql下的user表(在此表增刪改)
有三個預設使用者:root、mysql.session、mysql.sys
-
建立使用者
create user yyh identified by '密碼'
-
修改密碼(當前使用者)
set password = password('新密碼')
-
修改密碼(指定使用者)
set password for yyh = password('新密碼')
-
給使用者重新命名
rename user yyh to yyh2
-
使用者授權(all privileges,全部許可權,除了給別人授權的許可權;庫.表)
grant all privileges on *.* to yyh2 --全部的庫全部的表,對所有表都有最高的許可權
-
檢視許可權
show grants for yyh2 --檢視指定使用者的
show grants for [email protected] --檢視root使用者的
-
撤銷許可權(跟授權一樣)
revoke all privileges on *.* from yyh2
-
刪除使用者
drop user yyh2
資料庫備份
原因:
- 資料不丟失
- 資料轉移
方式:
-
直接拷貝檔案(data下的資料庫檔案)
-
navicat可以匯出(這個俺以前經常幹,略)
-
命令
-
匯出一張表(mysqldump -h主機 -u使用者名稱 -p密碼 資料庫 資料表 >匯出位置)
mysqldump -hlocalhost -uroot -p666 ssm users >D:/1.sql ---h表示host的意思
-
匯出多張表(mysqldump -h主機 -u使用者名稱 -p密碼 資料庫 表1 表2 表3 >匯出位置)
mysqldump -hlocalhost -uroot -p666 ssm users traveller role >D:/2.sql ---h表示host的意思
-
匯出資料庫(mysqldump -h主機 -u使用者名稱 -p密碼 資料庫 >匯出位置)
mysqldump -hlocalhost -uroot -p666 ssm >D:/3.sql ---h表示host的意思
-
匯入資料表(use database之後)
source d:/1.sql
若沒有登入,則
``mysql -u使用者名稱 -p密碼 庫名< 備份檔案`
-