數據庫學習之MySQL

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

聯表查詢的思路是:

  1. 分析需求,分析查詢的字段分別來自哪些表
  2. 確定使用哪種連接查詢
  3. 確定交叉點(即兩、三張表中哪個數據是相同的)

對於多表查詢:

首先,要查詢哪些數據。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)

前提是要滿足第一範式和第二範式。

第三範式需要確保數據表中的每一列數據都和主鍵直接相關,而不能簡介相關。

在進行規範數據庫的設計時,會產生 規範性和性能的問題。針對這樣的問題,需要考慮以下:

關聯查詢的表不得超過三張。

  • 考慮商業化的需求和目標,數據庫的性能更加重要。
  • 在規範性能的問題的時候,需要適當考慮一下規範性。
  • 故意給某些表增加一些冗餘的字段。從多表查詢中變爲單表查詢。
  • 故意增加一些計算列。從大數據量降低爲小數據量的查詢。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章