前言
SQL(Structured Query Language)是一种用于管理关系型数据库的标准化语言,它用于定义、操作和管理数据库中的数据。SQL是一种通用的语言,可以用于多种关系型数据库管理系统(RDBMS),如MySQL、Oracle、SQL Server等。
MySQL是一种开源的关系型数据库管理系统,它使用SQL作为其查询语言。MySQL是最流行的开源数据库之一,它具有高性能、可靠性和可扩展性。MySQL支持多用户、多线程和多表操作,可以在各种操作系统上运行。
因此,SQL是一种语言,而MySQL是一种关系型数据库管理系统,它使用SQL作为其查询语言。SQL可以用于其他关系型数据库管理系统,而MySQL是其中的一种。
本篇博客从数据资源谈起,阐述了数据库的重要性、相关概念等,然后介绍了MySQL数据库的DOS命令,数据类型,数据调优以及SQL分类,最后列举了SQL常用的函数,包括字符串、日期、数学、流程、聚合、分组等语句。
目录
- 前言
- 引出
- 从数据资产谈起
- 资产的概念
- 数据资产
- 为什么学数据库?
- 数据库的基本概念
- 市场比较流行的数据库厂商
- MySQL数据库
- MySQL常用DOS命令大全
- MySQL常用的数据类型
- 百万数据性能调优
- SQL的分类(DML,DQL)
- SQL的函数
- 字符串函数
- 日期函数
- 数学函数
- 流程控制函数
- 聚合函数
- 分组查询
- 总结
引出
1.从数据资源谈起,阐述了数据库的重要性、相关概念等;
2.介绍了MySQL数据库的DOS命令,数据类型,数据调优以及SQL分类;
3.列举了SQL常用的函数,包括字符串、日期、数学、流程、聚合、分组等语句;
从数据资产谈起
资产的概念
数据资产
我们讲数据资产,它是当今企业BSC最重要的核心要素,一个企业有三大核心要素:一是利润,二是人才,三十产品。然而每个企业每天经营同时,“资产不断的在流失“,比如人员的流失,比如人员离职后给公司留下的”财富“等。所以数据资产是当前最关注的核心点。 除了我们软件行业,很多行业都在慢慢的往数字化方向转型,目的是提高企业的竞争力,通过技术来提升市场的活跃度。
为什么学数据库?
数据库的基本概念
MySQL代表数据管理系统。
数据库就代表某个仓库
数据库里面存的就是表
数据库管理软件里面存放了很多数据库,数据库是通过本地文件来存储的。然后数据库里面是存储的表。
市场比较流行的数据库厂商
MySQL是免费开源的。
Oracle是一个全球非常厉害的数据厂商,Oracle
- 收费的: 一年几百万美元,不能买断
- 所有的金融系统全部都是Oracle
- 赠送你一个MySql
微软体系下的:SQLServer
- 买操作系统送的
开源的:PGSQL
MySQL数据库
MySQL常用DOS命令大全
一般而言,我们常用命令主要是在Linux系统下进行编写。作为windows系统一般会使用可视化工具进行数据库的操作。
MySQL常用的数据类型
java | mysql | 说明 |
---|---|---|
String | char (不可变) 、varchar (可变)、text (长文本,65535个字) | 字符串 |
int | tinyint、smallint、mediumint、 int、bigint | 数值 |
flaot,double | float(单精度)、double(双精度)、decimal | 浮点 |
Date | YEAR、TIME、DATE (日期)、DATETIME (日期和时间)、TIMESTAMP (日期和时间值) | 日期 |
File、Stream | BINARY、VARBINARY、TINYBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB | 二进制 |
百万数据性能调优
SHOW VARIABLES LIKE ‘autocommit’;
SHOW VARIABLES LIKE ‘autocommit’; 是一个MySQL查询语句,用于查看当前数据库连接的自动提交模式。
自动提交模式是指在执行每个SQL语句后是否自动提交事务。当自动提交模式开启时,每个SQL语句都会被立即提交,即使没有显式地使用COMMIT语句。当自动提交模式关闭时,需要显式地使用COMMIT语句来提交事务。
执行SHOW VARIABLES LIKE ‘autocommit’;查询语句后,会返回当前数据库连接的自动提交模式的值。如果返回值为ON,表示自动提交模式开启;如果返回值为OFF,表示自动提交模式关闭。
这个查询语句可以帮助你了解当前数据库连接的自动提交模式,以便在需要的时候进行相应的调整和处理。
package com.tianju;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* 用于模拟高吞吐量情况下添加数据
* @ClassName: InsertBatchTest
* @Description: TODO
* @author Wen.J 434679924@qq.com
* @date 2022-07-01 11:09:39
*/
public class InsertBatchTest {
// 耗时:127732
// 耗时:98122
// 耗时:4334
public static void main(String[] args) {
test3();
}
// 原始写法
public static void test1() {
Connection conn = null;
PreparedStatement cmd = null;
try {
int count = 50000; // 循环10000次
conn = JDBCUtil.getConnection();
String sql = "insert into goods values (? , ?)";
cmd = conn.prepareStatement(sql);
long start = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
cmd.setObject(1, (i+1));
cmd.setObject(2, "商品" + (i+1));
// cmd SQL预编译优化: insert into goods values (1 , '商品1')
// 每循环一次都会去访问数据库。。。 访问1万次。。。
// 提交事务了5万次
cmd.executeUpdate();
}
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start));
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtil.close(conn, cmd);
}
}
// 通过批量添加
public static void test2() {
Connection conn = null;
PreparedStatement cmd = null;
try {
int count = 50000; // 循环10000次
conn = JDBCUtil.getConnection();
String sql = "insert into goods values (? , ?)";
cmd = conn.prepareStatement(sql);
long start = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
cmd.setObject(1, (i+1));
cmd.setObject(2, "商品" + (i+1));
cmd.addBatch(); // 积攒SQL - >还没有访问数据库 - > 循环完毕后,将要积攒1万条SQL语句
if (i % 1000 == 0) { // 每500提交一次
// 批量提交一下
cmd.executeBatch();
// 清除SQL缓存
cmd.clearBatch();
}
}
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start));
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtil.close(conn, cmd);
}
}
// 引入事务机制
public static void test3() {
Connection conn = null;
PreparedStatement cmd = null;
try {
int count = 50000; // 循环10000次
conn = JDBCUtil.getConnection();
conn.setAutoCommit(false); // 关闭自动
String sql = "insert into goods values (? , ?)";
cmd = conn.prepareStatement(sql);
long start = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
cmd.setObject(1, (i+1));
cmd.setObject(2, "商品" + (i+1));
cmd.addBatch(); // 积攒SQL - >还没有访问数据库 - > 循环完毕后,将要积攒1万条SQL语句
if (i % 1000 == 0) { // 每500提交一次
// 批量提交一下
cmd.executeBatch();
// 清除SQL缓存
cmd.clearBatch();
}
}
// 事务只提交一次
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start));
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
conn.commit();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JDBCUtil.close(conn, cmd);
}
}
}
SQL的分类(DML,DQL)
SQL是一本脚本语言:
- 操作表结构,
- 操作表里面的数据,比如增删改查等。
数据操纵语言全程是Data Manipulation Language,主要是进行插入元组、删除元组、修改元组的操作。主要有insert、update、delete语法组成。
数据查询语言全称是Data Query Language,所以是用来进行数据库中数据的查询的,即最常用的select语句
SQL的函数
字符串函数
函数名 | 描 述 |
---|---|
LENGTH | 计算字符串长度函数,返回字符串的字节长度 |
CONCAT | 合并字符串函数,返回结果为连接参数产生的字符串,参数可以使一个或多个 |
INSERT | 替换字符串函数 |
LOWER | 将字符串中的字母转换为小写 |
UPPER | 将字符串中的字母转换为大写 |
LEFT | 从左侧字截取符串,返回字符串左边的若干个字符 |
RIGHT | 从右侧字截取符串,返回字符串右边的若干个字符 |
TRIM | 删除字符串左右两侧的空格 |
REPLACE | 字符串替换函数,返回替换后的新字符串 |
SUBSTRING | 截取字符串,返回从指定位置开始的指定长度的字符换 |
CHAR_LENGTH | 获取字符的个数 |
select LENGTH('abc'); -- 3
select LENGTH('中国'); -- 6 (1个中文占3~4之间);
select CHAR_LENGTH('豆腐干'); -- 字符个数
select 'a' + 'b' + 'c';
select CONCAT('a','b','c'); -- 字符串的拼接
select CHAR_LENGTH(CONCAT('a','b','c')); -- 函数之间可以组合
SELECT INSERT('abc',2,1,'A'); -- 第二个参数从1开始的
SELECT LOWER('ABC') as 小写 , UPPER('abc') as 大写;
SELECT LEFT('Student.java',7) , RIGHT('home.html' , 4) , SUBSTRING('aBc',2,1);
use empdb;
SELECT CONCAT(first_name,' ',last_name) FROM employees;
日期函数
函数名 | 描 述 |
---|---|
CURRENT_DATE,CURRENT_TIME,NOW() | 取得当前的系统日期和日期 |
YEAR | 获取年份,返回值范围是 1970〜2069 |
MONTH | 获取指定日期中的月份 |
MONTHNAME | 获取指定日期中的月份英文名称 |
DAYOFWEEK | 获取指定日期对应的一周的索引位置值 |
DAYOFYEAR | 获取指定曰期是一年中的第几天,返回值范围是1~366 |
DAYOFMONTH | 获取指定日期是一个月中是第几天,返回值范围是1~31 |
ADDDATE、SUBDATE | 向日期添加指定的时间间隔,向日期减去指定的时间间隔 |
ADDTIME、SUBTIME | 原始时间上添加指定的时间、原始时间上减去指定的时间 |
DATEDIFF | 获取两个日期之间间隔,返回参数 1 减去参数 2 的值 |
DATE_FORMAT | 格式化指定的日期,根据参数返回指定格式的值 |
WEEKDAY | 获取指定日期在一周内的对应的工作日索引 |
TIMESTAMPDIFF | 根据指定单位,比较日期的间隔 |
-- mysql -> 单表, 40T
SELECT CURRENT_DATE() , CURRENT_TIME() , CURRENT_TIMESTAMP() , NOW();
SELECT YEAR('2022-12-12') , YEAR(NOW()) , MONTH(NOW()) , MONTHNAME(NOW()) ;
SELECT DAYOFYEAR(NOW()) , DAYOFMONTH(NOW());
-- 按照数字显示周一,周二.....
-- java , 选择结构来做 if ,switch
-- 也有选择结构
SELECT CASE (DAYOFWEEK(NOW()) - 1)
WHEN 1 THEN '周一'
WHEN 2 THEN '周二'
WHEN 3 THEN '周三'
WHEN 4 THEN '周四'
WHEN 5 THEN '周五'
WHEN 6 THEN '周六'
WHEN 7 THEN '周日'
END;
-- IF
-- 判断年龄是否成年未成年
set @age = 12;
-- 三元表达式: age > 20 ? 语句1 : 语句2
SELECT IF(@age > 18,'已成年','未成年');
-- 操控时间, 可以多时间进行加减
SELECT ADDDATE(NOW(),INTERVAL 1 YEAR); -- 添加一年
SELECT ADDDATE(NOW(),INTERVAL -1 YEAR); -- 减去一年
SELECT ADDDATE(NOW(),INTERVAL 1 MONTH) ,
ADDDATE(NOW(),INTERVAL 1 DAY) ,
ADDDATE(NOW(),INTERVAL 1 HOUR) ,
ADDDATE(NOW(),INTERVAL 1 MINUTE);
-- 日期间隔,返回的是天数
SELECT DATEDIFF(NOW() , '2008-5-12');
-- 日期间隔,自定义(天,月,年)
SELECT TIMESTAMPDIFF(YEAR,'2008-5-12',NOW());
SELECT TIMESTAMPDIFF(MONTH,'2008-5-12',NOW());
SELECT TIMESTAMPDIFF(DAY,'2008-5-12',NOW());
SELECT TIMESTAMPDIFF(HOUR,'2008-5-12',NOW());
-- 8、查询年龄超过20周岁的Y2的学生信息
select * from student where TIMESTAMPDIFF(year,BornDate,NOW()) > 20 and GradeId = (
select GradeId from grade where GradeName = 'Y2'
);
-- 9、查询1月份过生日的学生信息
select * from student where MONTH(BornDate) = 1;
-- 10、查询今天(当月)过生日的学生姓名及所在年级
select * from student where MONTH(BornDate) = MONTH(NOW());
-- 11、查询学号为“Y21003007”的学生Email的域名
select substring_index(Email,'@',-1) from student where StudentNo = 'Y21003007';
-- 12、查询年龄是23岁的学生信息
select * from student where TIMESTAMPDIFF(year,BornDate,NOW()) = 23;
-- 13、查询年龄是28岁以上的女生
select * from student where TIMESTAMPDIFF(year,BornDate,NOW()) > 28 and sex = '女';
-- 14、查询年龄20岁到28岁之间,地址是北京的Y2男生
select * from student where TIMESTAMPDIFF(year,BornDate,NOW()) BETWEEN 20 and 28 ;
-- 15、查询生日为星期四的学生
select * from student where (DAYOFWEEK(BornDate) - 1) = 4;
-- 17、查询上个月9号过生的学生
-- 18、查询生日是当月的学生信息
-- 19、查询上个月9号过生的学生
-- 20、查询即将1周要过生日的
DROP PROCEDURE IF EXISTS getAge;
-- 定义存储过程 。速度很快
DELIMITER //
CREATE PROCEDURE getAge(IN birthday VARCHAR(20))
BEGIN
DECLARE age INT DEFAULT 0;
SET age = TIMESTAMPDIFF(YEAR,birthday,NOW());
SELECT age;
END//
DELIMITER ;
-- 调用存储过程
CALL getAge('1992-12-1');
数学函数
函数名 | 描 述 | 示 例 |
---|---|---|
RAND | 返回从 0 到 1 之间的随机 float 值 | SELECT RAND( )返回:0.79288062146374 |
ABS | 取数值表达式的绝对值 | SELECT ABS(-43)返回:43 |
CEILING | 取大于或等于指定数值、表达式的最小整数 | SELECT CEILING(43.5)返回:44 |
FLOOR | 取小于或等于指定表达式的最大整数 | SELECT FLOOR(43.5)返回:43 |
POWER | 取数值表达式的幂值 | SELECT POWER(5,2)返回:25 |
ROUND | 将数值表达式四舍五入为指定精度 | SELECT ROUND(43.543,1)返回:43.500 |
SIGN | 对于正数返回+1,对于负数返回-1,对于0则返回0 | SELECT SIGN(-43)返回:-1 |
SQRT | 取浮点表达式的平方根 | SELECT SQRT(9)返回:3 |
流程控制函数
函数名称 | 作用 |
---|---|
IF | 判断,流程控制 |
IFNULL | 判断是否为空 |
CASE | 搜索语句 |
SELECT CASE (DAYOFWEEK(NOW()) - 1)
WHEN 1 THEN '周一'
WHEN 2 THEN '周二'
WHEN 3 THEN '周三'
WHEN 4 THEN '周四'
WHEN 5 THEN '周五'
WHEN 6 THEN '周六'
WHEN 7 THEN '周日'
END;
-- IF
-- 判断年龄是否成年未成年
set @age = 12;
-- 三元表达式: age > 20 ? 语句1 : 语句2
SELECT IF(@age > 18,'已成年','未成年');
聚合函数
SQL语言本身,跨所有数据库的。
聚合函数有个特别,计算的值只有1个。
函数名 | 描 述 | 示 例 |
---|---|---|
MAX | 查询指定列的最大值 | select max(StudentResult) from result 返回:数值99 |
MIN | 查询指定列的最小值 | select min(StudentResult) from result 返回:数值54 |
COUNT | 统计查询结果的行数 | select count(1) from xzdw_2021 返回:数值662770 |
SUM | 求和,返回指定列的总和 | select SUm(StudentResult) from result 返回:数值6471 |
AVG | 求平均值,返回指定列数据的平均值 | select SUm(StudentResult) from result 返回:数值71.1099 |
SELECT MAX(GradeId) from student;
SELECT MIN(GradeId) from student;
SELECT * FROM student;
SELECT COUNT(*) FROM student;
SELECT COUNT(1) FROM student;
-- 不能再添加其它列了
SELECT COUNT(1) , studentNo FROM student;
-- 模拟用户登录: 学号和密码
select IF(count(1) > 0 , '登录成功', '登录失败' ) from student WHERE StudentNo = '001' and LoginPwd = 123456;
SELECT count(1) , MAX(GradeId) from student;
SELECT SUM(ClassHour) as 总课时 , AVG(ClassHour) as 平均课时 from `subject`;
-- 把查询结果导入到一个新表(不用手动取创建),方便做数据分析
create table table_2 SELECT SUM(ClassHour) as 总课时 , AVG(ClassHour) as 平均课时 from `subject`;
/*20、统计学生总人数*/
select count(1) from student;
/*21、统计S1年级的总学时*/
select SUM(ClassHour) from `subject` where GradeId = 1;
-- 22、统计学号为S1101004的学生第一学期考试(要考什么?考Html还是Java)总成绩
select SUM(StudentResult) from result where StudentNo = 'S1101004'
and SubjectId in (1,2,3,4,16,17);
-- 使用子查询来实现
select SUM(StudentResult) from result where StudentNo = 'S1101004'
and SubjectId in (select SubjectId from `subject` where GradeId = 1);
-- 23、 统计学号为S1101004的学生第一学期所有考试的平均分 (这个学生是白燕)
select AVG(StudentResult) from result where StudentNo = 'S1101004'
and SubjectId in (select SubjectId from `subject` where GradeId = 1);
-- 24、 统计2013年3月22日科目“C#语言和数据库技术”的最高分、最低分、平均分
select MAX(StudentResult) 最高分 ,
MIN(StudentResult) 最低分 ,
AVG(StudentResult) 平均分
from result where ExamDate = '2013-3-22'
and SubjectId = 3; -- 为什么要写3,因为3就就是c#语言和数据库技术的科目编号
-- 25、统计2013年3月22日科目“C#语言和数据库技术”及格学生的平均分
select AVG(StudentResult) from result where ExamDate = '2013-3-22' and StudentResult >= 60
and SubjectId = 3;
-- 26、 统计所有参加“C#语言和数据库技术”科目考试的平均分
select AVG(StudentResult) from result where SubjectId = 3;
-- 27、 统计成绩表中所有成绩的总分数
select SUM(StudentResult) from result;
-- 28、统计成绩表中所有成绩的平均分数
select AVG(StudentResult) from result;
-- 29、 统计80分以上的平均分数
select AVG(StudentResult) from result where StudentResult > 80;
-- 30、 统计成绩表中最高分
select MAX(StudentResult) from result;
-- 先排序,在取第一条
select * from result ORDER BY StudentResult desc limit 1;
-- 31、统计成绩表中考试科目为“HTML和CSS网页技术”中最低分
select MIN(StudentResult) from `subject` where SubjectId = 2;
-- 32、 统计S1的平均课时
select AVG(ClassHour) from `subject` where GradeId = 1;
-- 33、统计13年11月15号考试的最高分
-- 34、统计13年9月13号到10月18号之间,科目为“c#语言和数据库技术”的最高分
SELECT MAX(StudentResult) from result where
(ExamDate BETWEEN '2013-9-13' and '2013-10-18') and SubjectId = 3;
-- 35、统计三门课程“走进Java编程世界`”,“HTML和CSS网页技术1”,“面向对象程序设计8”及格学生的平均分
select AVG(StudentResult) from result where StudentResult >= 60 and SubjectId in (1,2,8);
-- 36、 统计女生有多少个人
-- 37、统计S1有多少个人
-- 38、统计Y2没有邮箱的男生有多少个人
-- 39、统计住在“北京”的女生有多少人 2
-- 40、统计住在“学生宿舍”年龄是25岁的人数
select count(*) from student where Address like '%学生宿舍%' and
TIMESTAMPDIFF(YEAR,BornDate,NOW()) = 25;
分组查询
GROUP BY
HAING
-- 分组查询
-- 统计各年级人数 . 结果集会出现?行
/*
SELECT列表中只能包含:
1、被分组的列
2、每个分组只能返回一个值的表达式,如聚合函数
*/
select GradeId , COUNT(1) from student
group by student.GradeId;
-- 1 VS 多
-- Map
-- 需求2:统计男女各多少人?
select sex as 性别, count(1) as 人数 from student
GROUP BY sex;
-- 需求3:统计各年级的科目平均课时。。。
-- 思路:按照年级进行分组,然后统计每个组里面的ClassHour平均课时
-- 分组,你简单理解就是把表拆开了。拆成了多个子表
select GradeId , AVG(ClassHour) from `subject` GROUP BY GradeId;
-- 需求4:基于需求3,统计各年级的科目平均课时大于60分以上。
-- 对分组结果再进行筛选。。。。。。 对不起不能用where
select GradeId , AVG(ClassHour) from `subject`
GROUP BY GradeId
HAVING AVG(ClassHour) > 60; -- 对分组后的结果再及逆行筛选
-- 统计及格各学生的平均分
select StudentNo, AVG(StudentResult) from result
where StudentResult >= 60
GROUP BY StudentNo;
--
select StudentNo, AVG(StudentResult) from result
where StudentResult >= 60
GROUP BY StudentNo
HAVING AVG(StudentResult) > 80
ORDER BY AVG(StudentResult) desc
LIMIT 1;
-- where > GROUP BY > HAVING > ORDER BY > LIMIT
总结
1.从数据资源谈起,阐述了数据库的重要性、相关概念等;
2.介绍了MySQL数据库的DOS命令,数据类型,数据调优以及SQL分类;
3.列举了SQL常用的函数,包括字符串、日期、数学、流程、聚合、分组等语句;