二百七十六、ClickHouse——Hive和ClickHouse非常不同的DWS指标数据SQL语句
一、目的
在完成数据之后对业务指标进行分析,Hive和ClickHouseSQL真不一样
二、部分业务指标表
2.1 统计数据流量表1天周期
2.1.1 Hive中原有代码
2.1.1.1 Hive中建表语句
--1、统计数据流量表——动态分区——1天周期 create table if not exists hurys_db.dws_statistics_volume_1day(device_no string comment '设备编号',scene_name string comment '场景名称',lane_no int comment '车道编号',lane_direction string comment '车道流向',section_no int comment '断面编号',device_direction string comment '雷达朝向',sum_volume_day int comment '每天总流量',week_day string comment '周几',month string comment '月份' ) comment '统计数据流量表——动态分区——1天周期' partitioned by (day string) stored as orc ;
2.1.1.2 Hive中SQL语句
--动态加载数据 insert overwrite table hurys_db.dws_statistics_volume_1day partition(day) selectdwd_st.device_no,dwd_sc.scene_name,dwd_st.lane_no,dwd_rl.lane_direction,dwd_st.section_no,dwd_rc.device_direction,sum(volume_sum) sum_volume_day,case when pmod(datediff(create_time,'2023-11-27') + 1,7) = 1 then '周一'when pmod(datediff(create_time,'2023-11-27') + 1,7) = 2 then '周二'when pmod(datediff(create_time,'2023-11-27') + 1,7) = 3 then '周三'when pmod(datediff(create_time,'2023-11-27') + 1,7) = 4 then '周四'when pmod(datediff(create_time,'2023-11-27') + 1,7) = 5 then '周五'when pmod(datediff(create_time,'2023-11-27') + 1,7) = 6 then '周六'else '周日' end as week_day,substr(day,1,7) month,day from hurys_db.dwd_statistics as dwd_stright join hurys_db.dwd_radar_lane as dwd_rlon dwd_rl.device_no=dwd_st.device_no and dwd_rl.lane_no=dwd_st.lane_noright join hurys_db.dwd_device_scene as dwd_dson dwd_ds.device_no=dwd_st.device_noright join hurys_db.dwd_scene as dwd_scon dwd_sc.scene_id = dwd_ds.scene_idright join hurys_db.dwd_radar_config as dwd_rcon dwd_rc.device_no=dwd_st.device_no where dwd_st.create_time is not null and dwd_st.day='2024-09-05' group by dwd_st.device_no, dwd_sc.scene_name, dwd_st.lane_no, dwd_rl.lane_direction, dwd_st.section_no, dwd_rc.device_direction, case when pmod(datediff(create_time,'2023-11-27') + 1,7) = 1 then '周一'when pmod(datediff(create_time,'2023-11-27') + 1,7) = 2 then '周二'when pmod(datediff(create_time,'2023-11-27') + 1,7) = 3 then '周三'when pmod(datediff(create_time,'2023-11-27') + 1,7) = 4 then '周四'when pmod(datediff(create_time,'2023-11-27') + 1,7) = 5 then '周五'when pmod(datediff(create_time,'2023-11-27') + 1,7) = 6 then '周六'else '周日' end, day ;
2.1.2 ClickHouse中现有代码
2.1.2.1 ClickHouse中表结构
--1、统计数据流量表——动态分区——1天周期 create table if not exists hurys_jw.dws_statistics_volume_1day(device_no String comment '设备编号',scene_name String comment '场景名称',lane_no Nullable(Int32) comment '车道编号',lane_direction Nullable(String) comment '车道流向',section_no Nullable(Int32) comment '断面编号',device_direction Nullable(String) comment '雷达朝向',sum_volume_day Nullable(Int32) comment '每天总流量',week_day Nullable(String) comment '周几',month Nullable(String) comment '月份',day Date comment '日期' ) ENGINE = MergeTree PARTITION BY day PRIMARY KEY day ORDER BY day SETTINGS index_granularity = 8192;
2.1.2.2 ClickHouse中SQL语句
--动态加载数据 selectdwd_st.device_no,dwd_sc.scene_name,dwd_st.lane_no,dwd_rl.lane_direction,dwd_st.section_no,dwd_rc.device_direction,sum(volume_sum) sum_volume_day, case when toDayOfWeek(create_time) = 1 then '周一'when toDayOfWeek(create_time) = 2 then '周二'when toDayOfWeek(create_time) = 3 then '周三'when toDayOfWeek(create_time) = 4 then '周四'when toDayOfWeek(create_time) = 5 then '周五'when toDayOfWeek(create_time) = 6 then '周六'when toDayOfWeek(create_time) = 7 then '周日'end as week_day, concat(toString(toYear(dwd_st.day)), '-', lpad(toString(toMonth(dwd_st.day)), 2, '0')) AS month,cast(dwd_st.day as String) day from hurys_jw.dwd_statistics as dwd_stright join hurys_jw.dwd_radar_lane as dwd_rlon dwd_rl.device_no=dwd_st.device_no and dwd_rl.lane_no=dwd_st.lane_noright join hurys_jw.dwd_device_scene as dwd_dson dwd_ds.device_no=dwd_st.device_noright join hurys_jw.dwd_scene as dwd_scon dwd_sc.scene_id = dwd_ds.scene_idright join hurys_jw.dwd_radar_config as dwd_rcon dwd_rc.device_no=dwd_st.device_no where dwd_st.create_time is not null and dwd_st.lane_no is not null and dwd_st.day >= ? group by dwd_st.device_no, dwd_sc.scene_name, dwd_st.lane_no, dwd_rl.lane_direction, dwd_st.section_no, dwd_rc.device_direction, case when toDayOfWeek(create_time) = 1 then '周一'when toDayOfWeek(create_time) = 2 then '周二'when toDayOfWeek(create_time) = 3 then '周三'when toDayOfWeek(create_time) = 4 then '周四'when toDayOfWeek(create_time) = 5 then '周五'when toDayOfWeek(create_time) = 6 then '周六'when toDayOfWeek(create_time) = 7 then '周日'end, dwd_st.day ;
2.2 统计数据流量表5分钟周期
2.2.1 Hive中原有代码
2.2.1.1 Hive中建表语句
--5、统计数据流量表——动态分区——5分钟周期 create table if not exists hurys_db.dws_statistics_volume_5min(device_no string comment '设备编号',scene_name string comment '场景名称',lane_no int comment '车道编号',lane_direction string comment '车道流向',section_no int comment '断面编号',device_direction string comment '雷达朝向',sum_volume_5min int comment '每5分钟总流量',start_time timestamp comment '开始时间' ) comment '统计数据流量表——动态分区——5分钟周期' partitioned by (day string) stored as orc ;
2.2.1.2 Hive中SQL语句
--动态加载数据 insert overwrite table hurys_db.dws_statistics_volume_5min partition(day) selectdwd_st.device_no,dwd_sc.scene_name,dwd_st.lane_no,dwd_rl.lane_direction,dwd_st.section_no,dwd_rc.device_direction,sum(volume_sum) sum_volume_5min,case when minute(create_time ) < 5 thenconcat(substr(create_time, 1, 14), '00:00')when minute(create_time) >=5 and minute(create_time) <10 thenconcat(substr(create_time, 1, 14), '05:00')when minute(create_time) >=10 and minute(create_time) <15 thenconcat(substr(create_time, 1, 14), '10:00')when minute(create_time) >=15 and minute(create_time) <20 thenconcat(substr(create_time, 1, 14), '15:00')when minute(create_time) >=20 and minute(create_time) <25 thenconcat(substr(create_time, 1, 14), '20:00')when minute(create_time) >=25 and minute(create_time) <30 thenconcat(substr(create_time, 1, 14), '25:00')when minute(create_time) >=30 and minute(create_time) <35 thenconcat(substr(create_time, 1, 14), '30:00')when minute(create_time) >=35 and minute(create_time) <40 thenconcat(substr(create_time, 1, 14), '35:00')when minute(create_time) >=40 and minute(create_time) <45 thenconcat(substr(create_time, 1, 14), '40:00')when minute(create_time) >=45 and minute(create_time) <50 thenconcat(substr(create_time, 1, 14), '45:00')when minute(create_time) >=50 and minute(create_time) <55 thenconcat(substr(create_time, 1, 14), '50:00')elseconcat(substr(create_time, 1, 14), '55:00') end as start_time,day from hurys_db.dwd_statistics as dwd_stright join hurys_db.dwd_radar_lane as dwd_rlon dwd_rl.device_no=dwd_st.device_no and dwd_rl.lane_no=dwd_st.lane_noright join hurys_db.dwd_device_scene as dwd_dson dwd_ds.device_no=dwd_st.device_noright join hurys_db.dwd_scene as dwd_scon dwd_sc.scene_id = dwd_ds.scene_idright join hurys_db.dwd_radar_config as dwd_rcon dwd_rc.device_no=dwd_st.device_no where dwd_st.create_time is not null and dwd_st.day='2024-09-05' group by dwd_st.device_no, dwd_sc.scene_name, dwd_st.lane_no, dwd_rl.lane_direction, dwd_st.section_no, dwd_rc.device_direction, case when minute(create_time ) < 5 thenconcat(substr(create_time, 1, 14), '00:00')when minute(create_time) >=5 and minute(create_time) <10 thenconcat(substr(create_time, 1, 14), '05:00')when minute(create_time) >=10 and minute(create_time) <15 thenconcat(substr(create_time, 1, 14), '10:00')when minute(create_time) >=15 and minute(create_time) <20 thenconcat(substr(create_time, 1, 14), '15:00')when minute(create_time) >=20 and minute(create_time) <25 thenconcat(substr(create_time, 1, 14), '20:00')when minute(create_time) >=25 and minute(create_time) <30 thenconcat(substr(create_time, 1, 14), '25:00')when minute(create_time) >=30 and minute(create_time) <35 thenconcat(substr(create_time, 1, 14), '30:00')when minute(create_time) >=35 and minute(create_time) <40 thenconcat(substr(create_time, 1, 14), '35:00')when minute(create_time) >=40 and minute(create_time) <45 thenconcat(substr(create_time, 1, 14), '40:00')when minute(create_time) >=45 and minute(create_time) <50 thenconcat(substr(create_time, 1, 14), '45:00')when minute(create_time) >=50 and minute(create_time) <55 thenconcat(substr(create_time, 1, 14), '50:00')elseconcat(substr(create_time, 1, 14), '55:00') end, day ;
2.2.2 ClickHouse中现有代码
2.2.2.1 ClickHouse中表结构
--5、统计数据流量表——动态分区——5分钟周期 create table if not exists hurys_jw.dws_statistics_volume_5min(device_no String comment '设备编号',scene_name String comment '场景名称',lane_no Nullable(Int32) comment '车道编号',lane_direction Nullable(String) comment '车道流向',section_no Nullable(Int32) comment '断面编号',device_direction Nullable(String) comment '雷达朝向',sum_volume_5min Nullable(Int32) comment '每5分钟总流量',start_time DateTime comment '开始时间',day Date comment '日期' ) ENGINE = MergeTree PARTITION BY day PRIMARY KEY day ORDER BY day SETTINGS index_granularity = 8192;
2.2.2.2 ClickHouse中SQL语句
--动态加载数据
selectdwd_st.device_no,dwd_sc.scene_name,dwd_st.lane_no,dwd_rl.lane_direction,dwd_st.section_no,dwd_rc.device_direction,sum(volume_sum) sum_volume_5min,
toDateTime(concat(toString(toDate(create_time)),' ',lpad(toString(extract(hour FROM create_time)), 2, '0'),':',CASEWHEN extract(minute FROM create_time) < 5 THEN '00'WHEN extract(minute FROM create_time) >= 5 AND extract(minute FROM create_time) < 10 THEN '05'WHEN extract(minute FROM create_time) >= 10 AND extract(minute FROM create_time) < 15 THEN '10'WHEN extract(minute FROM create_time) >= 15 AND extract(minute FROM create_time) < 20 THEN '15'WHEN extract(minute FROM create_time) >= 20 AND extract(minute FROM create_time) < 25 THEN '20'WHEN extract(minute FROM create_time) >= 25 AND extract(minute FROM create_time) < 30 THEN '25'WHEN extract(minute FROM create_time) >= 30 AND extract(minute FROM create_time) < 35 THEN '30'WHEN extract(minute FROM create_time) >= 35 AND extract(minute FROM create_time) < 40 THEN '35'WHEN extract(minute FROM create_time) >= 40 AND extract(minute FROM create_time) < 45 THEN '40'WHEN extract(minute FROM create_time) >= 45 AND extract(minute FROM create_time) < 50 THEN '45'WHEN extract(minute FROM create_time) >= 50 AND extract(minute FROM create_time) < 55 THEN '50'ELSE '55'END,':00')) as start_time,cast(dwd_st.day as String) day
from hurys_jw.dwd_statistics as dwd_stright join hurys_jw.dwd_radar_lane as dwd_rlon dwd_rl.device_no=dwd_st.device_no and dwd_rl.lane_no=dwd_st.lane_noright join hurys_jw.dwd_device_scene as dwd_dson dwd_ds.device_no=dwd_st.device_noright join hurys_jw.dwd_scene as dwd_scon dwd_sc.scene_id = dwd_ds.scene_idright join hurys_jw.dwd_radar_config as dwd_rcon dwd_rc.device_no=dwd_st.device_no
where dwd_st.create_time is not null and dwd_st.lane_no is not null and dwd_st.day >= ?
group by dwd_st.device_no, dwd_sc.scene_name, dwd_st.lane_no, dwd_rl.lane_direction, dwd_st.section_no, dwd_rc.device_direction, toDateTime(concat(toString(toDate(create_time)),' ',lpad(toString(extract(hour FROM create_time)), 2, '0'),':',CASEWHEN extract(minute FROM create_time) < 5 THEN '00'WHEN extract(minute FROM create_time) >= 5 AND extract(minute FROM create_time) < 10 THEN '05'WHEN extract(minute FROM create_time) >= 10 AND extract(minute FROM create_time) < 15 THEN '10'WHEN extract(minute FROM create_time) >= 15 AND extract(minute FROM create_time) < 20 THEN '15'WHEN extract(minute FROM create_time) >= 20 AND extract(minute FROM create_time) < 25 THEN '20'WHEN extract(minute FROM create_time) >= 25 AND extract(minute FROM create_time) < 30 THEN '25'WHEN extract(minute FROM create_time) >= 30 AND extract(minute FROM create_time) < 35 THEN '30'WHEN extract(minute FROM create_time) >= 35 AND extract(minute FROM create_time) < 40 THEN '35'WHEN extract(minute FROM create_time) >= 40 AND extract(minute FROM create_time) < 45 THEN '40'WHEN extract(minute FROM create_time) >= 45 AND extract(minute FROM create_time) < 50 THEN '45'WHEN extract(minute FROM create_time) >= 50 AND extract(minute FROM create_time) < 55 THEN '50'ELSE '55'END,':00')), cast(dwd_st.day as String)
;
就先这样,反正ClickHouse和Hive的SQL语句非常非常不一样!!!
相关文章:
二百七十六、ClickHouse——Hive和ClickHouse非常不同的DWS指标数据SQL语句
一、目的 在完成数据之后对业务指标进行分析,Hive和ClickHouseSQL真不一样 二、部分业务指标表 2.1 统计数据流量表1天周期 2.1.1 Hive中原有代码 2.1.1.1 Hive中建表语句 --1、统计数据流量表——动态分区——1天周期 create table if not exists hurys_d…...
Elasticsearch Date类型,时间存储相关说明
本文介绍了在SpringBoot中处理Elasticsearch中日期时间格式的问题。当时间输出为UTC格式并存在时区差异时,可通过设置字段格式如yyyy-MM-dd HH:mm:ss并指定时区为GMT8来解决。存储Date类型数据时,可以使用JSON库如json-lib, fastjson, Jackson或gson进行…...
mathorcup2024台风 我all in ai
三个问题,力大砖飞。 不建物理模型,直接all in好吧 第一个故意无监督 第二个LSTMCNN注意力,刚好时间空间 第三个在第二个上加了个transfomer ,然后LSTM变双向,增加层数(基线模型选的经验公式,少…...
android 10 后台启动activity
摘要:Android 10(API 级别 29)及更高版本会限制应用何时可以启动 activity 背景。这些限制有助于最大限度地减少对用户的干扰, 让用户能够更好地控制其屏幕上显示的内容。本文以此为出发点,基于展锐平台对系统代码进行…...
文案创作新思路:Python与文心一言API的完美结合
在这个信息爆炸的时代,内容创作似乎成了一项需要魔法才能完成的任务。不过,别担心!今天,我们将向你介绍一种新的“魔法”工具——百度文心一言 API。这款大语言模型不仅能与人对话互动,还能高效便捷地协助你获取创意灵…...
CentOS 7 上安装 MySQL 8.0 教程
🌟 你好 欢迎来到我的技术小宇宙!🌌 这里不仅是我记录技术点滴的后花园,也是我分享学习心得和项目经验的乐园。📚 无论你是技术小白还是资深大牛,这里总有一些内容能触动你的好奇心。🔍 &#x…...
Chromium HTML5 新的 Input 类型url对应c++
一、Input 类型: url url 类型用于应该包含 URL 地址的输入域。 在提交表单时,会自动验证 url 域的值。 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>test</title> </head> <body&g…...
java多线程编程(二)一一>线程安全问题, 单例模式, 解决程线程安全问题的措施
引言: 如果多线程环境下代码运行的结果是符合我们预期的,即在单线程环境应该的结果,则说这个程序是线程安全的 线程安全问题的原因: 一.操作系统的随机调度 : 二.多个线程修改同一个变量: 三.修改操作不是…...
Leetcode 213. 打家劫舍 II 动态规划
原题链接:Leetcode 213. 打家劫舍 II class Solution { public:int rob(vector<int>& nums) {int n nums.size();if (n 1)return nums[0];if (n 2)return max(nums[0], nums[1]);// 如果偷了第一家,就不能偷最后一家int dp[n - 1];dp[0] …...
就业市场变革:AI时代,我们将如何评估人才?
内容概要 在这个充满变革的时代,就业市场正被人工智能(AI)技术深刻改变。随着技术的进步,传统的人才评估方式逐渐显示出其局限性。例如,过去依赖于纸质简历和面试评估的方式在快速变化的环境中难以准确识别真实的人才…...
富格林:安全操作方式稳健出金
富格林认为,黄金一直是吸引投资者关注的投资产品之一,投资者不断踏入黄金投资交易市场。很多投资者都以为现货黄金投资是很容易实现出金获得丰厚利润,但是面对复杂的交易市场,不仅不能轻易实现安全获利出金,甚至可能还…...
早点包子店点餐的软件下载和点餐操作教程 佳易王餐饮点餐管理系统操作方法
一、概述 【软件试用版资源文件可以点文章最后卡片了解】 早点包子店点餐的软件下载和点餐操作教程 适合于早点早餐餐饮行业的软件,实现早点点餐,收银会员管理,库存统计,销售统计等一体化操作。 点餐的时候可以用手触摸点&…...
uniapp一键打包
1.先安装python环境, 2.复制这几个文件到uniapp项目里面 3.修改自己证书路径,配置文件路径什么的 4.在文件夹页面双击buildController.py或者cmd直接输入buildController.py 5.python报错,哪个依赖缺少安装哪个依赖 6.执行不动的话&…...
什么是ksqlDB?流处理世界里的新范式
在大数据技术快速迭代的今天,我们见证了数据处理范式的不断演进。从批处理到流处理,从复杂的编程框架到声明式API,技术在不断简化与进化。而ksqlDB的出现,为我们带来了一个全新的视角 - 它不仅仅是一个流处理引擎,更是重新定义了我们与实时数据交互的方式。 让我们重新认识流处…...
Vue.js组件开发
Vue.js 是一个流行的 JavaScript 框架,用于构建用户界面和单页应用程序。开发 Vue.js 组件是 Vue.js 开发的核心部分。下面是一些关于 Vue.js 组件开发的基本概念和示例。 1. 创建一个基本的 Vue 组件 <template><div><h1>{{ title }}</h1>…...
Oracle视频基础1.1.2练习
1.1.2 需求: 查询oracle组件和粒度大小, select component,granule_size from v$sga_dynamic_components;Oracle SGA 中组件和粒度大小查询详解 在 Oracle 数据库的内存结构中,SGA(System Global Area,系统全局区&am…...
Hadoop分布式文件系统架构和设计
Hadoop分布式文件系统架构和设计 引言Hadoop 分布式文件系统 (HDFS) 是一个设计用于在普通硬件上运行的分布式文件系统。它与现有的分布式文件系统有许多相似之处。然而,HDFS 与其他分布式文件系统的差异是显著的。HDFS具有高度的容错能力,并且设计用于在低成本硬件上部署。H…...
Prompt Engineering (Prompt工程)
2 prompt工程2大原则 2.1 给出清晰,详细的指令 策略1:使用分割符清晰的指示输出的不同部分,比如"",<>,<\tag>等分隔符 策略2:指定一个结构化的输出,比如json,html等格式 策略3:要…...
第十四课 Vue中的HTML及文本渲染
Vue中的HTML及文本渲染 HTML渲染 v-html指令可以在DOM中渲染新的子HTML DOM,Vue官方认为HTML渲染是不安全的,并不建议直接做HTML插入操作。 <div id"app"><div v-html"vals"></div></div><script>n…...
无人机救援系统简单解读
无人机救援系统简单解读 1. 源由2. 场景分析2.1 人员搜索2.2 紧急物资投送2.3 环境评估 3. 系统分解4. 初步总结5. 参考资料 1. 源由 最近,关于《Rapid Response UAV Post-Disaster Location Network Incorporating ML, Radio Control, and Global Positioning Sys…...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
