MySQL簡介
數據庫
爲什麼要學數據庫?
有以下幾點原因:
最現實的原因就是爲了找工作,數據庫是崗位的需求,所以要學。
其次就是現在是大數據時代,數據是非常重要的,得數據者得天下。
然後就是我們需要存儲數據,這就要用到數據庫了。
最後就是數據庫是所有軟件體系中最核心的存在。
什麼是數據庫?
數據庫即DataBase(DB),它是存放數據的倉庫,它的存儲空間很大,可以存放百萬條、千萬條、上億條數據。
數據庫是一個按照數據結構來存儲和管理數據的計算機軟件系統,安裝在操作系統之上。
數據庫的作用說白了就是:存儲數據、管理數據。
數據庫的分類
數據庫可以分爲關係型數據庫和非關係型數據庫。
關係型數據庫:(SQL)
關係型數據庫,存儲的格式可以直接且直觀地反映實體間的關係。關係型數據庫中表與表之間是有很多複雜的關聯關係的。
常見的關係型數據庫有MySQL,SqlServer,Oracle,DB2,SQLlite等。
在輕量或小型應用中,使用不同的關係型數據庫對系統的性能影響不大,但是在構建大型應用時,需要根據應用的業務需求和性能需求,選擇合適的關係型數據庫。
關係型數據庫大多都遵循SQL(Structured Query Language,結構化查詢語言)標準,常見操作有查詢(SELECT)、新增(INSERT)、更新(UPDATE)、刪除(DELETE)等。
關係型數據庫通過表和表之間、行和列之間的關係進行數據的存儲。
非關係型數據庫(NoSQL)
非關係型數據庫指的是分佈式的、非關係型的、不保證遵循ACID原則的數據存儲系統。
NoSQL數據庫有MongoDB,Redis,Memcache等。
非關係型數據庫是進行對象的存儲,通過對象的自身的屬性來決定。
非關係型數據庫的設計目的是簡化數據庫結構、避免冗餘、影響性能的表連接、摒棄複雜分佈式。
NoSQL數據庫適合追求速度和可擴展性、業務多變的應用場景。
數據庫管理系統簡稱DBMS,它是數據庫的管理軟件,可以科學有效地管理、維護和獲取數據。MySQL就是數據庫管理系統。
MySQL
MySQL是一個關係型數據庫管理系統,由瑞典MySQL AB公司開發,現屬於Oracle公司。MySQL是最流行的關係型數據庫管理系統之一,在web應用方面,MySQL是最好的RDBMS(Relational Database Management System,關係數據庫管理系統)應用軟件之一。
數據庫的操作
對數據庫的操作實際上是對數據庫中表中的數據的操作。
數據庫的基本操作
創建數據庫
CREATE DATABASE IF NOT EXISTS school;
刪除數據庫
DROP DATABASE IF EXISTS school;
使用數據庫
USE school;
查看數據庫
SHOW DATABASES;
如果表名或者字段名是一個特殊的字符,那麼就要使用tab鍵上的那個符號(``)將其括起來。如
CREATE DATABASE `school`;
數據庫的列類型
常用的數據庫的列類型。
數值
類型 | 含義 | 字節數 |
---|---|---|
tinyint | 十分小的數據 | 1個字節 |
smallint | 較小的數據 | 2個字節 |
mediumint | 中等大小的數據 | 3個字節 |
int | 標準的整數 | 4個字節(常用) |
bigint | 較大的數據 | 8個字節 |
float | 浮點數 | 4個字節 |
double | 浮點數 | 8個字節(存在精度問題) |
decimal | 字符串形式的浮點數 | 16個字節(不存在精度損失,常用語金融計算) |
字符串
類型 | 含義 | 大小 |
---|---|---|
char | 字符串固定大小的 | 0~255 |
varchar | 可變字符串 | 0~65535(常用) |
tinytext | 微型文本 | 2^8-1 |
text | 文本串 | 2^16-1(保存大文本) |
時間日期
類型 | 格式 |
---|---|
date | YYYY-MM-DD,日期格式 |
time | HH:mm:ss,時間格式 |
datetime | YYYY-MM-DD HH:mm:ss ,最常用的時間格式 |
timestamp | 時間戳,從1970.1.1到現在的毫秒數。常用 |
year | 表示年份 |
null
null表示沒有值,未知的。
不要使用null進行運算,因爲結果爲null
數據庫的字段屬性
字段屬性 | 含義 |
---|---|
Unsigned | 表示無符號的整數。表明該列不能聲明爲負數 |
Zerofill | 0填充。不足的位數,使用0來填充 |
自增 | 自增,即自動在上一條記錄的基礎上加1(默認)。通常用來設計唯一的主鍵,必須是整數類型。可以自定義設計主鍵自增的起始值和步長。 |
非空(NULL/NOT NULL) | j假設設置爲not null,如果不賦值,就會報錯。假設設置爲null,如果不填寫值,默認就爲null。 |
默認 | 設置默認的值。例如設置sex字段默認值爲男,如果不指定該列的值,那麼就會有默認的值。 |
每一個表都必須存在以下五個字段。這是用於做項目的,表示一個記錄存在意義!
字段 | 含義 |
---|---|
id | 主鍵 |
version | 樂觀鎖 |
is_delete | 僞刪除 |
gmt_create | 創建時間 |
gmt_update | 修改時間 |
創建數據庫表
創建數據庫表的格式:
CREATE TABLE [IF NOT EXISTS] `表名` (
`字段名` 列類型 [屬性] [索引] [註釋],
`字段名` 列類型 [屬性] [索引] [註釋],
......
`字段名` 列類型 [屬性] [索引] [註釋]
)[表類型][字符集設置][註釋]
在school數據庫中創建一個student表。
CREATE TABLE IF NOT EXISTS `student`(
`id` INT(4) NOT NULL AUTO_INCREMENT COMMENT '學號',
`name` VARCHAR(30) NOT NULL DEFAULT '匿名' COMMENT '姓名',
`pwd` VARCHAR(20) NOT NULL DEFAULT '123456' COMMENT '密碼',
`sex` VARCHAR(2) NOT NULL DEFAULT '女' COMMENT '性別',
`birthday` DATETIME DEFAULT NULL COMMENT '出生日期',
`address` VARCHAR(100) DEFAULT NULL COMMENT '家庭住址',
`email` VARCHAR(50) DEFAULT NULL COMMENT '郵箱',
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
幾個常用命令:
查看創建數據庫的語句
SHOW CREATE DATABASE school
查看創建表的定義語句
SHOW CREATE TABLE student
顯示錶的結構
DESC student
-- mysql的註釋爲--,且需要在--和註釋內容之間空一格
數據庫表的類型
在創建數據庫和表的時候會定義引擎,常用的有兩種:INNODB(默認使用)和MYSIAM(早些年使用)。
兩者的區別主要有以下:
MYISAM | INNODB | |
---|---|---|
事務支持 | 不支持 | 支持 |
數據行鎖定 | 不支持 | 支持 |
外鍵約束 | 不支持 | 支持 |
全文索引 | 支持 | 不支持 |
表空間的大小 | 較小 | 較大,約爲2倍 |
常規的使用操作:
- MYISAM:節約空間,速度較快
- INNODB:安全性高,事務的處理,多表多用戶操作
在物理空間存在的位置
所有的數據庫文件都存在data目錄下,一個文件夾就對應一個數據庫。本質還是文件的存儲。
MySQL引擎在物理文件上的區別:
- INNODB:在數據庫表中只有一個 *.frm文件,以及上級目錄下的ibdata1文件。
-
MYISAM對應文件
- *.frm文件:表結構的定義文件
- *.MYD文件:數據文件(data)
- *.MYI文件:索引文件(index)
設置數據庫表的字符集編碼
CHARSET=utf8
不設置字符集編碼的話,會使用MySQL默認的編碼 Latin1,該編碼不支持中文。
在my.ini配置文件中配置默認的編碼:
character-set-server=utf8
表的修改和刪除
表的修改
修改表名 ALTER TABLE 舊錶名 RENAME AS 新表名;
ALTER TABLE student RENAME AS student01;
增加表的字段 ALTER TABLE 表名 ADD 字段 列屬性;
ALTER TABLE student01 ADD grade INT(3);
修改表的字段–修改約束 ALTER TABLE 表名 MODIFY 字段 列屬性[]
ALTER TABLE student01 MODIFY grade VARCHAR(11) -- 修改約束
修改表的字段–字段重命名 ALTER TABLE 表名 CHANGE 舊名字 新名字 列屬性[]
ALTER TABLE student01 CHANGE grade grade1 INT(2)
刪除表的字段 ALTER TABLE 表名 DROP 字段名
ALTER TABLE student01 DROP grade1
表的刪除
-- 刪除表(考慮表如果存在再去刪除)
DROP TABLE IF EXISTS student01
在進行表的創建和刪除操作時,應該加上判斷避免報錯
MySQL數據管理
外鍵
外鍵:表的外鍵是另一表的主鍵,外鍵可以有重複的,可以是空值。外鍵表示了兩個關係之間的相關聯繫。
外鍵有兩種創建方式。
方式一
在創建表的時候,就增加約束來創建外鍵。但這樣做的缺點是麻煩且複雜。
CREATE TABLE `grade`(
`gradeid` INT(10) NOT NULL AUTO_INCREMENT COMMENT '年級id',
`gradename` VARCHAR(50) NOT NULL COMMENT '年級名稱',
PRIMARY KEY (`gradeid`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
-- 學生表的 gradeid 字段 要去引用年級表的 gradeid
-- 定義外鍵key
-- 給這個外鍵添加約束 (執行引用) references 引用
CREATE TABLE IF NOT EXISTS `student` (
`id` INT(4) NOT NULL AUTO_INCREMENT COMMENT '學號',
`name` VARCHAR(30) NOT NULL DEFAULT '匿名' COMMENT '姓名',
`pwd` VARCHAR(20)NOT NULL DEFAULT '123456' COMMENT '密碼',
`sex` VARCHAR(2) NOT NULL DEFAULT '女' COMMENT '性別',
`birthday` DATETIME DEFAULT NULL COMMENT '出生日期',
`gradeid` INT(10) NOT NULL COMMENT '學生的年級',
`address` VARCHAR(100) DEFAULT NULL COMMENT '家庭住址',
`email` VARCHAR(50) DEFAULT NULL COMMENT '郵箱',
PRIMARY KEY(`id`),
KEY `FK_gradeid` (`gradeid`),
CONSTRAINT `FK_gradeid` FOREIGN KEY (`gradeid`) REFERENCES
`grade`(`gradeid`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
刪除有外鍵關係的表的時候,必須先要刪除引用別人的表(從表),然後再刪除被引用的表(主表)。
方式二
創建表成功後,添加外鍵約束。
CREATE TABLE `grade`(
`gradeid` INT(10) NOT NULL AUTO_INCREMENT COMMENT '年級id',
`gradename` VARCHAR(50) NOT NULL COMMENT '年級名稱',
PRIMARY KEY (`gradeid`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
-- 學生表的 gradeid 字段 要去引用年級表的 gradeid
-- 定義外鍵key
-- 給這個外鍵添加約束 (執行引用) references 引用
CREATE TABLE IF NOT EXISTS `student` (
`id` INT(4) NOT NULL AUTO_INCREMENT COMMENT '學號',
`name` VARCHAR(30) NOT NULL DEFAULT '匿名' COMMENT '姓名',
`pwd` VARCHAR(20)NOT NULL DEFAULT '123456' COMMENT '密碼',
`sex` VARCHAR(2) NOT NULL DEFAULT '女' COMMENT '性別',
`birthday` DATETIME DEFAULT NULL COMMENT '出生日期',
`gradeid` INT(10) NOT NULL COMMENT '學生的年級',
`address` VARCHAR(100) DEFAULT NULL COMMENT '家庭住址',
`email` VARCHAR(50) DEFAULT NULL COMMENT '郵箱',
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
-- 創建表的時候沒有外鍵關係
ALTER TABLE `student`
ADD CONSTRAINT `FK_gradeid` FOREIGN KEY(`gradeid`) REFERENCES
`grade`(`gradeid`);
ALTER TABLE 表名 ADD CONSTRAINT 約束名 FOREIGN KEY(作爲外鍵的列) REFERENCES 哪個表(哪個字段)
上面的操作都是物理外鍵,是數據庫級別的外鍵,不建議使用(避免數據庫過多造成困擾)。
最佳的實現就是
- 數據庫就是單純的表,只用來存數據,只有行(數據)和列(字段)
- 若想使用多張表的數據,想使用外鍵則通過程序來實現
DML語言
DML:Data Manipulation Language,數據庫操作語言。通過該語言可以實現對數據庫的基本操作。
DML基本的操作是:
- 插入
- 修改
- 刪除
插入(添加)操作
插入操作使用 INSERT。
插入的語法爲:INSERT INTO 表名([字段名1,字段名2,字段名3]) VALUES ('值1'),('值2'),('值3',...)
-- INSERT INTO 表名([字段名1,字段名2,字段名3]) VALUES ('值1'),('值2'),('值3',...)
INSERT INTO `grade`(`gradename`) VALUES ('大一') -- 由於主鍵是自增的,我們可以省略
-- 如果不寫表的字段,就會一一匹配
INSERT INTO `grade` VALUES('大三')
一般寫插入語句時,一定要數據和字段一一對應
INSERT INTO `student`(`name`,`pwd`,`sex`) VALUES ('張三','123456','男')
-- 插入多個字段
INSERT INTO `grade`(`gradename`)
VALUES('大二'),('大四')
需要注意的是:
- 字段和字段之間使用英文逗號隔開
- 字段可以省略,但是後面的值還是要一一對應
- 可以同時插入多條數據,VALUES後面的值使用英文逗號隔開即可
修改操作
修改使用 UPDATE
修改操作的語法爲:update 表名 set column_name=value,[column_name=value,...] where [條件]
-- 修改名字,帶了條件
UPDATE `student` SET `name`='李四' WHERE id = 1;
-- 在不指定條件的情況下,會改動所有表!
UPDATE `student` SET `name`='王五'
-- 修改多個屬性,使用逗號隔開
UPDATE `student` SET `name`='張三',`age`='23' WHERE id = 1;
where id = 1
是一個條件句。where + 判斷條件(字段 操作符 某個值/區間)
where操作符會返回一個布爾值。
操作符 | 含義 | 示例 | 結果 |
---|---|---|---|
= | 等於 | 5=6 | false |
<> 或者 != | 不等於 | 5<>6/5!=6 | true |
> | 大於 | 10>8 | true |
< | 小於 | 10<8 | false |
>= | 大於等於 | 8>=8 | true |
<= | 小於等於 | 16<=20 | true |
between … and … | 在某個範圍內 | 5 between 1 and 10 | true |
and | 且/和 | 5>2 and 2>3 | false |
or | 或 | 5>2 or 2>3 | true |
對於修改的語法。需要注意的有:
- column_name 是數據庫的列,所以最好帶上``
- 修改的時候如果沒有帶篩選的條件,則會修改所有的列
- value 是一個具體的值,也可以是一個變量
- 多個設置的屬性之間,使用英文逗號隔開
刪除操作
刪除使用 delete。
刪除的語法:delete from 表名 [where 條件]
-- 刪除指定數據
DELETE FROM `student` WHERE id = 1;
-- 刪除時如果沒有帶條件,則會全部刪除,所以儘量避免這樣寫
DELETE FROM `student`;
TRUNCATE 命令
TRUNCATE 的作用是:完全清空一個數據庫表,但表的結構和索引約束不會變。
-- 清空 student 表
TRUNCATE `student`
delete和truncate的區別:
- 相同點:兩者都可以刪除數據庫表,都不會刪除表結構
- 不同點
- truncate 會重新設置自增列,計數器會歸零
- truncate不會影響事務
delete刪除的問題
:重啓數據庫後的現象
- INNODB:自增列會從1開始(存在內存中,斷電即失)
- MYISAM:繼續從上一個自增量開始(存在文件中,不會丟失)
DQL查詢數據
DQL
DQL:Data Query LANGUAGE,數據查詢語言。
對於DQL而言,所有的查詢操作都使用它(select);簡單查詢、複雜查詢都可以做到;它是數據庫中最核心的語言,也是最重要的語句;它是使用頻率最高的語句。
select 語法
SELECT [ALL | DISTINCT]
{* | table.* | [table.field[as alias1][,table.field2[as alias2]][,...]] }
FROM table_name [as table_alias]
[left | right |inner join table_name2] -- 聯合查詢
[WHERE ...] -- 指定結果需滿足的條件
[GROUP BY ...] -- 指定結果按照哪幾個字段來分組
[HAVING ...] -- 過濾分組的記錄必須滿足的次要條件
[ORDER BY ...] -- 指定查詢記錄按一個或多個條件排序
[LIMIT {[offset,]row_count | row_countOFFSET oeeset}]; -- 指定查詢的記錄從哪條至哪條
注意:[ ]括號表示可選的,{ }括號表示必選的
查詢字段
語法:
select 字段 from 表名
-- 查詢全部的學生 select 字段 from 表名
SELECT * FROM `student`
-- 查詢指定的字段
SELECT `StudentNo`,`StudentName` from student
有時候,列名字不是很見名知意,可以起別名,使用as。
字段名 as 別名;表名 as 別名
-- 起別名 AS 給結果起一個名字 可以給字段、表起別名
SELECT `StudentNo` AS 學號,`StudentName` AS 學生姓名 from student
-- 拼接函數 concat(a,b)
SELECT CONCAT('姓名:',StudentName) AS 新名字 FROM student
distinct 去重
distinct的作用是:去除select查詢出來的結果中重複的數據,即重複的數據只顯示一條即可。
-- 發現重複數據,去重
SELECT DISTINCT `StudentNo` FROM result
數據庫的列
-- 查詢系統版本(select+函數)
SELECT VERSION()
-- 可以用來計算(select+表達式)
SELECT 20-8 AS 計算結果
-- 查詢自增的步長(select+變量)
SELECT @@auto_increment_increment
-- 考試成績 + 1分查看
SELECT `StudentNo`,`StudentResult`+1 AS '提分後' FROM result
數據庫中的表達式可以是:文本值,列,null,函數,計算表達式,系統變量等
語法:select 表達式 from 表
where條件子句
where條件字句的作用是於檢索數據庫中符合條件的值。搜索的條件由一個或者多個表達式組成。結果是布爾值。
where中用到的邏輯運算符
運算符 | 語法 | 描述 |
---|---|---|
and && | a and b / a && b | 邏輯與,兩個都爲真,則結果爲真 |
or || | a or b / a ||b | 邏輯或,其中一個爲真,則結果爲真 |
not ! | not a / ! a | 邏輯非,真爲假,假爲真 |
-- and
SELECT StudentNo,`StudentResult` FROM result
WHERE StudentResult>=80 AND StudentResult<=100
-- &&
SELECT StudentNo,`StudentResult` FROM result
WHERE StudentResult>=80 && StudentResult<=100
-- !
SELECT studentNo,`StudentResult` FROM result
WHERE studentNo!=1000;
-- not
SELECT studentNo,`StudentResult` FROM result
WHERE NOT studentNo = 1000
模糊查詢 比較運算符
運算符 | 語法 | 描述 |
---|---|---|
is null | a is null | 如果a爲null,結果爲真 |
is not null | a is not null | 如果a不爲null,結果爲真 |
between | a between b and c | f如果a在b和c之間,則結果爲真 |
like | a like b | sql匹配,如果a匹配b,則結果真 |
in | a in (a1,a2,a3,…) | r如果a在a1,a2,a3,…中的其中的某一個值中,則結果爲真 |
-- 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 '%雨%'
-- in
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE StudentNo IN (1,3,5,6);
-- null not null
-- not null
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE `BornDate` IS NOT NULL
-- null
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE `BornDate` IS NULL
聯表查詢
聯表查詢使用 join。聯表查詢有三大類。
查詢方式 | 描述 |
---|---|
inner join | 如果表中至少有一個匹配,就返回行 |
left join | 會從左表中返回所有的值,即使右表中沒有匹配 |
right join | 會從右表中返回所有的值,即使左表中沒有匹配 |
join的語法:join(連接的表) on(判斷的條件)
-- inner join
SELECT s.studentNO,studentName,SubjectNo,StudentResult
FROM student AS s
INNER JOIN result AS r
ON s.studentNO = r.studentNO
-- left join
SELECT s.studentNO,studentName,SubjectNo,StudentResult
FROM student s
LEFT JOIN result r
ON s.studentNO = r.studentNO
-- right join
SELECT s.studentNO,studentName,SubjectNo,StudentResult
FROM student s
RIGHT JOIN result r
ON s.studentNO = r.studentNO
聯表查詢的思路是:
- 分析需求,分析查詢的字段分別來自哪些表
- 確定使用哪種連接查詢
- 確定交叉點(即兩、三張表中哪個數據是相同的)
對於多表查詢:
首先,要查詢哪些數據。select …
其次,要從哪幾張表中查。from 表 xxx join 連接的表 on 交叉條件
多張表查詢時,先查詢兩張表然後再慢慢增加。
join是連接查詢,where是等值查詢
自連接
自連接是自己的表和自己的表進行連接,核心是將一張表拆爲兩張一樣的表。
分頁和排序
排序
排序的方式有兩種,升序(ASC)和降序(DESC)。
排序的語法:order by 哪個字段 排序方式
SELECT s.`StudentNo`,`StudentName`,`SubjectName`,`StudentResult`
FROM student s
INNER JOIN `result` r
ON s.StudentNo = r.StudentNo
INNER JOIN `subject` sub
ON r.`SubjectNo` = sub.`SubjectNo`
WHERE subjectName = '數據庫結構-1'
ORDER BY StudentResult ASC
分頁
分頁的目的是 爲了緩解數據庫的壓力,使用戶的體驗感更好。網頁中就應用了分頁。
分頁的語法:limit 起始值,頁面的大小
SELECT s.`StudentNo`,`StudentName`,`SubjectName`,`StudentResult`
FROM student s
INNER JOIN `result` r
ON s.StudentNo = r.StudentNo
INNER JOIN `subject` sub
ON r.`SubjectNo` = sub.`SubjectNo`
WHERE subjectName = '數據庫結構-1'
ORDER BY StudentResult ASC
LIMIT 5,5
分頁的一些計算
每頁只顯示五條數據
第一頁 limit 0,5 (1-1)*5
第二頁 limit 5,5 (2-1)*5
第三頁 limit 10,5 (3-1)*5
第N頁 limit(n-1)* pageSize,pageSize
【pageSize:頁面大小】
【(n-1)* pageSize:起始值】
【n :當前頁 】
【數據總數/頁面大小 = 總頁數】
子查詢
當一個查詢時另一個查詢的條件時,稱之爲子查詢。
本質就是 在where語句中嵌套一個子查詢語句
SELECT StudentNo,StudentName FROM student WHERE StudentNo IN (
SELECT StudentNo FROM result WHERE StudentResult>80 AND SubjectNo = (
SELECT SubjectNo FROM `subject` WHERE `SubjectName` = '高等數學-2')
)
分組和過濾
分組是通過某個字段來進行分組。
過濾則是根據某個條件或某些條件來進行篩選。
SELECT SubjectName, AVG(StudentResult) AS 平均分,MAX(StudentResult) AS 最高
分,MIN(StudentResult) AS 最低分
FROM result r
INNER JOIN `subject` sub
ON r.`SubjectNo` = sub.`SubjectNo`
GROUP BY r.SubjectNo
HAVING 平均分>80
MySQL函數
常用函數
數學運算
-- 絕對值
SELECT ABS(-5)
-- 向上取整
SELECT CEILING(5.4)
-- 向下取整
SELECT FLOOR(5.4)
-- 返回一個 0~1 之間的隨機數
SELECT RAND()
-- 判斷一個數的符號 0返回0 負數返回-1,正數返回 1
SELECT SIGN(10)
字符串函數
-- 字符串長度
SELECT CHAR_LENGTH('hello,world')
-- 拼接字符串
SELECT CONCAT('我','愛','你')
-- 查詢,從某個位置開始替換某個長度
SELECT INSERT('我愛編程helloworld',1,2,'超級熱愛')
-- 小寫字母
SELECT LOWER('Hello')
-- 大寫字母
SELECT UPPER('Hello')
-- 返回第一次出現的子串的索引
SELECT INSTR('Hello','l')
-- 替換出現的指定字符串
SELECT REPLACE('我愛編程','愛','超級熱愛')
-- 返回指定的子字符串 (源字符串,截取的位置,截取的長度)
SELECT SUBSTR('我愛編程helloworld',4,6)
-- 反轉
SELECT REVERSE('清晨我上馬')
時間和日期函數
-- 獲取當前日期
SELECT CURRENT_DATE()
SELECT CURDATE()
-- 獲取當前的時間
SELECT NOW()
-- 本地時間
SELECT LOCALTIME()
-- 系統時間
SELECT SYSDATE()
-- 獲取具體的年 月 天 小時 分鐘 秒
SELECT YEAR(NOW())
SELECT MONTH(NOW())
SELECT DAY(NOW())
SELECT HOUR(NOW())
SELECT MINUTE(NOW())
SELECT SECOND(NOW())
有關係統的信息
SELECT SYSTEM_USER()
SELECT USER()
SELECT VERSION()
聚合函數
聚合函數是比較常用的。
常見的聚合函數有:
函數 | 描述 |
---|---|
count() | 計數 |
sum() | 求和 |
avg() | 平均值 |
max() | 最大值 |
min() | 最小值 |
count()
想要查詢一個表中有多少個記錄,可以使用count()。
count(字段) | 會忽略所有的null值 |
count(*) | 不會忽略null值。本質是計算行數 |
count(1) | 不會忽略null值。本質是計算行數 |
如果表沒有主鍵,那麼count(1)比count( * )快。表有主鍵,count(*)會自動優化到主鍵列上。
數據庫級別的MD5加密
MD5
MD5:Message-Digest Algorithm,是一種被廣泛使用的密碼散列函數。主要增強算法複雜度和不可逆性。
MD5是不可逆的,但具體值的MD5是一樣的。
UPDATE testmd5 SET pwd=MD5(pwd) WHERE id = 1
使用MD5,校驗的時候,需要將用戶傳遞進來的值進行MD5加密,然後在數據庫中對比加密後的值。
事務
事務:Transaction,一般是指要做的或所做的事情。
在mysql中,事務是將一組SQL放在一個批次中去執行。
事務的原則是:
ACID原則
A:原子性(Atomicity)
原子性即 事務要麼都成功,要麼都失敗,不存在一方成功一方失敗的情況(會出錯)。
B:一致性(Consistency)
事務前後的數據完整性要保持一致。
I:隔離性(Isolation)
事務的隔離是多個用戶併發訪問數據庫時,數據庫爲每一個用戶開啓的事務,不能被其他事務的操作數據所幹擾,多個併發事務之間要相互隔離。
D:持久性(Durability)
持久性是針對事務提交的,事務一旦提交則不可逆,將被持久化到數據庫中。
隔離導致的一些問題
髒讀
髒讀指的是一是個事務讀取了另外一個事務未提交的數據。
不可重複讀
在一個事務內讀取表中的某一行數據,多次讀取結果不同。(這個不一定是錯誤的,只是某些場合不對)
虛讀(幻讀)
虛讀指的是在一個事務內讀取到了別的事務插入的數據,導致前後讀取不一致。
執行事務
-- mysql 是默認開啓事務自動提交的
SET autocommit = 0 /* 關閉 */
SET autocommit = 1 /* 開啓(默認的) */
-- 手動處理事務
SET autocommit = 0 -- 關閉自動提交
-- 事務開啓
START TRANSACTION -- 標記一個事務的開始,從這個之後的 sql 都在同一個事務內
INSERT xx
INSERT xx
-- 提交: 持久化 (成功!)
COMMIT
-- 回滾: 回到的原來的樣子 (失敗!)
ROLLBACK
-- 事務結束
SET autocommit = 1 -- 開啓自動提交
索引
MySQL官方對索引的定義是:索引(Index)是幫助MySQL高效獲取數據的數據結構
InnoDB 的默認數據結構是 BTree
索引分類
索引可以分爲:
- 主鍵索引(PRIMARY KEY)
- 這是唯一的標識。主鍵是不可重複的,只能有一個列作爲主鍵。
- 唯一索引(UNIQUE KEY)
- 可以避免重複的列出現。唯一索引是可以重複的,多個列都可以標識爲 唯一索引。
- 常規索引(KEY/INDEX)
- 常規索引是默認的,使用index,key關鍵字來設置。
- 全文索引(FullText)
- 在特定的數據庫引擎下才有,如MyISAM。
- 可以快速定位數據。
基本語法
索引的創建:
- 在創建表的時候給字段增加索引
- 創建成功表後,增加索引
-- 顯示所有的索引信息
SHOW INDEX FROM student
-- 增加一個全文索引 (索引名) 列名
ALTER TABLE school.student ADD FULLTEXT INDEX `studentName`(`studentName`);
索引在小數據量的時候,用處不大,但是在大數據的時候,區別十分明顯~
索引的原則
- 索引不是越多越好
- 不要對進程變動數據加索引
- 小數據量的表不需要加索引
- 索引一般加在常用來查詢的字段上
權限管理和備份
用戶管理
方式一
使用可視化管理工具進行用戶的管理。
方式二
使用SQL命令進行用戶的管理,實際上操作的是 mysql.user這張表。本質也是對錶的增刪改查。
-- 創建用戶 CREATE USER 用戶名 IDENTIFIED BY '密碼'
CREATE USER zhangsan IDENTIFIED BY '123456'
-- 修改密碼
-- 修改當前用戶密碼
SET PASSWORD = PASSWORD('123456')
-- 修改指定用戶密碼
SET PASSWORD FOR zhangsan = PASSWORD('1234567')
-- 重命名 RENAME USER 原來名字 TO 新的名字
RENAME USER zhangsan TO zhangsan02
-- 用戶授權 ALL PRIVILEGES 全部的權限 (可以對數據庫和表)
-- ALL PRIVILEGES 除了給別人授權,其他都能夠幹
GRANT ALL PRIVILEGES ON *.* TO zhangsan02
-- 查詢權限
-- 查看指定用戶的權限
SHOW GRANTS FOR zhangsan02
SHOW GRANTS FOR root@localhost
-- 撤銷權限 REVOKE 哪些權限, 在哪個庫撤銷,給誰撤銷
REVOKE ALL PRIVILEGES ON *.* FROM zhangsan02
-- 刪除用戶
DROP USER zhangsan02
備份
備份的原因:
- 保證數據不丟失
- 數據轉移
MySQL數據庫備份的方式:
-
直接拷貝物理文件
-
在可視化工具中手動導出
- 在想要導出的表或庫中,右鍵選擇備份或導出
-
使用命令行導出(mysqldump命令)
# mysqldump -h 主機 -u 用戶名 -p 密碼 數據庫 表名 > 物理磁盤位置/文件名 mysqldump -hlocalhost -uroot -p123456 school student >D:/a.sql # mysqldump -h 主機 -u 用戶名 -p 密碼 數據庫 表1 表2 表3 > 物理磁盤位置/文件名 # mysqldump -h 主機 -u 用戶名 -p 密碼 數據庫> 物理磁盤位置/文件名 mysqldump -hlocalhost -uroot -p123456 school >D:/c.sql
數據的導入:
# 導入
# 登錄的情況下,切換到指定的數據庫
# source 備份文件
source d:/a.sql
mysql -u用戶名 -p密碼 庫名< 備份文件
規範數據庫設計
當數據比較複雜的時候,就需要設計數據庫。
數據庫的設計也有好壞之分。
糟糕的數據庫設計會產生一系列問題:
- 數據冗餘,浪費空間
- 數據庫插入和刪除都很麻煩,且產生異常
- 程序性能差
良好的數據庫設計的優點是:
- 節省內存空間
- 保證數據庫的完整性
- 方便開發系統
爲什麼需要數據庫規範化?
當數據庫不規範時,會產生一系列問題:
- 信息重複
- 更新異常
- 插入異常:無法正常顯示信息
- 刪除異常:丟失有效的信息
在軟件開發中,設計數據庫時涉及到兩方面:分析需求(分析業務和需要處理的數據庫的需求)和概要設計(設計關係圖 E-R圖)。
設計數據庫的步驟:
- 收集信息,分析需求
- 標識實體:把需求落地到每個字段
- 標識實體之間的關係
三大範式
第一範式(1NF)
原子性:保證每一列都不可再分
第二範式(2NF)
前提是要滿足第一範式。每張表只描述一件事情。
第三範式(3NF)
前提是要滿足第一範式和第二範式。
第三範式需要確保數據表中的每一列數據都和主鍵直接相關,而不能簡介相關。
在進行規範數據庫的設計時,會產生 規範性和性能的問題。針對這樣的問題,需要考慮以下:
關聯查詢的表不得超過三張。
- 考慮商業化的需求和目標,數據庫的性能更加重要。
- 在規範性能的問題的時候,需要適當考慮一下規範性。
- 故意給某些表增加一些冗餘的字段。從多表查詢中變爲單表查詢。
- 故意增加一些計算列。從大數據量降低爲小數據量的查詢。