天道酬勤,学无止境

mysql8.0新特性 之 窗口函数 使用示例及详解

什么是窗口函数

MySQL从8.0开始支持窗口函数,这个功能在大多数据库中早已支持,有的也叫分析函数。
窗口的概念非常重要,它可以理解为记录集合,窗口函数也就是在满足某种条件的记录集合上执行的特殊函数对于每条记录都要在此窗口内执行函数,有的函数随着记录不同,窗口大小都是固定的,这种属于静态窗口;有的函数则相反,不同的记录对应着不同的窗口,这种动态变化的窗口叫滑动窗口。简单的说窗口函数就是对于查询的每一行,都使用与该行相关的行进行计算。

窗口函数和普通聚合函数很容易混淆,二者区别如下:
    - 聚合函数是将多条记录聚合为一条;而窗口函数是每条记录都会执行,有几条记录执行完还是几条。
    - 聚合函数也可以用于窗口函数中。

窗口函数功能

名称描述
ROW_NUMBER()为分区中的每一行分配一个顺序整数【没有重复值的排序(记录相等也是不重复的),可以进行分页使用】
RANK()与DENSE_RANK()函数相似,不同之处在于当两行或更多行具有相同的等级时,等级值序列中存在间隙【跳跃排序】
DENSE_RANK()根据该ORDER BY子句为分区中的每一行分配一个等级。它将相同的等级分配给具有相等值的行。如果两行或更多行具有相同的排名,则排名值序列中将没有间隙【连续排序】
PERCENT_RANK()计算分区或结果集中行的百分数等级
CUME_DIST()计算一组值中一个值的累积分布
LAG()返回分区中当前行之前的第N行的值。如果不存在前一行,则返回NULL
LEAD()返回分区中当前行之后的第N行的值。如果不存在后续行,则返回NULL
FIRST_VALUE()返回相对于窗口框架第一行的指定表达式的值
LAST_VALUE返回相对于窗口框架中最后一行的指定表达式的值
NTH_VALUE()从窗口框架的第N行返回参数的值
NTILE()将每个窗口分区的行分配到指定数量的排名组中

将上述函数按照功能划分,可以把MySQL支持的窗口函数分为如下几类:

  • 序号函数:ROW_NUMBER()、RANK()、DENSE_RANK()
  • 分布函数:PERCENT_RANK()、CUME_DIST()
  • 前后函数:LAG()、LEAD()
  • 头尾函数:FIRST_VALUE()、LAST_VALUE()
  • 其他函数:NTH_VALUE()、NTILE()

函数示例

ROW_NUMBER()

语法格式:row_number() over(partition by 分组列 order by 排序列 desc);
在使用 row_number() over()函数时候,over()里头的分组以及排序的执行晚于 where 、group by、  order by 的执行。

创建数据表:
create table TEST_ROW_NUMBER_OVER(
       id varchar(10) not null,
       name varchar(10) null,
       age varchar(10) null,
       salary int null
);
select * from TEST_ROW_NUMBER_OVER t;
 
insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(1,'a',10,8000);
insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(1,'a2',11,6500);
insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(2,'b',12,13000);
insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(2,'b2',13,4500);
insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(3,'c',14,3000);
insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(3,'c2',15,20000);
insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(4,'d',16,30000);
insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(5,'d2',17,1800);
  1. 对查询结果进行排序
select id,name,age,salary,row_number()over(order by salary DESC) rn
from `TEST_ROW_NUMBER_OVER`

row_numer(),这个排序函数的特点是相同数据,先查出的排名在前,没有重复值。像这里的salary相同,先查出来的数据的rn排名优先
  1. 根据id分组排序
select id,name,age,salary,row_number()over(partition by id order by salary DESC) rn
from `TEST_ROW_NUMBER_OVER`

  1. 筛选以id分组查询后 序号为一的数据
select * from (select id,name,age,salary,row_number()over(partition by id order by salary DESC) rn
from TEST_ROW_NUMBER_OVER)
tt where rn = 1 

  1. 排序找出年龄在13岁到16岁数据,按salary排序
select id,name,age,salary,row_number()over(order by salary DESC) rn
from TEST_ROW_NUMBER_OVER where age between 13 and 16 

结果中 rank 的序号,其实就表明了 over(order by salary desc) 是在where age between and 后执行的

RANK()

select id,name,age,salary,rank()over(order by salary DESC) rn
from `TEST_ROW_NUMBER_OVER`

rank()函数,是跳跃排序,相同数据(这里为salary列相同)排名相同,比如并列第3,则两行数据(这里为rn列)都标为3,下一位将是第4名.中间的4被直接跳过了。排名存在重复值。

DENSE_RANK()

select id,name,age,salary,dense_rank()over(order by salary DESC) rn
from `TEST_ROW_NUMBER_OVER`

dense_rank(),这个是连续排序的,比如两条并列第3,则两行数据(这里为rn列)都标为3,下一个排名将是第4名

PERCENT_RANK()

select id,name,age,salary,percent_rank()over(order by salary DESC) rn
from `TEST_ROW_NUMBER_OVER`

percent_rank:(分组内当前行的值(第几行)-1)/(分组内总行数-1)
应用场景:不太了解

CUME_DIST()

select id,name,age,salary,cume_dist()over(order by salary DESC) rn
from `TEST_ROW_NUMBER_OVER`

cume_dist:求小于(或大于)等于当前值的行数/分组内总行数
使用场景:统计小于等于当前薪水的人数,占总人数比例

注意:CUME_DIST、PERCENT_RANK均不支持WINDOW子句(between...and...)

LAG() 、 LEAD()

Lag和Lead分析函数可以在同一次查询中取出同一字段的前N行的数据(Lag)和后N行的数据(Lead)作为独立的列
在实际应用当中,若要用到取今天和昨天的某字段差值时,Lag和Lead函数的应用就显得尤为重要。当然,这种操作可以用表的自连接实现,但是LAG和LEAD与left join、rightjoin等自连接相比,效率更高,SQL更简洁。下面我就对这两个函数做一个简单的介绍。

函数语法如下:
lag(exp_str,offset,defval) over(partion by …order by …)
lead(exp_str,offset,defval) over(partion by …order by …)

参数说明:
exp_str是字段名
Offset是偏移量,即是上1个或上N个的值,假设当前行在表中排在第10行,则offset 为3,则表示我们所要找的数据行就是表中的第7行(即10-3=7)。
Defval默认值,当两个函数取上N/下N个值,当在表中从当前行位置向前数N行已经超出了表的范围时,lag()函数将defval这个参数值作为函数的返回值,若没有指定默认值,则返回NULL,那么在数学运算中,总要给一个默认值才不会出错
  1. 对salary列:取上一个salary列作为单独的列,若不指定默认值,则默认值为NULL
select id,name,age,salary,rank()over(order by salary DESC) rn
from `TEST_ROW_NUMBER_OVER`

  1. 对salary列:取上一个salary列作为单独的列,指定默认值为0
select id,name,age,salary,lag(salary,1,0)over(order by salary DESC) rn
from `TEST_ROW_NUMBER_OVER`


3. 对salary列:取下一个salaryL列作为单独的列,指定默认值为0

select id,name,age,salary,lead(salary,1,0)over(order by salary DESC) rn
from `TEST_ROW_NUMBER_OVER`

  1. 运算:薪水跟上次相比涨了多少
select id,name,age,salary,p,salary-p as addsalary from
(select id,name,age,salary,lag(salary,1,0)over(order by salary DESC) p
from `TEST_ROW_NUMBER_OVER`) tt

FIRST_VALUE()、LAST_VALUE()

select id,name,age,salary,
first_value(salary)over(partition by id order by salary DESC) first_salary,
last_value(salary)over(partition by id order by salary DESC) last_salary
from `TEST_ROW_NUMBER_OVER`

first_value()的结果容易理解,直接在结果的所有行记录中输出同一个满足条件的首个记录;
last_value()默认统计范围是 rows between unbounded preceding and current row,也就是取当前行数据与当前行之前的数据的比较

那么如果我们直接在每行数据中显示最后的那个数据,需在order by 条件的后面加上语句:rows between unbounded preceding and unbounded following , 也就是前面无界和后面无界之间的行比较
select id,name,age,salary,
first_value(salary)over(partition by id order by salary DESC) first_salary,
last_value(salary)over(partition by id order by salary DESC rows between unbounded preceding and unbounded following) last_salary
from `TEST_ROW_NUMBER_OVER`

NTH_VALUE()

select id,name,age,salary,
nth_value(salary,3)over(order by id ASC) nth
from `TEST_ROW_NUMBER_OVER`

其中NTH_VALUE()中的第二个参数是指这个函数取排名第几的记录

NTILE()

SELECT id, name,age,salary, CASE NTILE (3) OVER (ORDER BY salary DESC) WHEN 1 THEN '高' WHEN 2 THEN '中' WHEN 3 THEN '低' END AS '级别' 
FROM TEST_ROW_NUMBER_OVER ORDER BY salary;

为什么salary同样是13000 一个高 一个中呢 ? 让我们来看下ntile的算法

ntile函数的分组依据(约定):

  • 每组的记录数不能大于它上一组的记录数,即编号小的桶放的记录数不能小于编号大的桶。也就是说,第1组中的记录数只能大于等于第2组及以后各组中的记录数。

  • 所有组中的记录数要么都相同,要么从某一个记录较少的组(命名为X)开始后面所有组的记录数都与该组(X组)的记录数相同。也就是说,如果有个组,前三组的记录数都是9,而第四组的记录数是8,那么第五组和第六组的记录数也必须是8。

    这里对约定2进行详细说明一下,以便于更好的理解。
    
    首先系统会去检查能不能对所有满足条件的记录进行平均分组,若能则直接平均分配就完成分组了;若不能,则会先分出一个组,这个组分多少条记录呢?就是 (总记录数/总组数)+1 条,之所以分配 (总记录数/总组数)+1 条是因为当不能进行平均分组时,总记录数%总组数肯定是有余的,又因为分组约定1,所以先分出去的组需要+1条。
    
    分完之后系统会继续去比较余下的记录数和未分配的组数能不能进行平均分配,若能,则平均分配余下的记录;若不能,则再分出去一组,这个组的记录数也是(总记录数/总组数)+1条。
    
    然后系统继续去比较余下的记录数和未分配的组数能不能进行平均分配,若能,则平均分配余下的记录;若还是不能,则再分配出去一组,继续比较余下的......这样一直进行下去,直至分组完成。
    
    举个例子,将51条记录分配成5组,51%5==1不能平均分配,则先分出去一组(51/5)+1=11条记录,然后比较余下的 51-11=40 条记录能否平均分配给未分配的4组,能平均分配,则剩下的4组,每组各40/4=10 条记录,分配完成,分配结果为:11,10,10,10,10
    

CTE()

MySQL的CTE是在MySQL8.0版本开始支持的,公用表表达式是一个命名的临时结果集,仅在单个SQL语句(例如select、insert、delete和update)的执行范围内存在。CTE分为递归CTE和非递归CTE。
CTE的出现简化了复杂查询语句的编写,提高了SQL性能。
  1. 非递归

    语法:
    WITH cte_name (column_list) AS (
    query
    ) 
    SELECT * FROM cte_name
    
    生成一个cte_name的派生表,然后再操作派生表
    

    🌰

    WITH age_list AS(
        select id,age,salary from `TEST_ROW_NUMBER_OVER` where salary > 10000
    )
    select * from age_list
    


    🌰🌰

    新建一个学生表 和 学校表 进行关联
    
    WITH student AS( 
    select id,username,school_id 
    from st_students 
    where username like '%浩南%'
    ),
    school AS(
    select student.id student_id,op_schools.id as school_id,`name`,address,student_count 
    from `op_schools` 
    right join student on school_id = op_schools.id
    )
    
    select student_id,school_id,`name`,student_count,row_number()over(partition by school_id order by student_count DESC) rn 
    from school 
    order by student_count DESC
    

  2. 递归

递归CTE概念:递归的方式是CTE的子查询可以引用其本身,使用递归方式时,WITH子句中要使用WITH RECURSIVE代替。递归CTE子句中必须包含两个部分,一个是种子查询(不可引用自身),另一个是递归查询,这两个子查询可以通过 UNION、UNION ALL或UNION DISTINCT 连接在一起。

注意:种子SELECT只会执行一次,并得到初始的数据子集,而递归SELECT是会重复执行直到没有新的行产生为止,最终将所有的结果集都查询出来,这对于深层查询(如具有父子关系的查询)是非常有用的。
CREATE TABLE emp(
id INT PRIMARY KEY NOT NULL,
name VARCHAR(100) NOT NULL,
manager_id INT NULL,
INDEX (manager_id)
)

----------------------------------------------

INSERT INTO emp VALUES
(333, "总经理", NULL), 
(198, "副总1", 333), 
(692, "副总2", 333),
(29, "主任1", 198),
(4610, "职员1", 29),
(72, "职员2", 29),
(123, "主任2", 692);

----------------------------------------------

WITH RECURSIVE test(id, name, path)
AS
(
SELECT id, name, CAST(id AS CHAR(200))
FROM emp WHERE manager_id IS NULL
UNION ALL
SELECT e.id, e.name, CONCAT(ep.path, ',', e.id)
FROM test AS ep JOIN emp AS e  ON ep.id = e.manager_id
 
)SELECT * FROM test ORDER BY path;

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 从零开始学前端 - 24. JS BOM之Window对象详解及常用方法
    作者: 她不美却常驻我心 博客地址: https://blog.csdn.net/qq_39506551 微信公众号:老王的前端分享 每篇文章纯属个人经验观点,如有错误疏漏欢迎指正。转载请附带作者信息及出处。 从零开始学前端 - 24. JS BOM之Window对象详解及常用方法 一、 window 相关知识点1、全局作用域2、窗口关系及框架父页面操纵子页面子页面操纵父页面 3、窗口位置4、窗口大小5、打开窗口6、 定时器7、弹出框 二、window 常用属性三、window 常用方法   Window 是 BOM 的核心对象,它表示浏览器的一个实例,也就是说, Window 对象只存在于浏览器环境中,在其他的环境内,是以 Global 为核心对象的。在浏览器中,Window 对象既是通过 JS 访问浏览器窗口的一个接口,又是 ECMAScript 规定的 Global 对象。这意味着在网页中定义的任何一个对象、变量和函数,都以 Window 作为其 Global 对象。   具体内容可以查看上一篇博客: JS Glabal 对象常用属性和方法。 一、 window 相关知识点 1、全局作用域   前面也提到了,在浏览器环境中,Window 对象代替了 Global 对象,因此所有在全局作用域中声明的变量、函数等内容都会变成 Window 对象的属性和方法。 var num =
  • 零基础入门 全角度解读企业主流数据库MySQL8.0 --- 复习笔记
    零基础入门 全角度解读企业主流数据库MySQL8.0 --- 复习笔记 第1章 【蓦然回首】开篇引导【少年,奋斗吧】1-1 【良好的开端】课程序言 试看 第2章 【上帝视角】技术选型之数据库选型【适用于志存高远的有志青年】2-1 NoSQL和SQL2-2 【天生我材必有用】关系型数据库的特点和适用场景2-3 【英雄的用武之地】非关系型数据库的特点和适用场景2-4 【心中有数】关系统型数据库选型步骤2-5 【合适比喜欢更重要】为项目选择适合的数据库---为什么使用mysql?2-6 【动动手】下载安装VirtualBox2-7 【装备就绪】准备虚拟服务器2-8 【跟着做】安装CentOS系统2-9 【动动手】配置CentOS系统2-10 【认真听】部署MySQL8.0.15之简介2-11 【认真看】部署MySQL8.0.152-12 【动手做】配置MySQL8.0.152-13 【跟上节奏】初始化MySQL8.0.152-14 【知识回顾】本章总结. 第3章 【设计师视角】关于数据库设计-程序猿必备技【适用于让你的才华撑起你的野心】3-1 【前情提要】数据库结构设计N部曲3-2 实战项目需求分析3-3 实战项目需求总结3-4 宽表模式3-5 宽表模式的数据更新异常3-6 宽表模式的数据插入异常3-7 宽表模式的适用场景3-8 数据库第一设计范式3-9 数据库第二设计范式3-10
  • MySQL8.0之快速加列
    MySQL8.0之快速加列 一、什么是Online DDL1.1 基本概念1.2 Online DDL语法1.3 Online DDL ALGORITHM选项详解1.4 Online DDL基本流程1.5 Online DDL空间要求1.6 Online DDL存在的问题 二、类型支持三、快速加列3.1 快速加列支持类型3.2 立刻加列的限制3.3 立刻加列的实现 四、总结   在正式介绍MySQL8.0的快速加列特性前,先来了解下什么是Online DDL,为什么需要快速加列这一特性。 一、什么是Online DDL 1.1 基本概念   Online DDL是在MySQL5.6版本后加入的特性,在5.7得到增强,Online DDL提供了在表更改过程中并发执行DML的功能。 1.2 Online DDL语法   具体语法如下: alter table ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT} ADD [COLUMN] col_name column_definition [FIRST|AFTER col_name] CHANGE [COLUMN] old_col_name new_col_name column_definition [FIRST|AFTER col_name] MODIFY
  • Java知识体系大纲
    性能调优专题 Jvm性能调优 JVM类加载机制详解 从JDK源码(C++)级别深度剖析类加载全过程 启动类、扩展类、应用程序类加载器源码深度剖析 类加载双亲委派机制及如何打破详解<br> 手写自定义类加载器 Tomcat类加载机制源码剖析 JVM内存模型 堆内存分代机制及对象生命周期详解 线程栈及栈帧内部结构详解 方法区(元空间)及常量池详解(深入到Hotspot底层C++级别解析) 程序计数器详解 本地方法栈详解 类字节码文件深度剖析 数据类型 无符号数 表 组成 0~3字节:魔数:文件类型 4~7字节:jdk本号 常量池 字面量:常量字符串、final常量值 符号引用 类和接口的fully Qualified Name 字段的方法和描述符 方法的名称和描述符 u2访问标志:类/接口、public、final、abstract 继承关系 u2类索引:类的全限定名 u2父索引:父类的全限定名 nu2+1接口索引:实现接口的全新定名 字段表集合:描述接口、变量 u2访问标志 u2 name_index u2 descriptor_index u2 attributes_count u2 attributes 方法表集合:描述方法 属性表集合 code属性 exception属性 LineNumberTable属性 LocalVariableTable属性 sourceFile属性
  • MySQL8.0新特性学习笔记(二):窗口函数
    目录 一,简介 二,窗口函数的两种写法 三,窗口表达式语法 1,PARTITION BY子句 2,ORDER BY子句 3,frame子句 四,窗口函数介绍 1,序号函数:row_number(),rank(),dense_rank() 2,分布函数:percent_rank() / cume_dist() 3,前后函数:lead() / lag() 4,头尾函数:first_val() / last_val() 5,其他函数:nth_value() / nfile() 6,原生聚合函数 MySQL8.0引入的窗口函数,可以比较方便的实现一些分析和统计功能,这些功能不用窗口函数也能实现,不过实现的sql可能会比较复杂。 一,简介 什么是窗口函数 窗口函数引入的其实不只是几个函数,而是一套完整的语法,窗口函数是此语法中的一部分。 语法: 窗口函数 over 窗口表达式。 over是窗口函数语法的关键字。 从语法上来看,窗口函数的使用实际上分为两部分:窗口函数和窗口。 窗口函数在sql中往往使用在查询结果中,返回一列值,就像查询一个字段一样。 窗口 从数据结构上来看,要使用窗口函数,首先我们要有一个窗口,所谓窗口,个人理解是一个数据集,数据集的内容可以类比group by分组之后的一组数据,只不过在使用了窗口函数的sql中,每一行记录都有一个自己的窗口,每行记录所对应的窗口
  • MySQL8.0(截止8.0.21)新特性汇总
    1. 默认字符集由latin1变为utf8mb4 在8.0版本之前,默认字符集为latin1,utf8指向的是utf8mb3,8.0版本默认字符集为utf8mb4,utf8默认指向的也是utf8mb4。 注:在Percona Server 8.0.15版本上测试,utf8仍然指向的是utf8mb3,与官方文档有出入。 2. MyISAM系统表全部换成InnoDB表 系统表全部换成事务型的innodb表,默认的MySQL实例将不包含任何MyISAM表,除非手动创建MyISAM表。之前的系统库mysql目录中为空,系统表存在于数据目录下面的mysql.ibd文件中。 3. 自增变量持久化 在8.0之前的版本,自增主键AUTO_INCREMENT的值如果大于max(primary key)+1,在MySQL重启后,会重置AUTO_INCREMENT=max(primary key)+1,这种现象在某些情况下会导致业务主键冲突或者其他难以发现的问题。 4. DDL原子化 InnoDB表的DDL支持事务完整性,要么成功要么回滚,将DDL操作回滚日志写入到data dictionary 数据字典表 mysql.innodb_ddl_log 中用于回滚操作,该表是隐藏的表,通过show tables无法看到。通过设置参数,可将ddl操作日志打印输出到mysql错误日志中。 mysql> set
  • 马哥教育11期高薪就业课程设置(网络班课程与此同步)(初稿)
    计算机专业的同学,学习了林林总总的数十科课程、掌握了专业所需要知识的结构以后,就该努力构建自身的核心竞争力了。不然,在专业细分、人才倍出的年代,想要安身立命直至实现个人价值难如登天。马哥教育第十一期课程的推出,是在调研了此前就业同学的实际情况、及多家企业的实际相关岗位需求,并结合相关岗位职业生崖发展的两到三年间快速成长的需要而制订出的,是帮助有志者强力构建自身核心竞争力的给力课程体系!我们课程的特色:实践与理论并重,努力让朋友们知其然,更知其所以然,而且尽量实现“授之以渔”!与国类似的培训机构的课程相比,我们的巨大优势之一在于力图深入浅地讲清楚每个理论知识点,而后再演示其实现,让朋友们既要知道如何做,更要知道为什么这么做,甚至如何换个方法做。我们已经公开不少视频片断,请有兴趣的朋友们下载观看(免费在线试听内容 ),并欢迎提出各种意见和建议!我们的培训以训练营的方式进行,知识讲解密集度大,因此充分课时时间可以保证学习的质量!课程时间安排为每周5天课,一般是上3天体息1天,而后上2天休息1天,以给同学们留下一些消化的时间;同时,根据课程难度和当期同学们的接受情况,课程进度还有不定期调整,因此,整套课程的时间在3个月左右。此外,我们的课堂时间基本属于讲7练3,即7成时间在讲课,最多3成时间用于练习,而要想保证学习效果,同学们就必须大量利用课余时间进行,这也就着我们的课程强度很大
  • Java8 Stream新特性详解及实战
    Java8 Stream新特性详解及实战 背景介绍 在阅读Spring Boot源代码时,发现Java 8的新特性已经被广泛使用,如果再不学习Java8的新特性并灵活应用,你可能真的要out了。为此,针对Java8的新特性,会更新一系列的文章,欢迎大家持续关注。 首先,我们来看一下Spring Boot源代码ConfigFileApplicationListener类中的一段代码: private List<Profile> getOtherActiveProfiles(Set<Profile> activatedViaProperty) { return Arrays.stream(this.environment.getActiveProfiles()).map(Profile::new) .filter((profile) -> !activatedViaProperty.contains(profile)) .collect(Collectors.toList()); } 这段代码怎么?够简洁明快吧,如果不使用Java8的新特性,想象一下得多少行代码才能实现?但如果没掌握或不了解Java8的新特性,这段代码读起来是不是很酸爽? Java 8的API中新增了一个处理集合的抽象概念:Stream,中文称作“流”。它可以指定你希望对集合进行的操作,可以执行非常复杂的查找
  • Ocelot简易教程(三)之主要特性及路由详解
    上篇《Ocelot简易教程(二)之快速开始2》教大家如何快速跑起来一个ocelot实例项目,也只是简单的对Ocelot进行了配置,这篇文章会给大家详细的介绍一下Ocelot的配置信息。希望能对大家深入使用Ocelot有所帮助。上篇中也提到了,最简单的Ocelot如下面所示,只有简单的两个节点,一个是ReRoutes,另一个就是GlobalConfiguration关于这两个节点的作用,上篇也已经讲述了,这里再简单的讲下ReRoutes:告诉Ocelot如何处理上游的请求。GlobalConfiguration:顾名思义就是全局配置,此节点的配置允许覆盖ReRoutes里面的配置,你可以在这里进行通用的一些配置信息。下面呢给出ReRoute 的所有的配置信息,当然在实际使用的时候你没有必要全部进行配置,只需要根据你项目的实际需要进行相关的配置就可以了。当然上面的配置项我就不一一的进行介绍,因为很多配置相信大家根据意思都能知道个大概了。我只会对比较常用的配置做下介绍。而且在接下来的文章中对对每个节点进行单独的详细的介绍。在介绍之前呢先看Ocelot的几个特性。Ocelot特性介绍合并配置文件这个特性允许用户创建多个配置文件来方便的对大型项目进行配置。试想一下,如果你的项目有几十个路由规则需要配置的话,那么在一个配置文件进行配置应该很痛苦吧,有了这个特性后,你就可以创建多个配置文件
  • MySQL8.0新特性学习笔记(四):Hash Join
    目录 准备工作一:驱动表和被驱动表 准备工作二:MySQL8.0之前的连接方式 Hash Join MySQL8.0正式引入了Hash Join的连接方式,下面介绍一下这种连接方式,并且和之前的连接方式做一下对比。 准备工作一:驱动表和被驱动表 比如这样一个使用了连接的sql: SELECT * from tableA join tableB on tableA.code=tableB.code; tableA和tableB通过code字段进行关联,一般情况下,MySQL的查询优化器会先选择其中一个表作为驱动表,假设选择了表A,那么表A是驱动表,驱动表的作用就是,遍历驱动表的每一条记录,对于某条记录中的code,从另外一个表B中查询对应的记录,然后把两条记录做关联,那么表B就是被驱动表。 实际情况中查询优化器会按照自己的逻辑选择驱动表和被驱动表。 准备工作二:MySQL8.0之前的连接方式 在MySQL8.0引入Hash Join之前,使用的是经典的Nested Loops Join(NLJ)算法,嵌套循环算法。 Nested Loops Join有以下几种演进版本: 1,Simple Nested Loops Join(SNLJ),简单嵌套循环算法 连接双方在连接字段上都没有索引,所以此算法没有什么套路,从驱动表取出记录,按照join的条件在被驱动表中查询,找到可连接的记录
  • 【爬虫】利用Python爬虫爬取小麦苗itpub博客的所有文章的连接地址(1)
    【爬虫】利用Python爬虫爬取小麦苗itpub博客的所有文章的连接地址(1)爬取结果:火狐(Firefox)如何移除add security exception添加的网站:http://blog.itpub.net/26736162/viewspace-2286064/ 如何将网页保存成mhtml格式:http://blog.itpub.net/26736162/viewspace-2285988/ Windows下安装MongoDB:http://blog.itpub.net/26736162/viewspace-2285966/ 【爬虫】python爬虫从入门到放弃:http://blog.itpub.net/26736162/viewspace-2285848/ 【爬虫】网页抓包工具--Charles的使用教程:http://blog.itpub.net/26736162/viewspace-2285754/ 【爬虫】网页抓包工具--Fiddler:http://blog.itpub.net/26736162/viewspace-2285735/ Tesseract-OCR的使用---提取图片中的文字(OneNote):http://blog.itpub.net/26736162/viewspace-2285595/ 【PDB升级】12.1.0.2的PDB升级到12.2.0
  • python编程入门与案例详解-&quot;Python小屋”免费资源汇总(截至2018年11月28日)...
    原标题:"Python小屋”免费资源汇总(截至2018年11月28日) 为方便广大Python爱好者查阅和学习,特整理汇总微信公众号"Python小屋”开通29个月以来推送过的700多篇文章清单,如果需要本清单的电子版,可以在公众号后台发送消息"资源汇总”获取下载地址。 非计算机专业《Python程序设计基础》教学参考大纲 计算机相关专业"Python程序设计”教学大纲(参考) 《Python程序设计》实验指导书(30个实验) 《Python程序设计基础与应用》课后习题答案 系列PPT: 1900页Python系列PPT分享一:基础知识(106页) 1900页Python系列PPT分享二:Python序列(列表、元组、字典、集合)(154页) 1900页Python系列PPT分享三:选择与循环结构语法及案例(96页) 1900页Python系列PPT分享四:字符串与正则表达式(109页) 1900页Python系列PPT分享五:函数设计与应用(134页) 1900页Python系列PPT分享六:面向对象程序设计(86页) 1900页Python系列PPT分享七:文件操作(132页) 1900页Python系列PPT分享八:异常处理结构与程序调试、测试(70页) 报告PPT(163页):基于Python语言的课程群建设探讨与实践 报告PPT(123页):Python编程基础精要
  • Java8 Period.between方法坑及注意事项
    在使用Java8 新特性中关于Period.between的方法时需注意该方法获取日期的区间问题。 @Test public void test1(){ LocalDate from = LocalDate.of(2018,10,1); System.out.println(Period.between(from,LocalDate.now()).getDays()); } 首先,猜测一下上面的代码返回的天数是多少?15天,你猜对了吗? 如果不理解为什么是15天,那么咱们再打印一下其他的心气,你可能就明白了。 @Test public void test1(){ LocalDate from = LocalDate.of(2017,9,1); Period period = Period.between(from,LocalDate.now()); System.out.println("2017-09-01到当前日期" LocalDate.now()); System.out.println("距离当前多少年:" period.getYears()); System.out.println("距离当前多少月:" period.getMonths()); System.out.println("距离当前多少日:" period.getDays()); } 在此执行程序,打印日志如下
  • 2020年前端知识复习必读文章
    1. JavaScript 基础 1.1 执行上下文/作用域链/闭包 理解 JavaScript 中的执行上下文和执行栈 JavaScript深入之执行上下文栈 一道js面试题引发的思考 JavaScript深入之词法作用域和动态作用域 JavaScript深入之作用域链 发现 JavaScript 中闭包的强大威力 JavaScript闭包的底层运行机制 我从来不理解JavaScript闭包,直到有人这样向我解释它... 破解前端面试(80% 应聘者不及格系列):从闭包说起 1.2 this/call/apply/bind JavaScript基础心法——this JavaScript深入之从ECMAScript规范解读this 前端基础进阶(七):全方位解读this 面试官问:JS的this指向 JavaScript深入之call和apply的模拟实现 JavaScript基础心法—— call apply bind 面试官问:能否模拟实现JS的call和apply方法 回味JS基础:call apply 与 bind 面试官问:能否模拟实现JS的bind方法 不用call和apply方法模拟实现ES5的bind方法 1.3 原型/继承 深入理解 JavaScript 原型 【THE LAST TIME】一文吃透所有JS原型相关知识点 重新认识构造函数、原型和原型链
  • JavaSE 8基础知识(一)Java8新特性之lambda表达式详解
    Java SE 8都有哪些新特性,包括哪些内容(一)? 本文内容参考自Java8标准 再次感谢尚硅谷教学资料对本文的启发! 接着上一篇博文的内容,在上一篇博文中提到,为了适应不断变化的需求(根据年龄筛选集合或者根据收入筛选集合或者根据其它内容等),我们特意创建了一个接口MyPredicate< T >来代表这种需求,同时将这个接口类型放入了主体方法的形式参数中,以便在调用主体方法的时候,能传入不同的实际需求的对象(多态,这些需求对象的类都必须implements这个接口),在最后的测试环节中引出了lambda表达式(本该传一个实际需求的对象,我们直接传入了一个lambda表达式): ①、先规定一个接口 在上一篇博文中规定这个接口是代表需求类型:MyPredicate< T >,但是在这篇博文中,这个接口是为lambda表达式准备的。 //为使用lambda表达式准备的接口,实际上它代表的还是需求。 public interface MyPredicate<T>{ //这里为什么规定方法的返回值为boolean类型 //继续往下看就知道了,因为这个方法 //需要在if语句中使用。 boolean test(T t); } ②、再规定一个方法(WorkOnAll(List list,MyPredicate m)),这个接口是这个方法的形式参数,同时创建一个集合list,进行测试 /
  • python代码案例详解-Python代码样例列表
    扫描左上角二维码,关注公众账号 数字货币量化投资,回复“Python例子”,获取以下600个Python经典例子源码 ├─algorithm │ Python用户推荐系统曼哈顿算法实现.py │ NFA引擎,Python正则测试工具应用示例.py │ Python datetime计时程序的实现方法.py │ python du熊学斐波那契实现.py │ python lambda实现求素数的简短代码.py │ Python localtime()方法计算今天是一年中第几周.py │ Python math方法算24点代码详解.py │ Python 类快速排序方法找到第定n小数的方法.py │ python3.2循环单词求和功能.py │ python单链表、二叉树的操作方法面试题.py │ Python大数运算之竖式乘法程序.py │ python子网掩码格式转换工具源代码.py │ Python完成计算三维矢量幅度的方法源码.py │ Python实现折半二分查询方法.py │ Python实现求素数操作示例.py │ Python实现的几个常见的排序算法.py │ python实现逆波兰计算简单方法.py │ Python对RSA算法的简单实现.py │ Python常见排序算法实现与测速源码.py │ Python应用global变量找有效数字.py │
  • 2020 BAT大厂面试经验:最全大数据+AI方向面试100题(附答案详解)
    “高频面经“系列共分为五篇,数据分析篇、数据结构与算法篇、大数据研发篇、机器学习篇和深度学习篇,每篇20问,共100问。这“100问”,与其说是面试中出现频率较高的“考题”,更不如说是大数据和AI方向构建完整知识体系的“知识点”。点击下方各篇链接即可进入查阅相应参考答案,更好内容直接关注公众号“雨云飞”回复“学习资料”获取! 欢迎关注作者微信公众号:涉及数据分析与挖掘、数据结构与算法、大数据与机器学习等内容 目录 数据分析篇 数据结构与算法篇 大数据研发篇 机器学习篇 深度学习篇 数据分析篇 数据分析主要侧重产品sence与Hive使用 目录 Mysql中索引是什么?建立索引的目的?sql语句执行顺序?数据库与数据仓库的区别?OLTP和OLAP的区别?行存储和列存储的区别?Hive执行流程?Hive HDFS HBase区别?数仓中ODS、DW、DM概念及区别?窗口函数是什么?实现原理?数仓中维度建模含义?有哪几种模式?Hive数据倾斜表现、原因及处理?用Python怎么进行数据分析?数据缺失值处理办法Excel中数据透视表,vlookup?AB测试与假设检验?TO C指标体系?如果次留下降了 5%该怎么分析?贝叶斯公式复述并解释应用场景CPA、CPS、CPM、CPT、CPC 是什么?AARRR模型是什么? 数据结构与算法篇 数据结构与算法侧重核心思路阐述和手撕代码 目录
  • [网络安全自学篇] 七十六.逆向分析之OllyDbg动态调试工具(二)INT3断点、反调试、硬件断点与内存断点
    这是作者网络安全自学教程系列,主要是关于安全工具和实践操作的在线笔记,特分享出来与博友们学习,希望您喜欢,一起进步。前文分享了Vulnhub靶机渗透题目bulldog,包括信息收集及目录扫描、源码解读及系统登陆、命令注入和shell反弹、权限提升和获取flag。这篇文章将讲解逆向分析之OllyDbg动态调试工具,包括INT3断点、反调试、硬件断点和内存断点。基础性文章,希望对您有所帮助。 同时建议先看前一篇文章:逆向分析之OllyDbg动态调试工具(一)基础入门及TraceMe案例分析 作者作为网络安全的小白,分享一些自学基础教程给大家,主要是关于安全工具和实践操作的在线笔记,希望您们喜欢。同时,更希望您能与我一起操作和进步,后续将深入学习网络安全和系统安全知识并分享相关实验。总之,希望该系列文章对博友有所帮助,写文不易,大神们不喜勿喷,谢谢!如果文章对您有帮助,将是我创作的最大动力,点赞、评论、私聊均可,一起加油喔~ 文章目录 一.常用断点之INT3断点1.查看INT3断点2.INT3原理3.INT3例子 二.INT3断点的反调试与反反调试三.常用断点之硬件断点原理解析四.常用断点之内存断点原理解析五.总结 PS:本文参考了github、安全网站和参考文献中的文章(详见参考文献),并结合自己的经验和实践进行撰写,也推荐大家阅读参考文献。 作者的github资源: 软件安全
  • python代码示例-Python代码样例列表
    ├─algorithm │ Python用户推荐系统曼哈顿算法实现.py │ NFA引擎,Python正则测试工具应用示例.py │ Python datetime计时程序的实现方法.py │ python du熊学斐波那契实现.py │ python lambda实现求素数的简短代码.py │ Python localtime()方法计算今天是一年中第几周.py │ Python math方法算24点代码详解.py │ Python 类快速排序方法找到第定n小数的方法.py │ python3.2循环单词求和功能.py │ python单链表、二叉树的操作方法面试题.py │ Python大数运算之竖式乘法程序.py │ python子网掩码格式转换工具源代码.py │ Python完成计算三维矢量幅度的方法源码.py │ Python实现折半二分查询方法.py │ Python实现求素数操作示例.py │ Python实现的几个常见的排序算法.py │ python实现逆波兰计算简单方法.py │ Python对RSA算法的简单实现.py │ Python常见排序算法实现与测速源码.py │ Python应用global变量找有效数字.py │ Python排序之直接插入排序方法.py │ Python方法如何将普通IP转换为十进制IP.py │ python方法求开方牛顿
  • python语言实例-Python代码样例列表
    ├─algorithm │ Python用户推荐系统曼哈顿算法实现.py │ NFA引擎,Python正则测试工具应用示例.py │ Python datetime计时程序的实现方法.py │ python du熊学斐波那契实现.py │ python lambda实现求素数的简短代码.py │ Python localtime()方法计算今天是一年中第几周.py │ Python math方法算24点代码详解.py │ Python 类快速排序方法找到第定n小数的方法.py │ python3.2循环单词求和功能.py │ python单链表、二叉树的操作方法面试题.py │ Python大数运算之竖式乘法程序.py │ python子网掩码格式转换工具源代码.py │ Python完成计算三维矢量幅度的方法源码.py │ Python实现折半二分查询方法.py │ Python实现求素数操作示例.py │ Python实现的几个常见的排序算法.py │ python实现逆波兰计算简单方法.py │ Python对RSA算法的简单实现.py │ Python常见排序算法实现与测速源码.py │ Python应用global变量找有效数字.py │ Python排序之直接插入排序方法.py │ Python方法如何将普通IP转换为十进制IP.py │ python方法求开方牛顿