MySQL數據庫之常用函數、視圖、索引、觸發器

常用函數及視圖

常用函數

#### 常用函數
```sql
-- FORMAT(X,N) 以將數字 x 進行格式化 “#,###.##”, 將 x 保留到小數點後 n 位,
-- 最後一位四捨五入
SELECT FORMAT(1234.5678,2)
-- LTRIM(s)去掉字符串 s 開始處的空格 
SELECT LTRIM('           NI HAO A ')
-- RTRIM(s)去掉字符串 s 結尾處的空格
SELECT RTRIM('# NI HAO A ')
-- REPEAT(s,n)將字符串 s 重複 n 次
SELECT REPEAT('HELLO ',3)
-- 獲取月份
SELECT MONTH('2019-02-12')
SELECT MONTH(NOW())
SELECT MONTHNAME(NOW())
-- 獲取天  DAYOFYEAR(d)
-- 從參數年01.01號到參數日期是第幾天 
SELECT DAYOFYEAR(NOW())
-- 計算當前月的第幾天
SELECT DAYOFMONTH(NOW())
-- 獲取日期格式中的天
SELECT DAY(NOW())
-- 將日期轉化爲指定的日期格式
SELECT DATE_FORMAT(NOW(),'%Y/%m/%d')
SELECT DATE_FORMAT(NOW(),'%Y-%m-%d')
SELECT DATE_FORMAT(NOW(),'%Y/%m/%d %T')
-- DATE()從日期或日期時間表達式中提取日期值
SELECT DATE(NOW())
-- DATEDIFF(d1,d2)計算日期 d1->d2 之間相隔的天數
SELECT DATEDIFF(NOW(),'2020-01-16')
-- 在字符串“I love ”和字符串“beijing”合併爲同一個字符串
SELECT CONCAT('I love','beijing');
-- 返回字符串“me”在字符串“You love me. He love me.”中第一次出現的位置
SELECT LOCATE('me','You love me.He love me')
-- 查看當前數據庫的版本號,當前數據庫名和當前用戶
SELECT DATABASE();
SELECT USER();
-- 使用字符串“college”來加密字符串“university”
SELECT ENCODE('college','university');
-- 把字符串“i love you”轉換成大寫
SELECT UPPER('i love you');
--把字符串“i love you”轉換成小寫
SELECT LOWER('I LOVE YOU');
-- 獲取顧客表每位郵箱的長度
SELECT LENGTH(cemail) AS 長度FROM customer;
-- 提取顧客郵件信息,起始位置爲 7,長度爲 5
SELECT SUBSTRING(cemail,7,5) as 內容 FROM customer
-- 獲取今年是哪一年,這個月是這一年的那個月,這一週是這一年的那一週,今天是這一年那一天
SELECT  YEAR(CURDATE()) as yr,
MONTH(CURDATE()) as mon, WEEK(CURDATE()) as wk, DAYOFYEAR(CURTIME()) AS yd;
-- 去掉字符串“	abc	”左邊的空格,去掉字符串“	bcd	”右邊的空格,去掉字符串“	bnm	”兩邊的空格
SELECT LTRIM('	abc	'),RTRIM('	bcd	'),TRIM('	bnm	')
exists關鍵字的用法:
-- 使用Exist查詢所有參加考試的學生信息
SELECT * FROM student WHERE EXISTS
(SELECT 1 FROM score WHERE student.stuid = score.stuid)
-- 2.查詢部門所有人工資都大於等於3000的部門信息
SELECT * FROM dept WHERE did IN
(SELECT did FROM employee 
GROUP BY did
HAVING MIN(salary) < 3000) 
-- 3.使用EXISTS查詢所有“2016-02-02”有員工入職的部門信息
SELECT * FROM dept WHERE EXISTS 
(SELECT 1 FROM employee WHERE dept.did = employee.did AND hiredate = '2016-02-02')
-- 4.查詢工資比財務部的所有員工工資都高的員工信息
SELECT * FROM employee WHERE salary >ALL
(SELECT salary FROM employee,dept 
WHERE employee.did = dept.did AND dname = '財務部')

SELECT * FROM employee WHERE salary >
(SELECT MAX(salary) FROM employee INNER JOIN dept 
ON employee.did = dept.did WHERE dname = '財務部')

IN和NOT IN
先執行子查詢,子查詢返回一個集合,然後再將子查詢的結果作爲外層查詢的條件。
EXISTS和NOT EXISTS
先執行外層查詢的第一條記錄,再查內層符合的記錄(查詢完整張表)是否存在,存在則外層查詢該記錄滿足;一次查詢外層的第二條、第三條是否滿足。

三大範式

1)第一範式:不允許表中有表。
2)第二範式:滿足第一範式,並且不存在非主屬性對候選碼的部分依賴。
3)第三範式:滿足第二範式,並且不存在非主屬性對候選碼的傳遞依賴。

#### 視圖
###### 概念
是一種虛擬表,邏輯表,只存表結構,不存數據。
###### 優點
保證數據安全,提升查詢效率。
1.簡單,用戶不用關心對應的表結構、關聯條件和篩選條件。
2.安全,用戶只能訪問被允許查詢的結果集。
3.數據獨立,一旦視圖確定表結構,可以屏蔽表結構變化對用戶的影響。
```sql
CREATE VIEW view_em
AS
SELECT  id,`name`,IF(sex=1,'男','女') sex,
				CASE(dept)
					WHEN 1001 THEN '行政部'
					WHEN 1002 THEN '銷售部'
					WHEN 1003 THEN '技術部'
					ELSE '無部門'
				END deptname,
				IF(ispost,'在職','離職') post
FROM tb_em

SELECT `name`,post,deptname FROM view_em
-- 更新視圖,刪除視圖數據,對應的基本表也改變了
UPDATE view_em SET name='張飛' WHERE id=1001
DELETE FROM view_em WHERE id=1006
-- 刪除表
DROP TABLE IF EXISTS tb_em;
-- 修改視圖 ALTER
ALTER VIEW view_mysql
AS
SELECT `name`,stu.stuid,score
FROM `subject` sub,student stu,score sco
WHERE sub.subid = sco.subid 
AND stu.stuid = sco.stuid AND subname = 'mysql'
-- 查看視圖的表結構
DESC view_mysql

觸發器、存儲引擎和索引

存儲引擎

概念

使用不同的存儲機制來存儲文件。

常見的存儲引擎

1.Innodb:數據庫的首選引擎,支持事務操作,支持併發、外鍵。
2.myisam:基於ISAM的存儲引擎,擁有較高的插入、查詢速度,不支持事務。
3.memory:將表中的數據放在內存中,數據量不大、沒有較高安全性,主要針對查詢、訪問數據。

索引

概念

是一個排序的列表,列表中存儲這索引值及該值數據所在的物理地址。

分類
類型 特點
普通索引 用表的普通列建立的索引。
主鍵索引 根據主鍵創建的索引,不允許重複、空行、空值。
唯一索引 用來建立索引的列是空值,只允許最多一個爲空值。
組合索引 用多個列組合構建的索引,不允許有空值。
全文索引 用文本對象對應的列構建的索引,可以對文章內容作索引。
優點

1.可以提升檢索的效率,減少IO次數。

缺點

1.索引會佔存儲空間,是普通表的1.5倍。
2.降低數據表的修改操作,在修改數據表的同時還需要修改索引表。

適合創建索引的列

1.經常搜索的某些列,加快搜索的速度。
2.作爲主鍵的列,加快搜索的速度。
3.經常用於連接表的列,主要指的是外鍵,可以加快連接的速度。
4.需要排序的列,利用索引的排序加快排序查詢時間。
5.WHERE子句的列,加快條件判斷速度。

索引的實現原理

1.不同的搜索引擎對索引的實現方式是不同的。
2.Myisam採用的是B+樹
3.InnoDB默認支持B+樹,也支持哈希

-- 查看存儲引擎
SHOW ENGINES;
-- 創建索引 
-- 1.普通索引
-- 1.1直接創建索引 
USE studentmanager;

CREATE INDEX myindex1
ON student(name(20));

SHOW INDEX FROM student;
-- 1.2修改表的時候添加索引
ALTER TABLE student ADD INDEX myindex2 (phone(11))
-- 1.3創建表的時候同時創建索引
CREATE TABLE mytable(
	id INT NOT NULL PRIMARY KEY,
	username VARCHAR(32) NOT NULL,
	INDEX myindex3(username(32))
)
-- 2.唯一索引------------------------------------------------
USE studentmanager;
CREATE UNIQUE INDEX myindex4 ON `subject`(subname(32));
SHOW INDEX FROM `subject`;
-- 3.主鍵索引


-- 測試索引 
CREATE DATABASE bigdata;
USE bigdata;
CREATE TABLE test(
	id BIGINT(10) PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT'主鍵id',
	username VARCHAR(50) DEFAULT NULL COMMENT'用戶名',
	nickname VARCHAR(50) DEFAULT NULL COMMENT'暱稱',
	`password` VARCHAR(50) DEFAULT NULL COMMENT'密碼'
)ENGINE=myisam AUTO_INCREMENT=10000001 DEFAULT CHARSET=utf8;

-- 模擬插入1000萬條數據
CREATE PROCEDURE testproc()
BEGIN
	DECLARE num INT;
	SET num = 1;
	WHILE num<10000000 DO
		INSERT INTO test(username,nickname,`password`) VALUES(num,CONCAT('暱稱',num),PASSWORD(num));
		-- 10000001,1,暱稱1,密碼
		SET num = num+1;
	END WHILE;
END

-- 調用存儲過程
CALL testproc()

SELECT COUNT(1) FROM test
-- 在不使用索引的情況下查詢
SELECT * FROM test WHERE nickname='暱稱'
-- 建立索引
ALTER TABLE test ADD INDEX nickname_index(nickname)

SELECT * FROM test WHERE nickname='暱稱'
-- 索引的刪除
DROP INDEX nickname_index ON test
-- 修改表的方式刪除索引
USE studentmanager;
SHOW INDEX FROM student;
ALTER TABLE student DROP INDEX myindex2;

觸發器

定義

就是某個表發生一個事件,然後自動化執行預先編寫好的SQL語句,執行相關操作。

觸發條件

增刪改

觸發的頻率

對每一行的操作

創建的四個要素

1.監視地點(table)
2.監視事件(增刪改)
3.觸發時間
– after:先完成數據的增刪改,再觸發,觸發的語句晚於監視的增刪改操作。
– before:先完成觸發,再增刪改,觸發的語句先於監視的增刪改。
4.觸發事件(增刪改)

應用場景

比如:下訂單

NEW和OLD

1.引用觸發器發生變化的記錄內容。
2.insert類型的觸發器中,表示將要或已經插入的數據。
3.Update類型的觸發器中,Old表示將要或已經被修改的源數據;New表示修改後的新數據。
4.Delete類型的觸發器,OLD表示將要或者已經刪除的源數據。
5.使用方法:New.列名;Old.列名。
6.儘量不使用觸發器,比較耗時。

-- 創建觸發器的語法
-- 觸發行的操作
CREATE TRIGGER tr_student_count
AFTER 
INSERT 
ON student
FOR EACH ROW
BEGIN 
	-- 修改班級爲1的班級實際人數
	UPDATE classinfo SET ActualNum = ActualNum+1 WHERE cid = 1;
	UPDATE classinfo SET RemainderNum = RemainderNum-1 WHERE cid = 1;	
END
-- 測試 當插入一條數據後,觸發器自動執行
INSERT INTO student(`name`,sex,phone,birthday,cid)
VALUES('蔡徐坤','男','12345678912','2019-01-01',1)

-- 對於新增而言,新插入的行使用new表示,行中新增的數據(每一列的值),

-- 刪除觸發器
DROP TRIGGER tr_student_count;
-- 創建新的觸發器
CREATE TRIGGER tr_student_count
AFTER INSERT ON student
FOR EACH ROW
BEGIN
-- 修改班級實際人數
	UPDATE classinfo SET ActualNum = ActualNum+1 WHERE cid=new.cid;
	UPDATE classinfo SET RemainderNum = RemainderNum-1 WHERE cid=new.cid;	
END

INSERT INTO student(`name`,sex,phone,birthday,cid)
VALUES('吳亦凡','男','12345678912','2019-01-01',3)

-- 創建一個刪除的觸發器
-- 對於刪除信息而言,想引用要刪除的一行數據,用old來表示,old.列名
CREATE TRIGGER tr_student_delete
AFTER DELETE ON student
FOR EACH ROW 
BEGIN
	-- 修改班級實際人數和實際名額
	UPDATE classinfo SET ActualNum = ActualNum-1 WHERE cid = old.cid;
	UPDATE classinfo SET RemainderNum = RemainderNum+1 WHERE cid = old.cid;
END

-- 測試刪除學生信息
DELETE FROM student WHERE stuid = 20;

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