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;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章