Flink-StarRocks详解:第二部分(第52天)

news2024/12/27 12:53:49

文章目录

  • 前言
  • 2. 表设计
    • 2.1 StarRocks表设计
      • 2.1.1 列式存储
      • 2.1.2 索引
      • 2.1.3 加速处理
        • 2.1.3.1 预先聚合
        • 2.1.3.2 分区分桶
        • 2.1.3.3 物化视图
        • 2.1.3.4 列级索引
  • 2.2 数据模型
      • 2.2.1 明细模型
        • 2.2.1.1 适用场景
        • 2.2.1.2 创建表
        • 2.2.1.3 使用说明
      • 2.2.2 聚合模型
        • 2.2.2.1 适用场景
        • 2.2.2.2 原理
        • 2.2.2.3 创建表
        • 2.2.2.4 使用说明
      • 2.2.3 更新模型
        • 2.2.3.1 适用场景
        • 2.2.3.2 原理
        • 2.2.3.3 创建表
        • 2.2.3.4 使用说明
      • 2.2.4 主键模型
        • 2.2.4.1 适用场景
        • 2.2.4.2 原理
        • 2.2.4.3 创建表
        • 2.2.4.4 使用说明


前言

本文为Flink-StarRocks详解后续章节:主要详解StarRocks表设计,聚合,更新,主键三大数据模型。
由于篇幅过长,后续接着下面进行详解:
 StarRocks分区分桶
 StarRocks查询数据湖
 实现即席查询案例

2. 表设计

2.1 StarRocks表设计

2.1.1 列式存储

在这里插入图片描述

StarRocks 中的表由行和列构成。每行数据对应用户一条记录,每列数据具有相同的数据类型。所有数据行的列数相同,可以动态增删列。在 StarRocks 中,一张表的列可以分为维度列(也称为 Key 列)和指标列(也称为 Value 列)。维度列用于分组和排序,指标列的值可以通过聚合函数 sum、count、min、max、hll_union_agg 和 bitmap_union 等累加起来。
在 StarRocks 中,表数据按列存储。物理上,一列数据会经过分块编码、压缩等操作,然后持久化存储到非易失设备上。但在逻辑上,一列数据可以看成是由相同类型的元素构成的一个数组。 一行数据的所有列值在各自的数组中按照列顺序排列,即拥有相同的数组下标。数组下标是隐式的,不需要存储。表中所有的行按照维度列,做多重排序,排序后的位置就是该行的行号。
查询时,如果指定了维度列上的等值条件或者范围条件、并且这些条件中的维度列可以构成表的维度列前缀,则可以利用数据的有序性,使用二分查找法快速锁定目标行。例如,表 table1 包含 event_day、siteid、citycode 和 username 四列,其中 event_day 和 siteid 是维度列。如果查询条件为 event_day = 2020-09-18 和 siteid = 2,因为 event_day 和 siteid 可以构成维度列前缀,因此可以使用二分查找法,只需要处理指定范围内的数据;如果查询条件为 citycode = 4 和 username = Andy,因为 citycode 和 username 不能构成维度列前缀,因此无法使用二分查找法,必须处理整表的数据。

2.1.2 索引

StarRocks 通过前缀索引 (Prefix Index) 和列级索引,能够快速找到目标行所在数据块的起始行号。
StarRocks 表设计原理如下图所示。
在这里插入图片描述

注意:因为不同的行数据量不一样,所以有的前缀在列级索引中会对应2个行号,有的1个,有的0个。
一张表中的数据组织主要由三部分构成:
 前缀索引
表中每 1024 行数据构成一个逻辑数据块 (Data Block)。每个逻辑数据块在前缀索引表中存储一个索引项,索引项的内容为数据块中第一行数据的维度列所构成的前缀,长度不超过 36 字节。前缀索引是一种稀疏索引。使用表中某行数据的维度列所构成的前缀查找前缀索引表,可以确定该行数据所在逻辑数据块的起始行号。
 列级数据块
表中每列数据都按 64 KB 分块存储。数据块作为一个单位单独编码、压缩,也作为 I/O 单位,整体写回设备或者读出。
 列级索引
表中每列数据都有一个独立的行号索引。行号索引表中,该列的数据块和行号一一对应。每个行号索引项由对应数据块的起始行号、位置和长度信息构成。用某行数据的行号查找行号索引表,可以获取包含该行号对应的数据块所在的位置,读取目标数据块后,可以进一步查找数据。
由此可见,通过某行数据的维度列所构成的前缀查找该行数据的过程包含以下五个步骤:

  1. 先查找前缀索引表,获得逻辑数据块的起始行号。
  2. 查找维度列的行号索引,定位到维度列的数据块。
  3. 读取数据块。
  4. 解压、解码数据块。
  5. 从数据块中找到维度列前缀对应的数据项。

2.1.3 加速处理

StarRocks 通过如下机制实现数据的加速处理:

2.1.3.1 预先聚合

StarRocks 支持聚合模型,维度列取值相同的数据行可合并一行。合并后,数据行的维度列取值不变,指标列的取值为这些数据行的聚合结果。用户需要给指标列指定聚合函数。通过预先聚合,可以加速聚合操作。

2.1.3.2 分区分桶

StarRocks 中,表被划分成多个 Tablet,每个 Tablet 多副本冗余存储在 BE 上。BE 和 Tablet 的数量可以根据计算资源和数据规模的变化而弹性伸缩。查询时,多台 BE 可以并行地查找 Tablet,从而快速获取数据。此外,Tablet 的副本可以复制和迁移,从而增强数据可靠性,并避免数据倾斜。总之,分区分桶有效保证了数据访问的高效性和稳定性。

2.1.3.3 物化视图

前缀索引可以加速数据查找,但是前缀索引依赖维度列的排列次序。如果使用非前缀的维度列构造查找谓词,则无法使用前缀索引。用户可以为数据表创建物化视图。物化视图的数据组织和存储与数据表相同,但物化视图拥有自己的前缀索引。在为物化视图创建索引时,可指定聚合的粒度、列的数量和维度列的次序,使频繁使用的查询条件能够命中相应的物化视图索引。

2.1.3.4 列级索引

StarRocks 支持布隆过滤器 (Bloom Filter)、ZoneMap 索引和 位图 (Bitmap) 索引等列级别的索引技术:
 布隆过滤器有助于快速判断数据块中不含所查找的值。
 ZoneMap 索引有助于通过数据范围快速过滤出待查找的值。
 位图索引有助于快速计算出枚举类型的列满足一定条件的行。

2.2 数据模型

建表时,需要指定数据模型 (Data Model),这样数据导入至数据模型时,StarRocks 会按照排序键对数据进行排序、处理和存储。本节介绍 StarRocks 支持的各种数据模型,满足在不同业务场景下的需求。
StarRocks 支持四种数据模型,分别是明细模型 (Duplicate Key Model)、聚合模型 (Aggregate Key Model)、更新模型 (Unique Key Model) 和主键模型 (Primary Key Model)。这四种数据模型能够支持多种数据分析场景,例如日志分析、数据汇总分析、实时分析等。

2.2.1 明细模型

明细模型是默认的建表模型。如果在建表时未指定任何模型,默认创建的是明细类型的表。
创建表时,支持定义排序键。如果查询的过滤条件包含排序键,则 StarRocks 能够快速地过滤数据,提高查询效率。明细模型适用于日志数据分析等场景,支持追加新数据,不支持修改历史数据。

2.2.1.1 适用场景

 分析原始数据,例如原始日志、原始操作记录等。
 查询方式灵活,不需要局限于预聚合的分析方式。
 导入日志数据或者时序数据,主要特点是旧数据不会更新,只会追加新的数据。

2.2.1.2 创建表

例如,需要分析某时间范围的某一类事件的数据,则可以将事件时间(event_time)和事件类型(event_type)作为排序键。使用DUPLICATE KEY来指定排序键。
在该业务场景下,建表语句如下:

CREATE TABLE IF NOT EXISTS test.detail (
    event_time DATETIME NOT NULL COMMENT "事件时间",
    event_type INT NOT NULL COMMENT "事件类型",
    user_id INT COMMENT "用户ID",
    device_code INT COMMENT "设备编码",
    channel INT COMMENT ""
)
DUPLICATE KEY(event_time, event_type)
DISTRIBUTED BY HASH(user_id)
PROPERTIES (
"replication_num" = "1"
);

注意
建表时必须使用 DISTRIBUTED BY HASH 子句指定分桶键,否则建表失败。
自 2.5.7 版本起,StarRocks 支持在建表和新增分区时自动设置分桶数量 (BUCKETS),无需手动设置分桶数量。

这里对建表过程进行演示。
进入starrrcoks管理平台EMR StarRocks Manager,点击左侧SQL Editor。新建查询文件,首先创建数据库

CREATE DATABASE IF NOT EXISTS test;

选中代码,点击左侧的运行。
在这里插入图片描述

创建完成后,点击查询列表右侧的数据库,点击刷新,可以看到test数据库。
在这里插入图片描述

然后将上述建表代码写入查询文件,选中,点击运行
在这里插入图片描述

创建完成后,可以在数据库下看到此张表信息。
在这里插入图片描述

点击左侧导航栏元数据管理,点击test数据库,同样可以看到detail表。点击进去,可以看到元数据信息。
在这里插入图片描述
在这里插入图片描述

2.2.1.3 使用说明

 排序键的相关说明:
 在建表语句中,排序键必须定义在其他列之前。
 排序键可以通过 DUPLICATE KEY 显式定义。本示例中排序键为 event_time 和 event_type。如果未指定,则默认选择表的前三列作为排序键。
 明细模型中的排序键可以为部分或全部维度列。
 建表时,支持为指标列创建 BITMAP、Bloom Filter 等索引。

2.2.2 聚合模型

建表时,支持定义排序键和指标列,并为指标列指定聚合函数。当多条数据具有相同的排序键时,指标列会进行聚合。在分析统计和汇总数据时,聚合模型能够减少查询时所需要处理的数据,提升查询效率。

2.2.2.1 适用场景

适用于分析统计和汇总数据。比如:
 通过分析网站或 APP 的访问流量,统计用户的访问总时长、访问总次数。
 广告厂商为广告主提供的广告点击总量、展示总量、消费统计等。
 通过分析电商的全年交易数据,获得指定季度或者月份中,各类消费人群的爆款商品。
在这些场景中,数据查询和导入,具有以下特点:
 多为汇总类查询,比如 SUM、MAX、MIN等类型的查询。
 不需要查询原始的明细数据。
 旧数据更新不频繁,只会追加新的数据。

2.2.2.2 原理

从数据导入至数据查询阶段,聚合模型内部同一排序键的数据会多次聚合,聚合的具体时机和机制如下:

  1. 数据导入阶段:数据按批次导入至聚合模型时,每一个批次的数据形成一个版本。在一个版本中,同一排序键的数据会进行一次聚合。
  2. 后台文件合并阶段 (Compaction) :数据分批次多次导入至聚合模型中,会生成多个版本的文件,多个版本的文件定期合并成一个大版本文件时,同一排序键的数据会进行一次聚合。
  3. 查询阶段:所有版本中同一排序键的数据进行聚合,然后返回查询结果。
    因此,聚合模型中数据多次聚合,能够减少查询时所需要的处理的数据量,进而提升查询的效率。
    例如,导入如下数据至聚合模型中,排序键为 Date、Country:
Date	Country	PV
2020.05.01	CHN	1
2020.05.01	CHN	2
2020.05.01	USA	3
2020.05.01	USA	4

在聚合模型中,以上四条数据会聚合为两条数据。这样在后续查询处理的时候,处理的数据量就会显著降低。

Date	Country	PV
2020.05.01	CHN	3
2020.05.01	USA	7
2.2.2.3 创建表

例如需要分析某一段时间内,来自不同城市的用户,访问不同网页的总次数。则可以将网页地址 site_id、日期 date 和城市代码 city_code 作为排序键,将访问次数 pv 作为指标列,并为指标列 pv 指定聚合函数为 SUM。
在该业务场景下,建表语句如下:

CREATE TABLE IF NOT EXISTS test.aggregate_tbl (
    site_id LARGEINT NOT NULL COMMENT "id of site",
    date DATE NOT NULL COMMENT "time of event",
    city_code VARCHAR(20) COMMENT "city_code of user",
    pv BIGINT SUM DEFAULT "0" COMMENT "total page views"
)
AGGREGATE KEY(site_id, date, city_code)
DISTRIBUTED BY HASH(site_id)
PROPERTIES (
"replication_num" = "1"
);
2.2.2.4 使用说明

 排序键的相关说明:
 在建表语句中,排序键必须定义在其他列之前。
 排序键可以通过 AGGREGATE KEY 显式定义。
如果 AGGREGATE KEY 未包含全部维度列(除指标列之外的列),则建表会失败。
如果不通过 AGGREGATE KEY 显示定义排序键,则默认除指标列之外的列均为排序键。
 排序键必须满足唯一性约束,必须包含全部维度列,并且列的值不会更新。
 指标列:通过在列名后指定聚合函数,定义该列为指标列。一般为需要汇总统计的数据。
 聚合函数:指标列使用的聚合函数。聚合模型支持的聚合函数,请参见 CREATE TABLE。常见的有SUM、MAX、MIN、REPLACE。
 查询时,排序键在多版聚合之前就能进行过滤,而指标列的过滤在多版本聚合之后。因此建议将频繁使用的过滤字段作为排序键,在聚合前就能过滤数据,从而提升查询性能。
 建表时,不支持为指标列创建 BITMAP、Bloom Filter 等索引。

2.2.3 更新模型

建表时,支持定义主键和指标列,查询时返回主键相同的一组数据中的最新数据。相对于明细模型,更新模型简化了数据导入流程,能够更好地支撑实时和频繁更新的场景。

2.2.3.1 适用场景

实时和频繁更新的业务场景,例如分析电商订单。在电商场景中,订单的状态经常会发生变化,每天的订单更新量可突破上亿。

2.2.3.2 原理

更新模型可以视为聚合模型的特殊情况,指标列指定的聚合函数为 REPLACE,返回具有相同主键的一组数据中的最新数据。
数据分批次多次导入至更新模型,每一批次数据分配一个版本号,因此同一主键的数据可能有多个版本,查询时返回版本最新(即版本号最大)的数据。相对于明细模型,更新模型通过简化导入流程,能够更好地支持实时和频繁更新。
例如下表中,ID 是主键,value 是指标列,_version 是 StarRocks 内部的版本号。其中,ID 为 1 的数据有两个导入批次,版本号分别为 1 和 2;ID 为 2 的数据有三个导入批次,版本号分别为 3、4、5。

ID	value	_version
1	100	1
1	101	2
2	100	3
2	101	4
2	102	5

查询 ID 为 1 的数据时,仅会返回最新版本 2 的数据,而查询 ID 为 2 的数据时,仅会返回最新版本 5 的数据,最终查询结果如下:

ID	value
1	101
2	102
2.2.3.3 创建表

在电商订单分析场景中,经常按照日期对订单状态进行统计分析,则可以将经常使用的过滤字段订单创建时间 create_time、订单编号 order_id 作为主键,其余列订单状态 order_state 和订单总价 total_price 作为指标列。这样既能够满足实时更新订单状态的需求,又能够在查询中进行快速过滤。
在该业务场景下,建表语句如下:

CREATE TABLE IF NOT EXISTS test.update_orders (
    create_time DATE NOT NULL COMMENT "create time of an order",
    order_id BIGINT NOT NULL COMMENT "id of an order",
    order_state INT COMMENT "state of an order",
    total_price BIGINT COMMENT "price of an order"
)
UNIQUE KEY(create_time, order_id)
DISTRIBUTED BY HASH(order_id)
PROPERTIES (
"replication_num" = "1"
); 
2.2.3.4 使用说明

 主键的相关说明:
 在建表语句中,主键必须定义在其他列之前。
 主键通过 UNIQUE KEY 定义。
 主键必须满足唯一性约束,且列的值不会修改。
 设置合理的主键。
 查询时,主键在聚合之前就能进行过滤,而指标列的过滤通常在多版本聚合之后,因此建议将频繁使用的过滤字段作为主键,在聚合前就能过滤数据,从而提升查询性能。
 聚合过程中会比较所有主键,因此需要避免设置过多的主键,以免降低查询性能。如果某个列只是偶尔会作为查询中的过滤条件,则不建议放在主键中。
 建表时,不支持为指标列创建 BITMAP、Bloom Filter 等索引。

2.2.4 主键模型

主键模型支持分别定义主键和排序键。数据导入至主键模型的表时先按照排序键排序后存储。查询时返回主键相同的一组数据中的最新数据。相对于更新模型,主键模型在查询时不需要执行聚合操作,并且支持谓词和索引下推,能够在支持实时和频繁更新等场景的同时,提供高效查询。
说明
 3.0 版本之前,主键模型不支持分别定义主键和排序键。
 自 3.1 版本起,存算分离模式支持创建主键模型表,但是不支持主键模型表开启持久化索引。

2.2.4.1 适用场景

主键模型适用于实时和频繁更新的场景,例如:
 实时对接事务型数据至 StarRocks。事务型数据库中,除了插入数据外,一般还会涉及较多更新和删除数据的操作,因此事务型数据库的数据同步至 StarRocks 时,建议使用主键模型。通过 Flink-CDC 等工具直接对接 TP 的 Binlog,实时同步增删改的数据至主键模型,可以简化数据同步流程,并且相对于 Merge-On-Read 策略的更新模型,查询性能能够提升 3~10 倍。
 利用部分列更新轻松实现多流 JOIN。在用户画像等分析场景中,一般会采用大宽表方式来提升多维分析的性能,同时简化数据分析师的使用模型。而这种场景中的上游数据,往往可能来自于多个不同业务(比如来自购物消费业务、快递业务、银行业务等)或系统(比如计算用户不同标签属性的机器学习系统),主键模型的部分列更新功能就很好地满足这种需求,不同业务直接各自按需更新与业务相关的列即可,并且继续享受主键模型的实时同步增删改数据及高效的查询性能。

2.2.4.2 原理

主键模型是由 StarRocks 全新设计开发的存储引擎支撑。相比于更新模型,主键模型的元数据组织、读取、写入方式完全不同,不需要执行聚合操作,并且支持谓词和索引下推,极大地提高了查询性能。

更新模型整体上采用了 Merge-On-Read 的策略。虽然写入时处理简单高效,但是查询时需要在线聚合多版本。并且由于 Merge 算子的存在,谓词和索引无法下推,严重影响了查询性能。
而主键模型采用了 Delete+Insert 的策略,保证同一个主键下仅存在一条记录,这样就完全避免了 Merge 操作。具体实现方式如下:
 StarRocks 收到对某记录的更新操作时,会通过主键索引找到该条记录的位置,并对其标记为删除,再插入一条新的记录。相当于把 Update 改写为 Delete+Insert。
 StarRocks 收到对某记录的删除操作时,会通过主键索引找到该条记录的位置,对其标记为删除。
这样,查询时不需要执行聚合操作,不影响谓词和索引的下推,保证了查询的高效执行。

2.2.4.3 创建表

 例如,需要按天实时分析订单,则可以将时间 dt、订单编号 order_id 作为主键,其余列为指标列。建表语句如下:

CREATE TABLE IF NOT EXISTS test.primary_orders (
    dt date NOT NULL,
    order_id bigint NOT NULL,
    user_id int NOT NULL,
    merchant_id int NOT NULL,
    good_id int NOT NULL,
    good_name string NOT NULL,
    price int NOT NULL,
    cnt int NOT NULL,
    revenue int NOT NULL,
    state tinyint NOT NULL
) PRIMARY KEY (dt, order_id)
PARTITION BY RANGE(`dt`) (
    PARTITION p20210820 VALUES [('2021-08-20'), ('2021-08-21')),
    PARTITION p20210821 VALUES [('2021-08-21'), ('2021-08-22')),
    PARTITION p20210929 VALUES [('2021-09-29'), ('2021-09-30')),
    PARTITION p20210930 VALUES [('2021-09-30'), ('2021-10-01'))
) DISTRIBUTED BY HASH(order_id)
PROPERTIES (
    "replication_num" = "1",
    "enable_persistent_index" = "true"
);

例如,需要按地域、最近活跃时间实时分析用户情况,则可以将表示用户 ID 的 user_id 列作为主键,表示地域的 address 列和表示最近活跃时间的 last_active 列作为排序键。建表语句如下:

CREATE TABLE IF NOT EXISTS test.primary_users (
    user_id bigint NOT NULL,
    name string NOT NULL,
    email string NULL,
    address string NULL,
    age tinyint NULL,
    sex tinyint NULL,
    last_active datetime,
    property0 tinyint NOT NULL,
    property1 tinyint NOT NULL,
    property2 tinyint NOT NULL,
    property3 tinyint NOT NULL
) PRIMARY KEY (user_id)
DISTRIBUTED BY HASH(user_id)
ORDER BY(`address`,`last_active`)
PROPERTIES (
    "replication_num" = "1",
    "enable_persistent_index" = "true"
);
2.2.4.4 使用说明

 主键相关的说明:
 在建表语句中,主键必须定义在其他列之前。
 主键通过 PRIMARY KEY 定义。
 主键必须满足唯一性约束,且列的值不会修改。本示例中主键为 dt、order_id。
 主键支持以下数据类型:BOOLEAN、TINYINT、SMALLINT、INT、BIGINT、LARGEINT、DATE、DATETIME、VARCHAR/STRING。并且不允许为 NULL。
 分区列和分桶列必须在主键中。
 enable_persistent_index:是否持久化主键索引,同时使用磁盘和内存存储主键索引,避免主键索引占用过大内存空间。通常情况下,持久化主键索引后,主键索引所占内存为之前的 1/10。可以在建表时,在PROPERTIES中配置该参数,取值范围为 true 或者 false(默认值)。
 自 2.3.0 版本起,StarRocks 支持配置该参数。
 如果磁盘为固态硬盘 SSD,则建议设置为 true。如果磁盘为机械硬盘 HDD,并且导入频率不高,则也可以设置为 true。
 建表后,如果需要修改该参数,可使用 ALTER TABLE 修改表的属性 。
 存算分离模式不支持主键模型表开启持久化索引。
 如果未开启持久化索引,导入时主键索引存在内存中,可能会导致占用内存较多。因此建议遵循如下建议:
 合理设置主键的列数和长度。建议主键为占用内存空间较少的数据类型,例如 INT、BIGINT 等,暂时不建议为 VARCHAR。
 在建表前根据主键的数据类型和表的行数来预估主键索引占用内存空间,以避免出现内存溢出。以下示例说明主键索引占用内存空间的计算方式:
 假设存在主键模型,主键为dt、id,数据类型为 DATE(4 个字节)、BIGINT(8 个字节)。则主键占 12 个字节。
 假设该表的热数据有 1000 万行,存储为三个副本。
 则内存占用的计算方式:(12 + 9(每行固定开销) ) * 1000W * 3 * 1.5(哈希表平均额外开销) = 945 M
 通过 ORDER BY 关键字指定排序键,可指定为任意列的排列组合。
注意:如果指定了排序键,就根据排序键构建前缀索引;如果没指定排序键,就根据主键构建前缀索引。
 支持使用 ALTER TABLE 进行表结构变更,但是存在如下注意事项:
 不支持修改主键。
 对于排序键,支持通过 ALTER TABLE … ORDER BY … 重新指定排序键。不支持删除排序键,不支持修改排序键中列的数据类型。
 不支持调整列顺序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1966161.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[C++] vector对比list deque的引出

文章目录 list与vector的对比双端队列dequedeque的特性deque的底层实现原理内存结构块表(Block Array)块(Block) 插入与删除两端插入两端删除 随机访问如何计算位置 迭代器设计 总结 list与vector的对比 vector与list都是STL中非…

实战AR增强现实【OpenCV+Ogre】

作为一份小小的礼物,我想向你展示借助 Ogre 和 OpenCV 自己制作增强现实变得多么容易。你应该知道,除了图形之外,我的另一个兴趣是计算机视觉。 演示将不依赖于 ARCore 或 ARKit 等专有解决方案 - 所有这些都将使用开源代码完成,…

【ROS2】 默认的DDS通信中间件替换为Eclipse Cyclone_DDS (DDS配置方法)

ROS2替换中间件为Cyclone_DDS 1.一些介绍:)2.不同DDS的RMW实现3.默认的FastDDS替换为Cyclone DDSi.安装依赖ii.编译 cyclone-dds 4.配置网络 1.一些介绍:) 上一篇我们探讨了ros1和ros2编写launch的区别 【ROS2】launch启动文件编…

相机外参矩阵

在上一篇文章中,我们学习了如何将相机矩阵分解为内参矩阵和外参矩阵的乘积。在接下来的两篇文章中,我们将更详细地探讨外参矩阵和内参矩阵。首先,我们将探讨查看外参矩阵的各种方式,并在最后进行交互式演示。 SDT工具推荐&#xf…

程序员必知必懂运维技术概念

引言 随着互联网和云计算的迅速发展,传统的单体架构逐渐被微服务架构所取代。这一变化带来了许多新的挑战,如环境一致性、应用的可移植性、服务的扩展性、服务间通信的管理以及安全性等。为了解决这些问题,业界开发了许多工具和技术&#xf…

SPSSAU | Adaboost模型原理及案例实操

AdaBoost(Adaptive Boosting)算法的核心思想是将多个弱分类器组合成一个强分类器。其算法步骤如下: 第一:初始化权重,为每个训练样本分配相等的初始权重; 第二:训练弱分类器,根据当…

如何做OLED屏幕安装方案

制定OLED屏幕安装方案时,需要综合考虑多个方面,包括安装环境、屏幕尺寸、支架选择、电源与信号连接、调试与测试等。以下是一个详细的OLED屏幕安装方案: 一、前期准备 确定安装位置: 根据使用需求和环境条件,选择一个…

基于FPGA的以太网设计(4)----详解PHY的使用(以YT8531为例)

目录 1、前言 2、如何了解PHY芯片? 2.1、总览 2.2、管脚 2.3、编码 2.4、自协商 2.5、环回模式 2.6、睡眠模式 2.7、复位 2.8、PHY地址 3、PHY芯片的寄存器配置 3.1、Basic Control Register (0x00) 3.2、Basic StatusRegister (0x01) 3.3、PHY Specific Status…

重生了,这一世 我一定要学会服务器 只因………

你好,我是Qiuner. 为帮助别人少走弯路和记录自己编程学习过程而写博客 这是我的 github https://github.com/Qiuner ⭐️ ​ gitee https://gitee.com/Qiuner 🌹 如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 😄 (^ ~ ^) 想看更多 那就点个关注吧 我…

IT运维管理与ITSM:理论与实践

IT运维管理和IT服务管理(ITSM)在现代企业信息化过程中占据着举足轻重的地位。它们不仅是确保IT系统稳定运行和业务连续性的关键,还是推动企业数字化转型、提升竞争力的重要力量。本文将结合《IT运维管理和ITSM》文档的内容,深入探…

【C++/STL】:哈希的应用 -- 位图布隆过滤器

目录 🚀🚀前言一,位图1. 位图的概念2. STL库中的位图3. 位图的设计4. 位图的模拟实现5. 位图的优缺点6. 位图相关考察题⽬ 二,布隆过滤器1. 布隆过滤器的概念2. 布隆过滤器的实现3. 布隆过滤器删除问题4. 布隆过滤器的优缺点 点击…

江森自控引入电子签,“碳”索智能建筑数字未来

近年来,伴随着科技的不断进步和市场领域的持续延伸,智能建筑已然成为建筑业科技升级的必经之路。 作为智能建筑领域的全球领导者,江森自控始终走在数字化变革前列,并在业内率先引入了电子合同,通过全流程线上进行的签…

【办公类-53-03】2024年第一学期校历制作(“月/日(星期)”版、排班表、跳过节日和周三)

背景需求: 前期代码制作出2024年第一学期校历,按照5天一周的方法,提取实际工作日。制作成“周计划教案”使用的长日期、短日期 -【办公类-53--01】2024年第一学期校历制作(星火讯飞提取实际工作日,5天一行&#xff0…

Spring-Retry 框架实战经典重试场景

Spring-Retry框架是Spring自带的功能&#xff0c;具备间隔重试、包含异常、排除异常、控制重试频率等特点&#xff0c;是项目开发中很实用的一种框架。 1、引入依赖 坑点&#xff1a;需要引入AOP&#xff0c;否则会抛异常。 xml <!-- Spring-Retry --> <dependency&…

【AI大模型】通义千问:开启语言模型新篇章与Function Call技术的应用探索

文章目录 前言一、大语言模型1.大模型介绍2.大模型的发展历程3.大模型的分类a.按内容分类b.按应用分类 二、通义千问1.通义千问模型介绍a.通义千问模型介绍b.应用场景c.模型概览 2.对话a.对话的两种方式通义千问API的使用 b.单轮对话Vue页面代码&#xff1a;Django接口代码 c.多…

【C++】—— 类与对象(一)

【C】—— 类与对象&#xff08;一&#xff09; 1、类的定义1.1、类定义1.1.1、类定义格式1.1.2、成员变量的标识1.1.3、C 中的 s t r u c t struct struct1.1.4、C 中的内联函数1.1.5、总结 1.2、访问限定符1.3、类域 2、实例化2.1、实例化的概念2.2、对象大小2.2.1、对象的大…

【Hot100】LeetCode—1143. 最长公共子序列

目录 题目1- 思路2- 实现⭐最长公共子序列——题解思路 3- ACM 实现 题目 原题连接&#xff1a;1143. 最长公共子序列 1- 思路 模式识别1——> 求子序列问题 ——> dp数组定义为 i-1 和 j-1 动规五部曲 1- 创建dp数组 dp[i][j]&#xff0c;代表以 i-1 结尾的 text1 和…

“外挂”——逆向软件的分析与破解

本文来源无问社区&#xff0c;更多实战内容&#xff0c;渗透思路可前往查看http://www.wwlib.cn/index.php/artread/artid/11458.html#maodian1 前言&#xff1a; “外挂”的制作离不开软件的分析破解&#xff0c;这平时做ctf中的逆向题是有⼀定的差别的。最直观的区别体现在…

Leetcode 438. 找到字符串中所有字母异位词(java实现)

解题思路&#xff1a;滑动窗口。 异位词的典型解题方法就是用数组来统计出现的个数。本题也不例外。 直接上代码来进行讲解&#xff1a; public List<Integer> findAnagrams(String s, String p) {//初始化返回数组List<Integer> res new ArrayList<>();if …