#### 常用函数
-- 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 ')
-- 使用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.数据独立,一旦视图确定表结构,可以屏蔽表结构变化对用户的影响。
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
使用不同的存储机制来存储文件。
常见的存储引擎
存储引擎 | 特点 |
---|---|
Innodb | 数据库的首选引擎,支持事务操作,支持并发、外键。 |
myisam | 基于ISAM的存储引擎,拥有较高的插入、查询速度,不支持事务。 |
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.触发事件(增删改)
比如:下订单
1.引用触发器发生变化的记录内容。
2.insert类型的触发器中,new表示将要或已经插入的数据。
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;