当前位置: 首页 > news >正文

TDengine 从入门到精通(2万字长文)

第一章:走进 TDengine 的世界

TDengine 是个啥?

如果你首次接触 TDengine,心里可能满是疑惑:这究竟是个什么东西,能派上什么用场?简单来讲,TDengine 是一款开源、高性能且云原生的时序数据库(Time Series Database, TSDB),专为处理时间序列数据而精心打造。它诞生的背景与目标十分明确,旨在攻克物联网(IoT)、车联网、工业互联网、金融市场、IT 运维等领域中,海量时间数据存储与分析的难题。

想象一下,每天数亿台设备持续不断地产生诸如温度、电压、流量等数据,传统数据库面对这汹涌如潮的数据可能不堪重负,瞬间 “垮掉”,而 TDengine 却能应对自如,轻松驾驭。它可不只是一个普通的数据库,还集成了缓存、数据订阅、流式计算以及数据清洗等多种功能,宛如一位全能型选手。无论是实时监控设备状态,还是深入分析历史趋势,TDengine 都能大显身手,发挥关键作用。

TDengine 的硬核特性

TDengine 的强大源于其一系列独特的设计与功能。接下来,让我们深入剖析这些 “硬核” 特性,看看它究竟凭借什么在时序数据库领域站稳脚跟,脱颖而出。

性能炸裂

TDengine 的性能堪称 “快得离谱”。它针对物联网大数据的特性进行了深度优化,写入和查询速度相较于传统通用数据库,提升了 10 倍以上,甚至在与不少同行的时序数据库对比中,也能轻松 “胜出”。它是如何做到这一点的呢?核心在于其存储引擎设计,通过采用列式存储、数据压缩以及时间分区等技术手段,将 TB 甚至 PB 级数据的处理变得轻而易举,仿佛小菜一碟。这不仅意味着更快的响应速度,还能为你节省大量的硬件开销,降低成本。

举个例子,假设你需要查询 1000 万条传感器数据的平均值,使用 MySQL 可能需要好几秒的时间,而 TDengine 或许几百毫秒就能迅速搞定。在对实时性要求极高的场景中,这种高效的性能表现简直如同 “救命稻草”,至关重要。

分布式架构,天生可扩展

TDengine 并非独自 “作战” 的 “独行侠”,它采用原生分布式设计,具备出色的水平扩展能力。这意味着什么呢?当数据量不断增长或者查询压力逐渐增大时,你只需简单地添加几台机器即可。节点数量越多,其处理能力就越强。而且,它内置了多副本机制,即便某个节点出现故障,数据也不会丢失,系统依旧能够稳定运行,坚如磐石。这种特性对于物联网、工业互联网这类动辄涉及上亿设备的数据洪流场景而言,尤为适用,能够轻松应对大规模数据的挑战。

SQL 用起来贼顺手

别把 TDengine 想象成一个高高在上、难以捉摸的技术 “怪兽”,实际上它非常接地气,直接支持 SQL 查询。如果你之前有使用 MySQL 或 PostgreSQL 的经验,那么切换到 TDengine 几乎不存在学习成本,能够快速上手。更令人惊喜的是,它还针对时序数据特别增加了一些实用功能,例如插值、降采样、时间加权平均(TWA)等操作,这些在传统 SQL 中难以直接实现的功能,在 TDengine 中只需通过简单的 SQL 语句就能轻松搞定,无需你再花费大量时间和精力编写一堆复杂的代码来处理,大大提高了工作效率。

比如,想要计算某设备过去一小时的平均电流,只需使用这样一句简单的 SQL 语句:

SELECT AVG(current) FROM meters WHERE ts > NOW - 1h;

代码简洁明了,同时执行效率还很高,能够快速得出所需结果。

写入方式花样多

TDengine 支持丰富多样的写入协议,像 InfluxDB Line 协议、OpenTSDB 的 Telnet 和 JSON 协议等,它都能完美兼容。这意味着你可以直接利用 Telegraf、Prometheus 等工具,将数据轻松 “塞” 进 TDengine,甚至无需编写一行代码,就能实现数据的快速写入。更为厉害的是,它还支持无模式写入。那么,什么是无模式写入呢?简单来说,就是你无需提前定义表结构,直接将数据传入,TDengine 也能准确无误地接收并处理。在业务需求频繁变动、灵活性要求较高的场景中,这种无模式写入功能简直是 “福音”,能够极大地提高数据处理的效率和灵活性。

内置缓存,省心又省力

TDengine 自带缓存功能,并且采用了时间驱动的 FIFO(先进先出)策略。最近产生的数据会自动保留在缓存中,当你想要查询某个设备的最新状态时,系统能够以极快的速度响应,瞬间给出结果。这不仅大大提高了查询速度,还能有效简化你的系统架构。以往,你可能需要自行搭建 Redis 等缓存工具来实现类似功能,而现在,TDengine 将这一切都集成在内,为你 “一站式” 解决,让你省心省力。

TDengine 能干啥?

说了这么多关于 TDengine 的特性,那么它究竟能够解决哪些实际问题呢?实际上,TDengine 的应用场景极为广泛,几乎涵盖了所有与时间序列数据相关的领域。下面,我们挑选几个典型的例子来详细探讨一下。

智能制造

在工厂环境中,生产线上的各类传感器每秒都在源源不断地输出数据,涉及温度、压力、转速等多个方面。TDengine 能够高效地存储这些数据,并且实时进行分析,为优化生产流程、提高生产效率提供有力支持。例如,通过数据分析发现某个机器的温度经常超出正常范围,系统便能及时发出预警,帮助你提前采取措施,避免因机器故障导致停机,从而减少不必要的损失。

能源管理

电力行业产生的数据量堪称庞大,每一台电表、每一个变电站都在持续不断地生成时序数据。TDengine 能够轻松应对如此海量的数据存储需求,同时支持实时分析用电趋势,甚至能够预测用电高峰期的需求,为电网的智能化运行提供关键支撑,助力电网更加高效、稳定地运转。

物联网平台

物联网(IoT)平台或许是 TDengine 最为擅长的应用领域之一。想象一下,成千上万的设备,如智能家居设备、共享单车、环境监测站等,每时每刻都在向平台上传数据。TDengine 不仅能够承受住这种巨大的数据流量冲击,还能快速响应各类查询请求,让你随时都能准确掌握设备的最新状态,实现对物联网设备的高效管理与监控。

工业大数据

对于工业企业而言,数据驱动决策至关重要,而 TDengine 恰好能成为得力助手。它能够将分散在各个角落的设备数据整合起来,通过深入分析历史趋势,挖掘潜在问题,甚至为未来的生产计划提供科学依据,帮助企业实现精细化管理,提升竞争力。

一句话总结:只要是存在大量时间序列数据需要存储、查询和分析的场景,TDengine 都能够充分发挥其优势,展现出强大的实力。

第二章:上手 TDengine:安装与配置

环境准备:跑起来之前得知道啥

TDengine 的安装过程并不复杂,但在安装之前,你需要清楚了解它能够在哪些环境中运行。它的兼容性相当出色,支持多种操作系统和硬件平台,具体要求如下:

组件支持平台注意事项
服务端Linux x64推荐使用 CentOS 7.9 或 Ubuntu 18.04
客户端Windows x64, Linux x64macOS 支持有限,部分功能无法完全使用
硬件平台x64, arm64从服务器到树莓派等设备均能运行

简单来说,只要是主流的 Linux 服务器,或者 Windows 客户端,基本都能够顺利安装和使用 TDengine。在硬件方面,它对 x64 和 arm64 架构都具有良好的兼容性,即使是嵌入式设备,也能够尝试运行。这种高度的灵活性使得 TDengine 既能应用于大规模集群场景,也能适配小型设备,满足不同用户的多样化需求。

安装 TDengine:手把手教你

TDengine 的安装过程设计得非常人性化,支持多种系统和安装方式。下面,我们针对几个常见的场景,详细讲解一下具体的安装步骤。

Debian/Ubuntu:deb 包安装
  1. 下载安装包:前往 TDengine 官网(tdengine.com),获取最新版本的 deb 包,例如 TDengine-server-3.0.0.0-Linux-x64.deb。下载完成后,将安装包上传至服务器,准备进行下一步安装操作。
  2. 动手安装:打开服务器的终端,进入安装包所在目录,输入以下命令:

sudo dpkg -i TDengine-server-3.0.0.0-Linux-x64.deb

系统会自动进行解包和安装操作。在安装过程中,可能会弹出一些配置问题,你只需按照提示进行填写即可。
3. 检查结果:安装完成后,使用命令taosd --version查看版本号,确认安装是否成功。如果能够正确显示版本信息,说明安装过程顺利完成。

CentOS/RHEL:rpm 包安装
  1. 下载安装包:同样在官网找到对应的 rpm 包,如 TDengine-server-3.0.0.0-Linux-x64.rpm。
  2. 执行安装:进入安装包所在目录,运行以下命令:

sudo rpm -ivh TDengine-server-3.0.0.0-Linux-x64.rpm

安装过程与 deb 包类似,按照提示逐步完成即可。

Windows:点一下就装
  1. 下载 exe 文件:官网提供了 Windows 版本的 exe 安装包,下载完成后,双击该文件,按照安装向导的提示,点击几下 “下一步”,即可轻松完成安装。
  2. 启动服务:安装完成后,你可以通过命令行输入taosd来启动服务,也可以直接在服务管理器中找到 TDengine 服务并启动它。
macOS:尝鲜用

目前,macOS 对 TDengine 的支持相对有限,但也可以进行安装。下载 pkg 包后,双击该文件,按照提示完成安装。不过需要注意的是,在 macOS 系统上,并非所有功能都能完全正常使用,因此在生产环境中,建议还是使用 Linux 系统。

启动与验证

安装完成后,启动服务是关键步骤。在 Linux 系统下,可以使用以下命令启动服务:

sudo systemctl start taosd

如果系统不支持 systemd,也可以手动运行以下命令启动:

/usr/local/taos/bin/taosd

服务启动后,在终端输入taos进入客户端,尝试连接到 TDengine。如果能够成功连接,就说明安装过程没有出现任何问题,你已经成功迈出了使用 TDengine 的第一步。

小贴士:如果是集群的第一个节点,在安装时可能会提示你填写 FQDN(完全限定域名),此时你可以先留空;后续添加节点时,则需要填写已有节点的域名。

初始配置:让 TDengine 听你话

安装好 TDengine 后,接下来需要对其进行一些初始配置,以便让它按照你的需求高效运行。配置主要通过修改/etc/taos/taos.cfg这个文件来完成,该文件位置固定,默认值通常能够满足基本需求,但如果你想要发挥 TDengine 的极致性能,可能还需要手动进行一些调整。

关键参数一览
  1. firstEP:该参数用于指定集群的入口地址,格式为主机名:端口,例如h1.tdengine.com:6030。如果是单机运行模式,则无需关注该参数;但在集群环境中,需要准确填写第一个节点的地址。
  2. FQDN:即完全限定域名,在多节点集群中,该参数必填。在单机模式下,可以跳过该设置;但在集群环境中,务必确保每个节点都能够正确识别对方的 FQDN,以保证节点之间的通信正常。
  3. hosts 文件:如果出现无法连接到服务器的情况,很可能是域名解析出现了问题。此时,你可以打开/etc/hosts文件,添加一行记录,例如192.168.1.10 h1.tdengine.com,或者确保已正确配置好 DNS,以解决域名解析问题。
  4. REST 连接:如果想要使用 REST 接口,无需额外安装任何软件,直接通过 HTTP 请求即可调用。不过需要注意的是,REST 接口的性能相对较低,并且无法使用订阅功能,因此更适合轻量级的应用场景。
  5. 数据节点参数:在dnodeCfg.json文件中,还包含一些高级选项,例如:
    • numOfMnodes:表示元数据节点数,默认值为 3。
    • statusInterval:节点状态上报间隔,默认值为 10 秒。
    • monitorInterval:资源监控周期,默认值为 30 秒。
配置实战

假设你想要搭建一个单机测试环境,那么只需要修改taos.cfg文件即可。打开该文件,找到以下几行:

# firstEP           h1.tdengine.com:6030
# fqdn              localhost

对于单机环境,直接将fqdn设置为localhost,然后保存并退出文件。接下来,重启服务使配置生效:

sudo systemctl restart taosd

重启服务后,使用taos命令连接到 TDengine,尝试创建一个数据库,检查配置是否成功生效。

如果是搭建集群环境,则每台机器的taos.cfg文件都需要保持一致,尤其是firstEP参数,必须指向同一个入口节点。修改完成后,逐台重启机器上的 TDengine 服务,确保所有节点都能够正常连接到集群。

注意:如果配置出现错误,可能会收到诸如 “Unable to resolve FQDN” 之类的错误提示。此时,需要仔细检查网络连接和域名配置,不要慌张,按照提示逐步排查问题即可。

第三章:数据模型设计:玩转 TDengine 的核心

创建数据库:从零开始

TDengine 的数据管理是从创建数据库开始的。它的建库语法非常灵活,允许你根据实际需求调整各种参数。下面,我们先了解几个常用的参数:

参数含义取值范围默认值版本支持
KEEP数据存储时长(天)[days, 365000]36502.0.8.0
UPDATE是否允许更新数据0, 1, 212.0.8.0
COMP数据压缩级别0, 1, 222.0.8.0
REPLICA副本数[1, 3]12.0.8.0
BLOCKS每个 VNODE 的内存块数[3, 1000]62.0.8.0
PRECISION时间精度'ns', 'us','ms''ns'2.0.8.0

想要创建一个数据库,只需使用一条简单的 SQL 语句:

CREATE DATABASE power KEEP 365 DAYS 10 BLOCKS 6 UPDATE 1;

这条语句的含义是创建一个名为power的数据库,数据将存储 365 天,每 10 天划分为一个文件,内存块设置为 6 个,并且允许更新数据。是不是很简单呢?

小技巧:从 2.1.3.0 版本开始,修改这些参数无需重启服务,修改后会立即生效,非常方便。

表结构设计:一个设备一张表

TDengine 的表设计有一个独特之处,即 “一个设备一张表”。虽然乍一听可能觉得有些繁琐,但实际上这种设计非常巧妙,能够显著提升性能和扩展性。

基本规则
  1. 表的第一列必须是TIMESTAMP类型,并且该列会自动作为主键。例如常见的时间戳字段ts,其作为时序数据库的核心标识,是不可修改的。
  2. 支持丰富的列类型,包括整型(INT)、浮点型(FLOAT)、字符串型(BINARY)等,你可以根据实际需求灵活选择。
  3. 列数存在一定限制,在 2.1.7.0 版本之后,超级表最多支持 4096 列,这通常能够满足大多数实际应用场景的需求。
超级表登场

TDengine 有一个强大的功能 —— 超级表(Super Table)。超级表就像是一个模板,能够用于管理一堆结构相同的子表。例如,假设你有 1000 个电表,每个电表的数据格式都相同(包含时间、电流、电压等字段),那么只需要创建一个超级表即可:

CREATE STABLE meters (ts TIMESTAMP,current FLOAT,voltage INT,phase FLOAT
) TAGS (location BINARY(64),groupId INT
);

上述语句创建了一个名为meters的超级表,它包含ts(时间戳)、current(电流)、voltage(电压)、phase(相位)等数据列,同时还定义了location(位置)和groupId(组 ID)两个标签。

接下来,为具体的电表创建子表:

CREATE TABLE d1001 USING meters TAGS ('Beijing', 1);

d1001这个子表继承了meters超级表的结构,并且带上了特定的location(北京)和groupId(1)标签。在后续查询数据时,你可以直接对meters超级表进行操作,系统会自动扫描其所有子表,获取相关数据。

实战举例

假设你负责管理大量的物联网设备,需要存储这些设备的温度和湿度数据。依据 TDengine “一个设备一张表” 的设计理念以及超级表的特性,可以这样设计数据模型:

CREATE STABLE sensors (ts TIMESTAMP,temp FLOAT,humidity FLOAT
) TAGS (device_id BINARY(32),region INT
);CREATE TABLE dev_001 USING sensors TAGS ('DEV001', 101);

这里,sensors超级表定义了通用的数据结构,包括时间戳ts、温度temp和湿度humidity字段,同时设置了device_id(设备 ID)和region(区域)标签。dev_001子表基于sensors超级表创建,代表具体的一台设备,它携带了特定的设备 ID 和区域信息。这样的设计使得每个设备的数据都有独立的表进行存储,查询时能够快速定位,管理起来也更加便捷高效。无论是新增设备,还是对设备数据进行统计分析,都变得简单明了。

超级表妙用:效率翻倍

超级表不仅是简化表管理的得力工具,更是 TDengine 高性能的核心秘诀所在。接下来,让我们深入探讨如何充分发挥超级表的强大功能。

创建与操作

创建超级表使用CREATE STABLE语句,创建子表则使用CREATE TABLE语句。若后续需要修改超级表的结构,通过ALTER STABLE语句即可轻松实现:

ALTER STABLE meters ADD COLUMN power INT;

上述语句为meters超级表添加了一个名为power(功率)的整型列,并且该操作会自动应用到所有基于meters超级表创建的子表上,实现了对子表结构的统一管理,大大提高了数据结构维护的效率。

查询神器

超级表最大的优势之一体现在查询操作上,它能够极大地简化查询流程。例如,想要计算所有电表的平均电压:

SELECT AVG(voltage) FROM meters WHERE location = 'Beijing';

这条 SQL 语句会自动遍历meters超级表下所有location(位置)为Beijing(北京)的子表,对这些子表中的电压数据进行聚合计算,最终返回平均电压值。这种查询方式无需逐个指定子表,系统自动完成数据的收集与处理,大大节省了查询编写的工作量,同时也提高了查询执行的效率。

标签活用

标签(TAGS)是超级表的灵魂所在,合理运用标签能够实现对子表的快速筛选。若要查询某个子表的标签值,可以使用以下语句:

SHOW TABLE TAGS FROM d1001;

该语句会返回d1001子表的所有标签信息,包括标签名称及其对应的值。

如果需要修改子表的标签,同样可以通过简单的 SQL 语句实现:

ALTER TABLE d1001 SET TAG location = 'Shanghai';

上述语句将d1001子表的location标签值从原来的值修改为Shanghai(上海)。通过灵活运用标签的查询与修改功能,能够更加便捷地对设备数据进行分类管理和检索。

小结

超级表通过巧妙的设计,将分散的设备数据组织得井然有序,在查询和管理数据时展现出了极高的效率和准确性。尤其是在设备众多、数据繁杂的场景中,超级表的优势更加明显,能够实现对数据的高效处理,如同进行一场降维打击,轻松应对复杂的数据管理与分析需求。

第四章:数据操作:让 TDengine 动起来

数据操作是使用 TDengine 过程中的日常任务,涵盖插入、查询、更新、删除等基本操作。接下来,我们将逐步拆解这些操作,深入了解如何灵活运用它们,通过理论与实战相结合的方式,确保你在学习后能够熟练上手操作 TDengine。

插入数据:喂饱 TDengine

TDengine 的插入功能极为灵活,支持单条插入、批量插入、多表插入,甚至具备自动建表的能力。下面,我们逐一介绍这些插入方式。

单条插入:最基础的玩法

最基础的插入方式就是单条插入,使用INSERT INTO语句向表中添加一条数据。例如,对于电表d1001,要插入一组电流、电压等数据,可以这样写:

INSERT INTO d1001 VALUES ('2025-04-04 10:00:00', 12.5, 220, 0.33);

这条语句的含义是向d1001表中插入一条记录,时间为 2025 年 4 月 4 日上午 10 点,电流值为 12.5A,电压值为 220V,相位为 0.33。操作简单直接,数据插入后立即生效。

批量插入:效率翻倍

当单条插入数据效率较低时,批量插入是更好的选择。批量插入允许你一次性向表中插入多条数据,大大节省时间和网络开销。例如:

INSERT INTO d1001 VALUES
('2025-04-04 10:01:00', 12.6, 221, 0.34),
('2025-04-04 10:02:00', 12.4, 219, 0.32);

上述语句一次性将两条数据插入到d1001表中,相较于单条插入,减少了网络请求次数,显著提高了数据插入的效率。在数据量较大的情况下,批量插入的优势尤为突出。

多表插入:一箭双雕

更为强大的是,TDengine 支持一次向多个表插入数据。例如,假设有两台电表d1001d1002,可以使用以下语句进行插入操作:

INSERT INTO 
d1001 VALUES ('2025-04-04 10:03:00', 12.7, 223, 0.35)
d1002 (ts, current, phase) VALUES ('2025-04-04 10:03:00', 13.1, 0.36);

在这个例子中,d1001表插入了完整的字段数据,而d1002表只插入了部分字段(tscurrentphase),未指定的voltage字段会默认设置为NULL。这种多表插入的写法在涉及多个设备数据插入的场景中,能够大大简化操作流程,提高工作效率。

自动建表:懒人福音

TDengine 还具备一项实用功能 —— 在插入数据时自动创建表。假设已经存在超级表meters,但表d2001尚未创建,此时可以使用以下语句进行数据插入:

INSERT INTO d2001 USING meters TAGS ('Shanghai', 2) VALUES ('2025-04-04 10:04:00', 12.8, 224, 0.37);

这条命令会首先检查d2001表是否存在,若不存在,则根据meters超级表的结构自动创建d2001表,并为其设置Shanghai2的标签,然后再插入数据。在动态变化的业务场景中,这种自动建表功能能够极大地提高数据处理的灵活性,减少人工干预,堪称 “懒人福音”。

注意事项
  1. 时间戳范围:插入数据的时间戳需要在合理范围内,受到数据库的KEEPDAYS参数限制。例如,如果KEEP设置为 3650 天,DAYS设置为 10 天,那么时间戳应在 “当前时间 - 3650 天” 到 “当前时间 + 10 天” 之间,超出这个范围的数据将无法成功插入。
  2. 大小限制:单条记录的大小不能超过 48KB,整条 SQL 语句的长度不能超过 1MB。在实际应用中,需要注意数据量的控制,避免因数据过大导致插入失败。
  3. 多线程:TDengine 支持多线程写入,但并非线程越多写入效率越高。通常情况下,将线程数控制在 20 个左右较为合适,过多的线程可能会导致系统资源竞争加剧,反而降低写入性能。

掌握了这些插入技巧,能够充分发挥 TDengine 的数据写入能力,让数据快速、高效地存储到数据库中。

查询数据:挖出金子

TDengine 的查询功能强大且贴心,尤其是针对时序数据进行了专门优化,为数据分析师提供了极大的便利。下面,我们一同探索如何从数据库中精准地查询出所需数据。

超级表查询:一网打尽

超级表在查询操作中发挥着重要作用,能够一次性扫描其所有子表的数据。例如,想要计算所有电表的平均电压,可以使用以下 SQL 语句:

SELECT AVG(voltage) FROM meters WHERE location = 'Beijing';

这条语句会自动遍历meters超级表下所有locationBeijing的子表,对这些子表中的电压数据进行聚合计算,最终返回平均电压值。通过超级表查询,能够轻松实现对大量相关设备数据的快速统计分析,大大提高了查询效率。

窗口切分:时间分片大师

在处理时序数据时,时间窗口是常用的分析手段。TDengine 提供了三种时间窗口切分方式:

  1. 时间窗口(Interval):按照固定的时间间隔对数据进行切分。例如,想要每 10 分钟统计一次数据,可以使用以下语句:

SELECT COUNT(*), AVG(current) FROM d1001 INTERVAL(10m);

上述语句将以每 10 分钟为一个时间窗口,统计d1001表中每个窗口内的数据条数,并计算平均电流值。通过时间窗口切分,能够清晰地观察到数据在不同时间段内的变化趋势。
2. 会话窗口(Session):根据时间间隔阈值对数据进行分组。例如,当数据的时间间隔超过 5 秒时,将其划分为新的会话,可以使用以下语句:

SELECT COUNT(*) FROM d1001 SESSION(ts, 5s);

这种方式适用于分析具有连续性的数据,能够根据设定的时间间隔自动识别不同的会话区间。
3. 事件窗口(Event_window):按照特定条件对数据进行切分,适用于较为复杂的数据分析场景。通过灵活设置事件窗口的条件,可以筛选出符合特定业务逻辑的数据片段进行分析。

这些窗口功能能够帮助你快速把握数据在时间维度上的特征和规律,为深入分析时序数据提供了有力工具。

特殊函数:时序专属

TDengine 还提供了几个专门针对时序数据设计的实用函数:

  1. TWA():时间加权平均函数,该函数在计算平均值时会考虑时间因素的权重。例如,想要计算d1001表中过去 1 小时内电流的时间加权平均值,可以使用以下语句:

SELECT TWA(current) FROM d1001 WHERE ts > NOW - 1h;

通过时间加权平均,能够更准确地反映数据在不同时间段内的重要性差异,对于分析具有时间敏感性的数据非常有用。
2. SPREAD():用于计算数据的最大最小值差值。例如,想要计算d1001表中电压的波动范围,可以使用以下语句:

SELECT SPREAD(voltage) FROM d1001;

该函数能够快速获取数据的离散程度,帮助你了解数据的变化幅度。
3. LAST_ROW():用于获取表中的最后一条记录。例如,想要查询d1001表中的最新数据,可以使用以下语句:

SELECT LAST_ROW(*) FROM d1001;

这些特殊函数为时序数据的分析提供了便捷的计算方法,无需手动编写复杂的算法,即可完成常见的时序数据分析任务。

结果处理

在查询数据后,你还可以对查询结果进行进一步处理,如分组、排序、限制输出等。例如:

SELECT AVG(voltage), location FROM meters GROUP BY location ORDER BY AVG(voltage) DESC LIMIT 5;

这条语句首先按照locationmeters超级表下的子表进行分组,然后计算每个分组内的平均电压值,接着按照平均电压值从高到低进行排序,最后只返回排名前 5 的结果。通过灵活运用这些结果处理操作,能够根据具体需求对查询结果进行筛选和整理,获取最有价值的信息。

查询功能是 TDengine 的核心优势之一,无论是实时监控设备状态,还是进行历史数据的深度分析,TDengine 都能够凭借其强大的查询能力,为你提供准确、快速的查询结果。

更新与删除:改改删删

TDengine 的更新和删除功能虽然相对简洁,但足以满足实际应用中的常见需求。

更新数据

TDengine 的数据更新操作受到数据库UPDATE参数设置的影响:

0:表示不允许更新数据,这是数据库的默认设置。在这种模式下,对已有数据进行更新操作将被拒绝。

1:当设置为 1 时,若插入与已有记录时间戳相同的数据,新数据将覆盖旧数据。例如,在power库中,如果其UPDATE设置为 1,执行以下插入语句:

INSERT INTO d1001 VALUES ('2025-04-04 10:00:00', 13.0, 225, 0.38);

那么之前在2025-04-04 10:00:00时间戳下的记录(如(12.5, 220, 0.33))将被新插入的数据所覆盖。
2:设置为 2 时,更新操作更加灵活,不仅可以覆盖相同时间戳的记录,甚至允许对部分字段进行单独更新,进一步增强了数据更新的灵活性。

删除数据

删除数据使用DELETE FROM语句,并支持通过条件过滤来精准删除符合特定条件的数据。例如,想要删除d1001表中 2025 年 4 月 4 日上午 9 点之前的数据,可以使用以下语句:

DELETE FROM d1001 WHERE ts < '2025-04-04 09:00:00';

上述语句将根据时间戳条件,删除d1001表中满足条件的数据。

对于超级表,同样可以进行删除操作。例如,想要删除meters超级表下所有locationShanghai的子表数据,可以使用以下语句:

DELETE FROM meters WHERE location = 'Shanghai';

这条语句会自动遍历meters超级表下所有相关子表,删除符合条件的数据。

需要特别注意的是,删除操作是不可逆的,一旦执行删除语句,数据将永久丢失。因此,在执行删除操作之前,强烈建议先使用SELECT语句进行查询,确认要删除的数据是否正确,避免误删重要数据。

第五章:高级特性:TDengine 的杀手锏

TDengine 不仅仅具备基本的数据存储和查询功能,还拥有一系列高级特性,这些特性能够助力你的数据分析和实时处理能力更上一层楼,使其在众多数据库中脱颖而出。

时间序列分析:洞察未来

对于时序数据而言,存储只是基础,深入的分析才是关键所在。TDengine 在时间序列分析方面投入了大量精力,具备强大的分析能力。

分解与建模
  1. 时间序列分解:TDengine 能够将时间序列数据分解为趋势、季节和随机三个主要部分。通过这种分解,能够更清晰地洞察数据背后隐藏的规律。例如,在分析电表数据时,可以通过时间序列分解了解用电的长期趋势(如随着季节变化的用电增长或下降趋势)、季节性波动(如每天不同时段的用电高峰和低谷)以及随机因素导致的波动(如突发设备故障引起的短暂用电异常),从而为电力调度和能源管理提供更精准的依据。
  2. ARIMA 模型:该模型主要用于预测非平稳时间序列数据。以预测未来一小时的电流走势为例,TDengine 可以利用历史电流数据,通过 ARIMA 模型分析数据的自相关性、季节性等特征,构建预测模型,进而对未来短期内的电流值进行较为准确的预测。这对于电力系统的负荷预测、设备维护计划制定等具有重要意义,能够帮助相关人员提前做好准备,保障电力供应的稳定性。
  3. 贝叶斯结构(BSTS):BSTS 模型结合了先验知识,在预测过程中,不仅考虑历史数据,还融入了领域专家的经验或其他相关先验信息,使得预测结果更加准确可靠。例如,在分析金融市场的时间序列数据时,可以结合市场趋势判断、宏观经济指标等先验知识,利用 BSTS 模型进行预测,为投资决策提供更全面、精准的参考。
窗口与函数

在前面介绍查询功能时,已经提及了

请继续

连续查询:自动化的魔法

连续查询是 TDengine 一个非常实用的高级特性,它可以按照用户设定的时间间隔自动执行查询任务,并将结果存储到指定的表中。这在需要定期对数据进行汇总和分析的场景下非常有用,比如每天统计一次设备的平均温度、每小时统计一次用电量等。

创建连续查询

使用CREATE CONTINUOUS QUERY语句来创建连续查询。例如,要每天统计一次所有电表的平均电压,并将结果存储到一个名为daily_avg_voltage的表中,可以这样写:

CREATE CONTINUOUS QUERY cq_daily_avg_voltage ON power
BEGININSERT INTO daily_avg_voltageSELECT AVG(voltage) FROM meters GROUP BY location
END EVERY 1d;

在这个例子中:

  • cq_daily_avg_voltage 是连续查询的名称。
  • ON power 表示这个连续查询是在 power 数据库上执行。
  • BEGIN 和 END 之间是具体的查询语句,这里是计算每个 location 下电表的平均电压,并将结果插入到 daily_avg_voltage 表中。
  • EVERY 1d 表示查询任务每天执行一次。
管理连续查询

可以使用 SHOW CONTINUOUS QUERIES 语句查看所有的连续查询:

SHOW CONTINUOUS QUERIES;

如果需要删除某个连续查询,可以使用 DROP CONTINUOUS QUERY 语句:

DROP CONTINUOUS QUERY cq_daily_avg_voltage;

数据订阅:实时同步的桥梁

TDengine 支持数据订阅功能,允许外部应用程序实时获取数据库中数据的变化。这在实时监控、数据同步等场景中非常有用。

订阅方式

有两种订阅方式:

  • 全量订阅:从指定的时间点开始,订阅数据库中所有表的数据变化。
  • 增量订阅:只订阅指定时间点之后新增的数据变化。
示例代码

以下是一个简单的 Python 示例,展示如何使用 TDengine 的 Python 客户端进行数据订阅:

import taos# 连接到TDengine
conn = taos.connect(host="localhost", user="root", password="taosdata", database="power")# 创建订阅
sub = conn.subscribe(topic="my_subscription",sql="SELECT * FROM meters",interval=1000,  # 订阅间隔为1000毫秒start_time=taos.TSDB_TIMESTAMP_NULL,  # 从最新数据开始订阅callback=lambda result: print(result.fetch_all())
)# 启动订阅
sub.start()try:while True:pass
except KeyboardInterrupt:# 停止订阅sub.stop()conn.close()

在这个示例中:

  • 首先使用 taos.connect 方法连接到 TDengine 数据库。
  • 然后使用 conn.subscribe 方法创建一个订阅,指定订阅的主题、查询语句、订阅间隔、起始时间和回调函数。
  • 最后调用 sub.start() 方法启动订阅,当有新数据时,回调函数会被触发,打印出查询结果。

缓存机制:加速数据访问

TDengine 的缓存机制可以显著提高数据的访问速度。它会将最近访问的数据缓存在内存中,当再次访问相同数据时,直接从缓存中获取,避免了磁盘 I/O 操作,从而大大提高了查询性能。

缓存配置

可以通过修改 TDengine 的配置文件 taos.cfg 来调整缓存的大小和其他参数。例如,以下是一些常用的缓存配置参数:

  • cache:设置缓存的总大小,单位为 MB。
  • cache_blocks:设置缓存中数据块的数量。
缓存策略

TDengine 采用了基于时间和访问频率的缓存淘汰策略,优先保留最近访问和访问频率高的数据。这样可以确保缓存中的数据是最有价值的,提高缓存的命中率。

第六章:性能优化:让 TDengine 飞起来

索引:快速定位的指南针

在数据库中,索引就像是一本书的目录,能帮助你快速定位到所需的数据。TDengine 提供了两种类型的索引:

标签索引

标签索引主要用于加速基于标签的查询。在创建表时,可以为标签字段添加索引。例如,为 meters 超级表的 location 标签添加索引:

CREATE INDEX idx_location ON meters (location);

添加索引后,当执行基于 location 标签的查询时,数据库可以更快地定位到符合条件的数据。例如:

SELECT * FROM meters WHERE location = 'Beijing';

这个查询会利用 idx_location 索引,快速筛选出 location 为 Beijing 的子表数据,大大提高查询效率。

时间戳索引

时间戳索引是 TDengine 中非常重要的索引,因为时序数据通常会按照时间进行查询。TDengine 会自动为时间戳字段创建索引,无需手动干预。例如,在查询某个时间段内的数据时:

SELECT * FROM d1001 WHERE ts BETWEEN '2025-04-01 00:00:00' AND '2025-04-02 00:00:00';

数据库会利用时间戳索引,快速定位到符合时间范围的数据,减少不必要的扫描。

分区:化整为零的智慧

分区是将大表拆分成多个小的分区,每个分区可以独立存储和管理,从而提高查询和写入性能。TDengine 支持按时间和标签进行分区。

时间分区

时间分区是最常用的分区方式,按照时间范围将数据划分到不同的分区中。例如,可以按照天、周或月进行分区。在创建表时,可以指定分区策略。例如,为 meters 超级表按天进行分区:

CREATE STABLE meters (ts TIMESTAMP,current FLOAT,voltage FLOAT,phase FLOAT
) TAGS (location BINARY(32),device_id BINARY(32)
) PARTITION BY DAYS(1);

这样,每天的数据会存储在不同的分区中。当查询某个时间段的数据时,数据库只需要扫描相关的分区,而不是整个表,从而提高查询效率。

标签分区

标签分区是根据标签值将数据划分到不同的分区中。例如,可以根据 location 标签进行分区:

CREATE STABLE meters (ts TIMESTAMP,current FLOAT,voltage FLOAT,phase FLOAT
) TAGS (location BINARY(32),device_id BINARY(32)
) PARTITION BY TAG(location);

这样,不同 location 的数据会存储在不同的分区中。当查询某个 location 的数据时,数据库只需要扫描对应的分区,提高查询效率。

集群:众人拾柴火焰高

TDengine 支持集群部署,通过将数据分布在多个节点上,可以提高系统的并发处理能力和数据存储容量。

集群架构

TDengine 集群主要由管理节点(MN)和数据节点(DN)组成。管理节点负责集群的管理和元数据的存储,数据节点负责数据的存储和处理。

集群部署

部署 TDengine 集群需要进行以下步骤:

  1. 安装 TDengine:在每个节点上安装 TDengine。
  2. 配置集群:修改每个节点的配置文件 taos.cfg,指定集群的相关信息,如管理节点的地址、节点 ID 等。
  3. 启动集群:依次启动管理节点和数据节点。
集群优势

集群部署可以带来以下优势:

  • 高并发处理:多个节点可以同时处理查询和写入请求,提高系统的并发处理能力。
  • 数据冗余:数据会在多个节点上进行冗余存储,提高数据的可靠性。
  • 可扩展性:可以通过添加节点来扩展集群的存储容量和处理能力。

第七章:开发与集成:TDengine 的跨界融合

编程语言支持:多语言的桥梁

TDengine 支持多种编程语言,包括 Python、Java、C、C++ 等,这使得开发者可以根据自己的需求选择合适的语言进行开发。

Python 开发

Python 是一种非常流行的编程语言,具有简洁的语法和丰富的库。以下是一个使用 Python 连接 TDengine 并执行查询的示例:

import taos# 连接到 TDengine
conn = taos.connect(host="localhost", user="root", password="taosdata", database="power")# 创建游标
cursor = conn.cursor()# 执行查询
cursor.execute("SELECT * FROM d1001 LIMIT 10")# 获取查询结果
results = cursor.fetchall()# 打印结果
for row in results:print(row)# 关闭游标和连接
cursor.close()
conn.close()

在这个示例中,首先使用 taos.connect 方法连接到 TDengine 数据库,然后创建游标并执行查询,最后获取查询结果并打印。

Java 开发

Java 是一种广泛应用于企业级开发的编程语言。以下是一个使用 Java 连接 TDengine 并执行查询的示例:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;public class TDengineJavaExample {public static void main(String[] args) {try {// 加载驱动Class.forName("com.taosdata.jdbc.TSDBDriver");// 连接到 TDengineConnection conn = DriverManager.getConnection("jdbc:TAOS://localhost:6030/power", "root", "taosdata");// 创建 StatementStatement stmt = conn.createStatement();// 执行查询ResultSet rs = stmt.executeQuery("SELECT * FROM d1001 LIMIT 10");// 处理查询结果while (rs.next()) {System.out.println(rs.getString(1));}// 关闭资源rs.close();stmt.close();conn.close();} catch (Exception e) {e.printStackTrace();}}
}

在这个示例中,首先加载 TDengine 的 JDBC 驱动,然后使用 DriverManager.getConnection 方法连接到数据库,接着创建 Statement 并执行查询,最后处理查询结果并关闭资源。

C 和 C++ 开发

C 和 C++ 是性能较高的编程语言,适合对性能要求较高的场景。TDengine 提供了 C 和 C++ 的开发库,可以方便地进行开发。以下是一个简单的 C 语言示例:

#include <stdio.h>
#include <taos.h>int main() {TAOS *taos = taos_connect("localhost", "root", "taosdata", "power", 6030);if (taos == NULL) {printf("Failed to connect to TDengine\n");return -1;}TAOS_RES *res = taos_query(taos, "SELECT * FROM d1001 LIMIT 10");if (res == NULL) {printf("Failed to execute query\n");taos_close(taos);return -1;}TAOS_ROW row;while ((row = taos_fetch_row(res))) {printf("%s\n", row[0]);}taos_free_result(res);taos_close(taos);return 0;
}

在这个示例中,首先使用 taos_connect 函数连接到 TDengine 数据库,然后使用 taos_query 函数执行查询,接着使用 taos_fetch_row 函数获取查询结果,最后释放资源并关闭连接。

与其他系统集成:生态融合

TDengine 可以与其他系统进行集成,如数据采集系统、数据分析平台等,实现数据的无缝流转和处理。

与 Kafka 集成

Kafka 是一个高性能的分布式消息队列系统,可以用于数据的采集和传输。可以将 TDengine 作为 Kafka 的数据存储后端,将 Kafka 中的数据实时写入 TDengine。以下是一个简单的集成步骤:

  1. 安装 Kafka 和 TDengine:分别安装 Kafka 和 TDengine。
  2. 配置 Kafka Connect:使用 Kafka Connect 配置数据从 Kafka 到 TDengine 的传输。可以编写自定义的 Kafka Connect 连接器,将 Kafka 中的消息解析并写入 TDengine。
  3. 启动 Kafka Connect:启动 Kafka Connect 服务,开始数据传输。
与 Grafana 集成

Grafana 是一个流行的开源数据可视化平台,可以用于展示 TDengine 中的数据。集成步骤如下:

  1. 安装 Grafana:安装 Grafana 并启动服务。
  2. 添加 TDengine 数据源:在 Grafana 中添加 TDengine 作为数据源,配置连接信息。
  3. 创建仪表盘:在 Grafana 中创建仪表盘,选择 TDengine 数据源,编写查询语句,展示数据。

相关文章:

TDengine 从入门到精通(2万字长文)

第一章&#xff1a;走进 TDengine 的世界 TDengine 是个啥&#xff1f; 如果你首次接触 TDengine&#xff0c;心里可能满是疑惑&#xff1a;这究竟是个什么东西&#xff0c;能派上什么用场&#xff1f;简单来讲&#xff0c;TDengine 是一款开源、高性能且云原生的时序数据库&…...

ctfshow VIP题目限免(前10题)

目录 源码泄露 前台JS绕过 协议头信息泄露 robots后台泄露 phps源码泄露 源码压缩包泄露 版本控制泄露源码 版本控制泄露源码2 vim临时文件泄露 cookie泄露 源码泄露 根据题目提示是源代码泄露&#xff0c;右键查看页面源代码发现了 flag 前台JS绕过 发现右键无法使用了&…...

PyTorch中的各种损失函数的详细解析与通俗理解!

目录 1. 前言 2. 回归任务中的损失函数 2.1 L1损失&#xff08;Mean Absolute Error, MAE&#xff09; 2.2 平方损失&#xff08;Mean Squared Error, MSE&#xff09; 2.3 平滑L1损失&#xff08;Smooth L1 Loss&#xff09; 3. 分类任务中的损失函数 3.1 交叉熵损失&a…...

leetcode53-最大子数组和

leetcode 53 思路 本题使用贪心算法&#xff0c;核心在于对每一个元素进行遍历&#xff0c;在遍历过程里&#xff0c;持续更新当前的子数组和以及最大子数组和 假设 sum 是当前的子数组和&#xff0c;max 是到目前为止最大的子数组和遍历数组时&#xff0c;计算每个位置的当…...

解决Long类型前端精度丢失和正常传回后端问题

在 Java 后端开发中&#xff0c;可能会遇到前后端交互过程中 Long 类型精度丢失的问题。尤其是在 JavaScript 中&#xff0c;由于其 Number 类型是双精度浮点数&#xff0c;超过 16 位的 Long 类型值就会发生精度丢失。 问题背景 假设有如下实体类&#xff1a; public class…...

Green Coding规范:从循环语句到数据库查询的节能写法

本文系统化阐述绿色编码的工程实践方案&#xff0c;通过重构循环控制结构、优化集合操作范式、改进数据库访问模式三大技术路径&#xff0c;实现典型业务系统降低28.6%的CPU指令周期消耗。基于对JVM和SQL解释器的指令级分析&#xff0c;提出循环展开的黄金分割法则、位图索引加…...

Spring Boot整合Elasticsearch

摘要&#xff1a;本文手把手教你如何在Spring Boot项目中整合Elasticsearch&#xff08;ES&#xff09;&#xff0c;并实现基本的CRUD与搜索操作。包含版本选择、配置、代码示例及常见问题解决。 一、环境准备 1.1 软件版本 Spring Boot: 3.xElasticsearch: 8.x&#xff08;推…...

2025年渗透测试面试题总结- 某四字大厂面试复盘扩展 一面(题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 某四字大厂面试复盘扩展 一面 一、Java内存马原理与查杀 二、冰蝎与哥斯拉原理对比&#xff08;技术演…...

java基础自用笔记:文件、递归、常见的字符集、IO流

文件 递归 递归文件夹寻找某个文件&#xff0c;要先判断是否有权限进入文件夹&#xff08;若无权限返回null&#xff09;然后再判断文件数量是否不为0 常见的字符集 IO流 字节流 文件字节输入流 当读取到最后一个字节的时候&#xff0c;装在buffer[0]中&#xff0c;如果后面没…...

关于计算机网络的一些疑问

目录 1. HTTP/1.x 中的“队头阻塞”&#xff08;Head-of-Line Blocking&#xff09;问题解释什么是队头阻塞&#xff1f;其他相关概念&#xff1a; 2. HPACK 算法是什么&#xff1f;HPACK 的作用&#xff1a;HPACK 的特点&#xff1a;HPACK 提升性能的原因&#xff1a; 3. 如何…...

超大规模数据场景(思路)——面试高频算法题目

目录 用4KB内存寻找重复元素 从40个亿中产生不存在的整数【位】 如果只让用10MB空间存储&#xff1f; 初次遍历 二次遍历 用2GB内存在20亿个整数中查找出现次数最多的数【分块】 从亿万个URL中查找问题【分块 堆】 40亿个非负整数中找出现两次的数【位 不过多个位哈】 …...

高级:性能优化面试题深度剖析

一、引言 在Java应用开发中&#xff0c;性能优化是确保系统高效运行的关键。面试官通过相关问题&#xff0c;考察候选人对性能优化的理解和实践经验。本文将深入探讨Java应用性能优化的方法&#xff0c;包括JVM调优、数据库优化等&#xff0c;结合实际开发场景&#xff0c;帮助…...

【软件】在 macOS 上安装和配置 Apache HTTP 服务器

在 macOS 上安装 Apache HTTP 服务器的步骤&#xff1a; 1.安装 Apache HTTP 服务器 macOS 系统可能已经预装了 Apache HTTP 服务器。你可以通过终端检查它是否已经安装&#xff1a; httpd -v如果系统提示command not found&#xff0c;说明 Apache 未安装。你可以通过 Home…...

数据结构之链表

定义&#xff1a;在计算机科学中&#xff0c;链表是数据元素的线性集合&#xff0c;其每个元素都指向下一个元素&#xff0c;元素存储上并不连续。 链表分类&#xff1a;单向链表&#xff08;每个元素知道下一个元素是谁&#xff09;、双向链表&#xff08;每个元素知道其上一…...

基于Python的懂车帝汽车数据爬虫分析与可视化系统

【Python】基于Python的懂车帝汽车数据爬虫分析与可视化系统 &#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 &#x1f697;&#x1f525;【视频简介】&#x1f525;&#x1f697; 大家好&…...

setInterval问题以及前端如何实现精确的倒计时

一、为什么setInterval不能实现 原因有两&#xff1a;1、js是单线程&#xff0c;基于事件循环执行其他任务&#xff08;这里建议读者可以多去了解一下浏览器线程与事件循环相关知识&#xff09; 2、setinterval是每隔delay时间&#xff0c;把逻辑放到任务队列中&#xff0c;而…...

Python爬虫教程010:使用scrapy爬取当当网数据并保存

文章目录 3.6 爬取当当网数据3.6.1 创建项目3.6.2 查找要爬取的数据对象3.6.3 保存数据3.6 爬取当当网数据 3.6.1 创建项目 【1、创建项目】: scrapy startproject scrapy_dangdang_095【2、创建爬虫文件】 cd scrapy_dangdang_095\scrapy_dangdang_095\spiders scrapy ge…...

达芬奇预设:复古16mm胶片质感老式电影放映机转场过渡+音效

达芬奇预设&#xff1a;复古16mm胶片质感老式电影放映机转场过渡音效 特征&#xff1a; DaVinci Resolve 宏 8 过渡 幻灯片投影仪效果 可在任何帧速率和分辨率下工作 教程包括 系统要求&#xff1a; 达芬奇 Resolve 18.0...

Spring MVC 的请求处理流程是怎样的?

Spring MVC 请求处理流程的大致可分为以下几个步骤&#xff1a; 1. 请求到达 DispatcherServlet: 所有请求首先到达 DispatcherServlet&#xff08;前端控制器&#xff09;。DispatcherServlet 是 Spring MVC 的核心&#xff0c;它负责接收请求&#xff0c;并将请求委派给其他…...

PyTorch 实现图像版多头注意力(Multi-Head Attention)和自注意力(Self-Attention)

本文提供一个适用于图像输入的多头注意力机制&#xff08;Multi-Head Attention&#xff09;PyTorch 实现&#xff0c;适用于 ViT、MAE 等视觉 Transformer 中的注意力计算。 模块说明 输入支持图像格式 (B, C, H, W)内部转换为序列 (B, N, C)&#xff0c;其中 N H * W多头注…...

STM32单片机入门学习——第17节: [6-5] TIM输入捕获

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难&#xff0c;但我还是想去做&#xff01; 本文写于&#xff1a;2025.04.06 STM32开发板学习——第17节: [6-5] TIM输入捕获 前言开发板说明引用解答和科普一…...

P8819 [CSP-S 2022] 星战 Solution

Preface 不可以&#xff0c;总司令 的来源. Description 给定一张 n n n 点 m m m 边的有向图 G G G&#xff0c;有 q q q 次操作分四种&#xff1a; 1 u v&#xff1a;使边 u → v u\to v u→v 失活.2 u&#xff1a;使点 u u u 的所有入边失活.3 u v&#xff1a;使边…...

【spring02】Spring 管理 Bean-IOC,基于 XML 配置 bean

文章目录 &#x1f30d;一. bean 创建顺序&#x1f30d;二. bean 对象的单例和多例❄️1. 机制❄️2. 使用细节 &#x1f30d;三. bean 的生命周期&#x1f30d;四. 配置 bean 的后置处理器 【这个比较难】&#x1f30d;五. 通过属性文件给 bean 注入值&#x1f30d;六. 基于 X…...

Llama 4架构解析与本地部署指南:MoE模型在170亿参数下的效率突破

Meta最新发布的Llama 4系列标志着开源大语言模型(LLM)的重大演进,其采用的混合专家(MoE)架构尤为引人注目。 两大核心模型——Llama 4 Scout(170亿参数含16专家)和Llama 4 Maverick(170亿参数含128专家)——展现了Meta向高效能AI模型的战略转型,这些模型在挑战传统扩…...

`docker run --restart no,always,on-failure,unless-stopped`笔记250406

docker run --restart no,always,on-failure,unless-stopped 笔记250406 docker run --restart 用于配置容器的自动重启策略&#xff0c;当容器意外退出时&#xff0c;Docker 会根据策略自动重新启动容器。这是确保服务高可用的重要参数。 语法 docker run --restart <策略…...

stl的VS的string的内部实现,引用计数的写实拷贝,编码

本章目标 1.stl的vs的string的内部实现 2.引用计数的写实拷贝 3.编码 1.stl的string的内部实现 我们先来看一个例子 string s1; cout<<sizeof(s1)<<endl;我们知道类的内存管理也是遵循内存对齐的规则的. 我们假设当前机器的环境是32位的.string类的内部有三个成…...

Docker 从入门到进阶 (Win 环境) + Docker 常用命令

目录 引言 一、准备工作 1.1 系统要求 1.2 启用虚拟化 二、安装Docker 2.1 安装WSL 2 2.2 安装Docker Desktop 2.3检查是否安装成功 三、配置Docker 3.1 打开Docker配置中心 四、下载和管理Docker镜像 4.1 拉取镜像 4.2 查看已下载的镜像 4.3 运行容器 4.4 查看正…...

C# Winform 入门(12)之制作简单的倒计时

倒计时效果展示 控件展示 以下均是使用label来形成的 label 的 BorderStyle&#xff1a;Fixed3D ForeColor&#xff1a;Red Blackground&#xff1a;Black label 的属性 Name&#xff1a; txtyear txtmonth txtday txttime txtweek txtDays txtHour txtM…...

基于springboot+vue的漫画天堂网

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…...

leetcode每日一题:最大整除子集

题目 368. 最大整除子集 给你一个由 无重复 正整数组成的集合 nums &#xff0c;请你找出并返回其中最大的整除子集 answer &#xff0c;子集中每一元素对 (answer[i], answer[j]) 都应当满足&#xff1a; answer[i] % answer[j] 0 &#xff0c;或 answer[j] % answer[i] …...

【Unity】animator检测某state动画播放完毕方法

博主对动画系统很不熟&#xff0c;可能使用的方法比较曲折&#xff0c;但是我确实没找到更有效的方法了。 unity的这个animator在我看来简直有毛病啊&#xff0c;为什么那么难以获取某状态动画的信息呢&#xff1f;&#xff1f;&#xff1f; 想要知道动画播完没有只有用norma…...

玄机-应急响应-webshell查杀

题目要求&#xff1a; 要求获取四个flag webshell查杀&#xff1a; 常见的webshell&#xff1a; PHP: eval(), system(), exec(), shell_exec(), passthru(), assert(), base64_decode() ASP: Execute(), Eval(), CreateObject() JSP: Runtime.getRuntime().exec() websh…...

小菜Go:Ubuntu下Go语言开发环境搭建

前置要求Ubuntu环境搭建 文章推荐 此处推荐一个比较好的文章&#xff0c;基本按部就班就欧克~ 安装虚拟机&#xff08;VMware&#xff09;保姆级教程&#xff08;附安装包&#xff09;_vmware虚拟机-CSDN博客 安装可能遇到的问题 虚拟机安装遇到的问题如&#xff1a;Exception…...

多功能指示牌是否支持多语言交互?

嘿&#xff0c;朋友们&#xff01;你们知道吗&#xff1f;叁仟多功能指示牌在多语言交互方面可太厉害了&#xff0c;下面就为大家热情介绍一些常见的实现方式和相关说明哦&#xff01; 显示多语言文字&#xff1a;哇哦&#xff0c;在众多国际化的超棒场所&#xff0c;像那充满…...

2025ArkTS语言开发入门之前言

2025ArkTS语言开发入门之前言&#xff08;一&#xff09; 引言 要想学好一门语言&#xff0c;必先会下载对应的编辑器/集成开发环境&#xff0c;ArkTS也是如此&#xff0c;下面我带着大家去下载并安装ArkTS语言的集成开发环境——Dev Eco Studio。 下载 来到华为开发者联盟…...

Python高级爬虫+安卓逆向1.1-搭建Python开发环境

目录 引言&#xff1a; 1.1.1 为什么要安装Python? 1.1.2 下载Python解释器 1.1.3 安装Python解释器 1.1.4 测试是否安装成功 1.1.5 跟大神学高级爬虫安卓逆向 引言&#xff1a; 大神薯条老师的高级爬虫安卓逆向教程&#xff1a; 这套爬虫教程会系统讲解爬虫的初级&…...

深入理解MySQL:核心特性、优化与实践指南

MySQL是一个开源的关系型数据库管理系统(RDBMS)&#xff0c;由瑞典MySQL AB公司开发&#xff0c;目前属于Oracle公司。它是目前世界上最流行的开源数据库之一&#xff0c;广泛应用于各种规模的Web应用和企业系统中。 目录 一、核心特点 关系型数据库&#xff1a; 开源免费&am…...

38常用控件_QWidget的enable属性(2)

实现用另一个按钮切换之前按钮的“可用”状态 在同一个界面中,要求不同的控件的 objectName 也是必须不同的.(不能重复&#xff09; 后续就可以通过 ui->objectName 方式来获取到对应的控件对象了 ui->pushButton // 得到了第一个按钮对应的对象 ui->pushButton 2 //…...

如何单独指定 Android SDK tools 的 monitor.bat 使用特定 JDK 版本

核心概念与背景介绍 在 Android 开发过程中&#xff0c;Android SDK Tools 提供了许多实用工具&#xff0c;其中 monitor.bat 是 Windows 下用于启动 Android Device Monitor 的批处理文件。Device Monitor 可以帮助我们查看日志、内存、线程等运行信息。 JDK 与 monitor.bat …...

【代码随想录 字符串1】 344.反转字符串

自己的 class Solution {public void reverseString(char[] s) {int mid s.length /2;int j1;for (int i 0; i < mid; i) {char tem s[i];s[i] s[s.length -j];s[s.length -j] tem;j;}s.toString();} }双指针 class Solution {public void reverseString(char[] s) {…...

gogs私服对应SSH 协议配置

一、使用非特权端口&#xff08;推荐&#xff09; 1. 修改 Gogs 配置文件 sudo nano /home/git/gogs/custom/conf/app.ini 找到 [server] 部分&#xff0c;修改为&#xff1a; [server] START_SSH_SERVER true SSH_PORT 2222 # 改为1024以上的端口 2. 重启 Gogs sud…...

蓝桥与力扣刷题(74 搜索二维矩阵)

题目&#xff1a;给你一个满足下述两条属性的 m x n 整数矩阵&#xff1a; 每行中的整数从左到右按非严格递增顺序排列。每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target &#xff0c;如果 target 在矩阵中&#xff0c;返回 true &#xff1b;否则&#xff…...

多元高斯分布函数

1、 n n n元向量 假设 n n n元随机变量 X X X X [ X 1 , X 2 , ⋯ , X i , ⋯ , X n ] T μ [ μ 1 , μ 2 , ⋯ , μ i , ⋯ , μ n ] T σ [ σ 1 , σ 2 , ⋯ , σ i , ⋯ , σ n ] T X i ∼ N ( μ i , σ i 2 ) \begin{split} X&[X_1,X_2,\cdots,X_i,\cdots ,X_n…...

【PySpark大数据分析概述】02 Spark大数据技术框架

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PySpark大数据分析与应用 ⌋ ⌋ ⌋ PySpark作为Apache Spark的Python API&#xff0c;融合Python易用性与Spark分布式计算能力&#xff0c;专为大规模数据处理设计。支持批处理、流计算、机器学习 (MLlib) 和图计算 (GraphX)&am…...

JVM 参数调优指南_优化 Java 应用性能

1. 引言 1.1 什么是 JVM 参数调优 JVM 参数调优是指通过调整 Java 虚拟机的各种参数,以优化 Java 应用程序的性能和稳定性。 1.2 JVM 参数调优的重要性 提高性能:优化内存使用和垃圾回收,提升应用程序的响应速度。稳定性:减少内存溢出和垃圾回收暂停时间,提高系统的稳定…...

闭包和装饰器

什么是闭包 闭包&#xff08;Closure&#xff09;是 Python 中一个非常重要的概念&#xff0c;它是一种特殊的函数对象&#xff0c;通常用于封装和延迟计算某些值。以下是闭包的详细定义和解释&#xff1a; 1.闭包的定义 闭包是指一个函数对象&#xff0c;它不仅包含函数的代…...

电脑显示器选购

显示器分类 按尺寸大小 一般显示器屏幕有24寸、27寸、32寸等 按技术分类 LCD显示器 使用液晶分子作为主要材料&#xff0c;以液晶为显示/控制模块制造而成的显示设备。液晶显示器中的液晶体在工作时不发光&#xff0c;而是控制外部的光通过量。当外部光线通过液晶分子时&a…...

论伺服电机在轨道式巡检机器人中的优势及应用实践​

一、引言​ 1.1 研究背景与意义​ 在现代工业生产、电力系统、轨道交通等诸多领域&#xff0c;保障设施设备的安全稳定运行至关重要。轨道式巡检机器人作为一种高效、智能的巡检工具&#xff0c;正逐渐在这些领域崭露头角。它能够沿着预设轨道&#xff0c;对目标区域进行全方位…...

室内指路机器人是否支持与第三方软件对接?

嘿&#xff0c;你知道吗&#xff1f;叁仟室内指路机器人可有个超厉害的技能&#xff0c;那就是能和第三方软件 “手牵手” 哦&#xff0c;接下来就带你一探究竟&#xff01; 从技术魔法角度看哈&#xff1a;好多室内指路机器人都像拥有超能力的小魔法师&#xff0c;采用开放式…...

Docker 命令大全:从入门到精通

一、容器生命周期管理 1. 容器操作基础 # 运行容器 docker run -d --name my_nginx -p 8080:80 nginx:latest# 启动/停止容器 docker start my_nginx docker stop my_nginx# 重启容器 docker restart my_nginx# 删除容器 docker rm my_nginx 2. 容器状态管理 # 查看运行中的…...