Clickhouse之物化视图分享

news2025/2/24 7:01:00

前言

ClickHouse广泛用于用户和系统日志查询场景中,主要针对于OLAP场景,为业务方提供稳定高效的查询服务。在业务场景下,数据以不同的格式、途径写入到clickhouse。用传统JOIN方式查询海量数据,通常有如下痛点:

  1. 每个查询的代码冗长,有的长达1500行、2000行sql,使用和理解上特别痛苦

  2. 性能上无法满足业务诉求,数据量大会内存不足;

  3. 事实表就一张,可是维度表却有多张,关联数据量暴增

  4. 重复计算

如何将这些数据进行整合,以类似ClickHouse宽表的方式呈现给上层使用,用户可以在一张表中查到所需的所有指标,避免提供多表带来的代码复杂度和性能开销问题?

这里将重点介绍如何通过物化视图有效解决上述场景的问题。在介绍之前,先看一下什么是物化视图,以及如何创建、使用,如何增加维度和指标,结合字典增维等场景。

原理篇

物化视图

CREATE MATERIALIZED VIEW [IF NOT EXISTS] [db.]table_name [ON CLUSTER] [TO[db].[table]] [ENGINE = engine] [POPULATE] AS SELECT ...

注意事项

  1. 创建不带[[db].[table]]的物化视图时,必须指定ENGINE。

        

-- 创建本地表
CREATE TABLE download (
  when DateTime,
  userid UInt32,
  bytes Float32
) ENGINE=MergeTree
PARTITION BY toYYYYMM(when)
ORDER BY (userid, when);

-- 往本地表插入数据
INSERT INTO download
  SELECT
    now() + number * 60 as when,
    25,
    rand() % 100000000
  FROM system.numbers
  LIMIT 5000;

-- 创建物化视图
CREATE MATERIALIZED VIEW download_daily_mv
ENGINE = SummingMergeTree -- 指定engine
PARTITION BY toYYYYMM(day) ORDER BY (userid, day)
POPULATE
AS SELECT
  toStartOfDay(when) AS day,
  userid,
  count() as downloads,
  sum(bytes) AS bytes
FROM download
GROUP BY userid, day

-- 查询物化视图
SELECT * FROM download_daily_mv
ORDER BY day, userid 
LIMIT 5

SELECT
    toStartOfMonth(day) AS month,
    userid,
    sum(downloads),
    sum(bytes)
FROM download_daily_mv
GROUP BY userid, month WITH TOTALS
ORDER BY userid, month
  1. 使用[[db].[table]]的物化视图时,官方推荐不使用POPULTE

    1. 若使用POPULATE,会将现有的数据插入到表中

    2. 不使用POPULATE,查询仅包含创建视图后插入表中的数据

    3. 不推荐使用理由:官方说明是因为在创建视图期间插入表中的数据不会插入其中

    4. 对于实际业务场景来说,历史数据不可少,可以通过查询条件方式进行数据同步

        

--明细表
CREATE TABLE counter (
  when DateTime DEFAULT now(),
  device UInt32,
  value Float32
) ENGINE=MergeTree
PARTITION BY toYYYYMM(when)
ORDER BY (device, when)

--插入模拟数据
INSERT INTO counter
  SELECT
    toDateTime('2023-06-19 00:00:00') + toInt64(number/10) AS when,
    (number % 10) + 1 AS device,
    (device * 3) +  (number/10000) + (rand() % 53) * 0.1 AS value
  FROM system.numbers LIMIT 1000000

--目标表(统计表)
CREATE TABLE counter_daily (
  day DateTime,
  device UInt32,
  count UInt64,
  max_value_state AggregateFunction(max, Float32),
  min_value_state AggregateFunction(min, Float32),
  avg_value_state AggregateFunction(avg, Float32)
)
ENGINE = SummingMergeTree()
PARTITION BY tuple()
ORDER BY (device, day)

--创建视图,注意通过条件解决新旧数据
CREATE MATERIALIZED VIEW counter_daily_mv
TO counter_daily -- 无须指定engine,跟表engine一致
AS SELECT
    toStartOfDay(when) as day,
    device,
    count(*) as count,
    maxState(value) AS max_value_state,
    minState(value) AS min_value_state,
    avgState(value) AS avg_value_state
FROM counter
WHERE when >= toDate('2023-06-19 00:00:00')
GROUP BY device, day
ORDER BY device, day

--视图创建后,插入新数据
INSERT INTO counter
  SELECT
    toDateTime('2023-06-19 00:00:00') + toInt64(number/10) AS when,
    (number % 10) + 1 AS device,
    (device * 3) +  (number / 10000) + (rand() % 53) * 0.1 AS value
  FROM system.numbers LIMIT 1000000

--视图创建后,插入历史数据
INSERT INTO counter_daily
SELECT
  toStartOfDay(when) as day,
  device,
  count(*) AS count,
  maxState(value) AS max_value_state,
  minState(value) AS min_value_state,
  avgState(value) AS avg_value_state
FROM counter
WHERE when < toDateTime('2023-06-19 00:00:00')
GROUP BY device, day
ORDER BY device, day

--查询数据(查询目标表与查询物化视图是一样的)
SELECT
  device,
  sum(count) AS count,
  maxMerge(max_value_state) AS max,
  minMerge(min_value_state) AS min,
  avgMerge(avg_value_state) AS avg
FROM counter_daily
GROUP BY device
ORDER BY device ASC

源表、物化视图、目标表的关系

结论

  • 物化视图是源表的查询结果集的一份持久化存储,用于报告聚合数据和解析

  • 产生物化视图的过程就叫做“物化”(materialization),如 as select ... from ...

  • 物化视图是数据库中的预计算逻辑+显式缓存,典型的空间换时间思路

物化视图工作原理

  1. 当向SELECT中指定的源表插入了新行时,这些新行也会发送到该源表的所有物化视图,类似插入触发器,但是同步时机上受限于更新策略

    1. 数据更新策略:

      1. 设置刷新机制:ALTER MATERIALIZED VIEW my_view; UPDATE EVERY 1 HOUR;

      2. 使用视图前手动刷新视图,触发同步,保证数据准确性:REFRESH MATERIALIZED VIEW my_view;

      3. 创建视图时配置:SETTINGS refresh_interval = 3600,单位秒;0:表示禁用自动刷新;>0:表示间隔多久自动刷新;效果同 UPDATE EVERY 1 HOUR;

    2. 历史数据同步策略:

      1. 全量数据同步,通过查询条件控制:WHERE when < toDateTime('2023-06-19 00:00:00')

      2. 设置数据过期时间,保证数据一致性: TTL 30 DAYS

      3. 手动清理过期数据,保证数据一致性:CLEANUP TTL my_view IN blocking;注意:可能会导致一定的服务停止时间或查询延迟

  2. 相对于物化视图,插入不是原子的。因此:同步执行对物化视图的插入,并非所有物化视图都已完全更新并可用于查询

  3. 链式/级联物化视图的插入也是非原子的,同上

  4. 对源表现有数据的任何更改(如更新、删除、删除分区等)都不会更改物化视图。

  5. 代码导航,感兴趣可源码走读

    1. 添加视图 OutputStream, InterpreterInsertQuery.cpp (https://github.com/ClickHouse/ClickHouse/blob/cb4644ea6d04b3d5900868b4f8d686a03082379a/src/Interpreters/InterpreterInsertQuery.cpp#L313)
    
    if (table->noPushingToViews() && !no_destination)
        out = table->write(query_ptr, metadata_snapshot, context);
    else
        out = std::make_shared<PushingToViewsBlockOutputStream>(table, metadata_snapshot, context, query_ptr, no_destination);
    2.构造 Insert , PushingToViewsBlockOutputStream.cpp (https://github.com/ClickHouse/ClickHouse/blob/cb4644ea6d04b3d5900868b4f8d686a03082379a/src/DataStreams/PushingToViewsBlockOutputStream.cpp#L85)
    
    ASTPtr insert_query_ptr(insert.release());
    InterpreterInsertQuery interpreter(insert_query_ptr, *insert_context);
    BlockIO io = interpreter.execute();
    out = io.out;
    3.物化新增数据:PushingToViewsBlockOutputStream.cpp (https://github.com/ClickHouse/ClickHouse/blob/cb4644ea6d04b3d5900868b4f8d686a03082379a/src/DataStreams/PushingToViewsBlockOutputStream.cpp#L331)
    
    Context local_context = *select_context;
    local_context.addViewSource(
        StorageValues::create(
            storage->getStorageID(), metadata_snapshot->getColumns(), block, storage->getVirtuals()));
    select.emplace(view.query, local_context, SelectQueryOptions());
    in = std::make_shared<MaterializingBlockInputStream>(select->execute().getInputStream()

使用篇

背景

在实际使用中,经常遇到一个维度关联的问题,比如将物品的类别、用户的画像信息等带入场景计算;这里简单列举下clickhouse中做维度补全的操作。模拟用户维度数据和物品维度数据生成字典(字典有很多种存储结构,这里主要列举hashed模式)

字典

--创建 用户维度数据 字典
CREATE DICTIONARY dim.dict_user_dim on cluster cluster (
 uid UInt64 ,
 platform String default '' ,
 country String default '' ,
 province String default '' ,
 isp String default '' ,
 app_version String default '' ,
 os_version String default '',
 mac String default '' ,
 ip String default '',
 gender String default '',
 age Int16 default -1
) PRIMARY KEY uid 
SOURCE(
  CLICKHOUSE(
    HOST 'localhost' PORT 9000 USER 'default' PASSWORD '' DB 'dim' TABLE 'user_dim_dis'
  )
) LIFETIME(MIN 1800 MAX 3600) LAYOUT(HASHED());

--创建 物品维度数据 字典
CREATE DICTIONARY dim.dict_item_dim on cluster cluster (
 item_id UInt64 ,
 type_id UInt32 default 0,
 price UInt32 default 0
) PRIMARY KEY item_id 
SOURCE(
  CLICKHOUSE(
    HOST 'localhost' PORT 9000 USER 'default' PASSWORD '' DB 'dim' TABLE 'item_dim_dis'
  )
) LIFETIME(MIN 1800 MAX 3600) LAYOUT(HASHED())

注意事项

  • 语法不做详细介绍,想要更深了解可以参考官方文档

  • 字典的数据是冗余在所有节点的,默认字典的加载方式是惰性加载,也就是需要至少一次查询才能将字典记载到内存,避免一些不使用的字典对集群带来影响。

  • 也可以通过hash分片的方式将用户指定到某个shard,那么字典也可以实现通过hash分片的方式存储在每个节点,间接实现分布式字典,减少数据存储

使用方式

  • 一种是通过dictGet;如果只查询一个key,建议使用dicGet,代码复杂可读性高,同时字典查的value可以作为另一个查询的key

  • 另外一种方式是通过join

--单value方法1:
SELECT
    dictGet('dim.dict_user_dim', 'platform', toUInt64(uid)) AS platform,
    uniqCombined(uid) AS uv
FROM dws.user_product_dis
WHERE day = '2023-06-19'
GROUP BY platform

Query id: 52234955-2dc9-4117-9f2a-45ab97249ea7

┌─platform─┬───uv─┐
│ android  │ 9624 │
│ ios      │ 4830 │
└──────────┴──────┘

2 rows in set. Elapsed: 0.009 sec. Processed 49.84 thousand rows, 299.07 KB (5.37 million rows/s., 32.24 MB/s.)

--多value方法1:
SELECT
    dictGet('dim.dict_user_dim', 'platform', toUInt64(uid)) AS platform,
    dictGet('dim.dict_user_dim', 'gender', toUInt64(uid)) AS gender,
    uniqCombined(uid) AS uv
FROM dws.user_product_dis
WHERE day = '2023-06-19'
GROUP BY
    platform,
    gender

Query id: ed255ee5-9036-4385-9a51-35923fef6e48

┌─platform─┬─gender─┬───uv─┐
│ ios      │ 男     │ 2236 │
│ android  │ 女     │ 4340 │
│ android  │ 未知   │  941 │
│ android  │ 男     │ 4361 │
│ ios      │ 女     │ 2161 │
│ ios      │ 未知   │  433 │
└──────────┴────────┴──────┘

6 rows in set. Elapsed: 0.011 sec. Processed 49.84 thousand rows, 299.07 KB (4.70 million rows/s., 28.20 MB/s.)
--单value方法2:
SELECT
    t2.platform AS platform,
    uniqCombined(t1.uid) AS uv
FROM dws.user_product_dis AS t1
INNER JOIN dim.dict_user_dim AS t2 ON toUInt64(t1.uid) = t2.uid
WHERE day = '2023-06-19'
GROUP BY platform

Query id: 8906e637-475e-4386-946e-29e1690f07ea

┌─platform─┬───uv─┐
│ android  │ 9624 │
│ ios      │ 4830 │
└──────────┴──────┘

2 rows in set. Elapsed: 0.011 sec. Processed 49.84 thousand rows, 299.07 KB (4.55 million rows/s., 27.32 MB/s.)

--多value方法2:
SELECT
    t2.platform AS platform,
    t2.gender AS gender,
    uniqCombined(t1.uid) AS uv
FROM dws.user_product_dis AS t1
INNER JOIN dim.dict_user_dim AS t2 ON toUInt64(t1.uid) = t2.uid
WHERE day = '2023-06-19'
GROUP BY
    platform,
    gender

Query id: 88ef55a6-ddcc-42f8-8ce3-5e3bb639b38a

┌─platform─┬─gender─┬───uv─┐
│ ios      │ 男     │ 2236 │
│ android  │ 女     │ 4340 │
│ android  │ 未知   │  941 │
│ android  │ 男     │ 4361 │
│ ios      │ 女     │ 2161 │
│ ios      │ 未知   │  433 │
└──────────┴────────┴──────┘

6 rows in set. Elapsed: 0.015 sec. Processed 49.84 thousand rows, 299.07 KB (3.34 million rows/s., 20.07 MB/s.)

结论

从查询结果来看,dictGet要更快一些,同时在代码可读性上也要更好一些,可以结合场景使用。

  • 如果在业务开发过程中,遗漏了维度或者指标,则可以通过修改字典和视图来实现,实现方式

-- 新增字典维度
alter table dim.dict_user_dim on cluster cluster modify column if exists gender String default '未知' comment '性别' after item_id;

-- 修改物化视图
alter table my_view_table on cluster cluster_name add column if not exists new_measure AggregateFunction(uniqCombined,UInt32) comment 'new_measure';

实践经验

  • 如果业务表有较频繁的删除或修改,物化视图本地表的引擎需要使用CollapsingMergeTree或VersionedCollapsingMergeTree

  • 如果物化视图是由两表join产生的,则仅有在左表插入数据时才更新。如果只有右表插入数据,则不更新

--创建本地表
CREATE TABLE IF NOT EXISTS ods.click_log_local
ON CLUSTER cluster_01 (
  click_date Date,
  click_time DateTime,
  user_id Int64,
  event_type String,
  city_id Int64,
  product_id Int64
)
ENGINE = ReplicatedMergeTree('/ch/tables/ods/click_log/{shard}','{replica}')
PARTITION BY click_date
ORDER BY (click_date,toStartOfHour(click_time),city_id,event_type)
TTL click_date + INTERVAL 1 MONTH
SETTINGS index_granularity = 8192,
use_minimalistic_part_header_in_zookeeper = 1,
merge_with_ttl_timeout = 86400;

--创建分布式表
CREATE TABLE IF NOT EXISTS ods.click_log_all
ON CLUSTER cluster_01 AS ods.click_log_local
ENGINE = Distributed(cluster_01,ods,click_log_local,rand());
--创建本地表
CREATE MATERIALIZED VIEW IF NOT EXISTS ods.city_product_stat_local
ON CLUSTER cluster_01
ENGINE = ReplicatedSummingMergeTree('/ch/tables/ods/city_product_stat/{shard}','{replica}')
PARTITION BY click_date
ORDER BY (click_date,ts_hour,city_id,product_id)
SETTINGS index_granularity = 8192, use_minimalistic_part_header_in_zookeeper = 1
AS SELECT
  click_date,
  toStartOfHour(click_time) AS ts_hour,
  city_id,
  product_id,
  count() AS visit
FROM ods.click_log_local
GROUP BY click_date,ts_hour,city_id,product_id;

--创建分布式表
CREATE TABLE IF NOT EXISTS ods.city_product_stat_all
ON CLUSTER cluster_01 AS ods.city_product_stat_local
ENGINE = Distributed(cluster_01,ods,city_product_stat_local,rand());
--在查询前针对指定分区,手工触发merge
optimize table city_product_stat_local on cluster cluster_01 
partition '2021-12-01' FINAL DEDUPLICATE by click_date,ts_hour,city_id,product_id

select * from city_product_stat_all mspsa order by click_date 

参考链接

https://clickhouse.com/docs/en/sql-reference/statements/create/view#materialized-view

https://clickhouse.com/docs/knowledgebase/are_materialized_views_inserted_asynchronously

https://clickhouse.com/docs/en/guides/developer/cascading-materialized-views

https://clickhouse.com/docs/en/operations/settings/settings#wait-for-async-insert

https://clickhouse.com/docs/en/operations/settings/settings#optimize-on-insert

https://clickhouse.com/docs/en/integrations/data-formats/json#using-materialized-views

https://clickhouse.com/docs/en/whats-new/changelog/2020#bug-fix-27

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

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

相关文章

【TOP生物信息】基于Scanpy的单细胞数据质控、聚类、标注

扫码关注下方公粽号&#xff0c;回复推文合集&#xff0c;获取400页单细胞学习资源&#xff01; 「写在前面」 Python作为一种高级编程语言&#xff0c;被广泛用于单细胞数据分析&#xff0c;有着以下的优势&#xff1a; 「大量的生物信息学库&#xff1a;」 Python拥有大量的…

【UE 从零开始制作坦克】6-坦克开炮

效果 步骤 1. 添加初学者内容包&#xff08;需要用到其中的音效和粒子效果&#xff09; 2. 接下来制作坦克的炮弹 首先新建一个Actor蓝图类&#xff0c;作为所有发射物体&#xff08;炮弹、机枪子弹等&#xff09;的父类&#xff0c;这里命名为“TotalCategoryOfProjectile”…

从清华高材生拿到百万年薪offer说起

这几天在脉脉上看到一个很火的帖子&#xff0c;帖子内容是一位清华姚班毕业的博士&#xff0c;透露其拿到「亚马逊应用科学家」的offer&#xff0c;Base 110k/月&#xff0b;股票400K分四年给&#xff0c;还有195k的签字费。 清华姚班毕业薪资 看到这张截图博主留下了羡慕的泪…

搞懂了,React 中原来要这样测试自定义 Hooks

React 中自定义的 Hooks 为开发者提供了重用公共方法的能力。然而&#xff0c;如果你是一个测试新手的话&#xff0c;测试这些钩子可能会很棘手。本文中&#xff0c;我们将探索如何使用 React Testing Library 测试库来测试自定义钩子。 如何测试 React 组件 开始前&#xff…

【统计模型】生存分析基本知识介绍

目录 一、生存分析介绍 1.生存分析用途 2.传统方法在分析随访资料时的困难 &#xff08;1&#xff09;生存时间和生存结局都是我们关心的因素 &#xff08;2&#xff09;存在大量失访 &#xff08;3&#xff09;显然&#xff0c;将失访数据无论是算作死亡还是存活都不合理…

CSS基础学习--20 提示工具(Tooltip)

一、定义 提示工具在鼠标移动到指定元素后触发&#xff0c;总共四种样式实例&#xff1a; 二、基础提示框(Tooltip) 提示框在鼠标移动到指定元素上显示 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>CSS基础学习-提…

【RV1126】IIC驱动--EEPROM

文章目录 原理图查找空闲的I2CEEPROM芯片改设备树编写驱动驱动端设备端驱动端和设备端编译成驱动模块应用层的测试代码 原理图查找空闲的I2C 由上面可以知道&#xff0c;空闲了I2C4接口&#xff0c;然后也引出来了。 再找原理图找到具体引脚&#xff1a; I2C4_SCL&#xff1…

第 5 章 机器学习技术的应用(下)

全文目录 机器学习技术的实施方法 预测阶段效果监控 离线预测在线预测 监控点击率的稳定性 真实点击率的稳定性 计算相邻两个区间内点击率分布的 PSI(Population Stability Index, 群体稳定性指标), 小于 0.1 可认为数据相对稳定;预测点击率的稳定性 与系统本身和用户发生变…

Dice Loss

导读 ​ Dice Loss是由 Dice 系数而得名的&#xff0c;Dice系数是一种用于评估两个样本相似性的度量函数&#xff0c;其值越大意味着这两个样本越相似&#xff0c;Dice系数的数学表达式如下&#xff1a; Dice 2 ∣ X ∩ Y ∣ ∣ X ∣ ∣ Y ∣ \text { Dice }\frac{2|X \ca…

Windows10完全卸载oracle19c

Windows10完全卸载oracle19c 1.停止服务2.卸载产品3.清理注册表4.清理环境变量5.清理文件夹 1.停止服务 winR输入service.msc进入服务列表&#xff0c;停止所有的服务 2.卸载产品 点击开始菜找到Oracle&#xff0c;然后点击Oracle安装产品&#xff0c;再点击Universal Inst…

如何安装PHP框架

目录 什么是PHP框架 第一步 安装PHP依赖包 第二步 导入PHP相关包 第三步 解包并切换进指定目录 第四步 在PHP目录内编译安装 第五步 编译 第六步 拷贝配置文件进行编辑 第七步 修改时区 第八步 修改文件指定路径 第九步 将命令加入指定目录进行识别 第十步 进入配置…

【Flutter】Audioplayers 4.1.0 简要使用说明

文章目录 一、前言二、安装和设置三、基本使用1.创建 AudioPlayer 实例2.设置音频源3.控制播放 四、示例代码五、总结 一、前言 Audioplayers 是一个非常实用的 Flutter 插件&#xff0c;它可以帮助我们在 Flutter 应用中播放音频。无论你是想在你的应用中添加背景音乐&#x…

【Python】在同一图形中更加优雅地绘制多个子图

1. 引言 数据可视化非常重要&#xff0c;有一句俗语叫做一图顶千言&#xff0c;我相信好多小伙伴应该都听说过这句话&#xff1b;即使是有人第一次听到&#xff0c;我想应该也会觉得赞成&#xff0c;这足以说明数据可视化的重要性。我们在前一篇博客中&#xff0c;介绍了如何利…

C语言基础 位域

C语言基础&#xff1a;位域 主题&#xff1a;位域&#xff08;bit-field&#xff09; 关键字&#xff1a;位域 冒号 结构体 存储空间 参考链接&#xff1a;C语言中文网&#xff1a;位域 、C菜鸟工具&#xff08;在线编译器&#xff09;、位域知乎问答 注&#xff1a;以下内容中…

VM安装linux虚拟机宿主机连接不上虚拟机问题处理及静态ip设置

VM安装linux虚拟机宿主机连接不上虚拟机问题处理 用 vm安装linux虚拟机宿主机连不上虚拟机&#xff0c;ipconfig宿主机发现VMnet1以及VMnet8的Ip都变成了169.254开头的地址&#xff0c;网上各种方式都试了都不行&#xff0c;要么 是 虚拟机连不上网&#xff0c;要么 是宿主机连…

金融测试岗面试有多难?我有秘招……

最近发现好多人都喜欢往金融测试岗跑&#xff0c;看来是真的很香了&#xff0c;但是你们知不知道面试金融测试岗还是很难的&#xff0c;如果想去面试真的要多做些了解再去&#xff0c;我在这里总结了一份面试文档分享给大家&#xff0c;若有需要&#xff0c;【留言777】即可。 …

windows 系统加固

其实Windows和Linux加固的方法都差不多 1.防火墙 1.防火墙的开启 2.入站规则进行设置 对一些端口更改后可以使用telnet 进行检测端口是否开放 2.安装杀毒软件 3.扫描漏洞&#xff0c;打补丁 一般漏洞扫描可以借用第三方平台对系统漏洞进行扫描。 开启补丁的自动更新 4.用…

【css系列】八股2023/6/18

1.说说设备像素、css像素、设备独立像素、dpr、ppi 之间的区别&#xff1f; css 像素&#xff1a;长度单位&#xff0c;在css规范中&#xff0c;长度单位分为两类&#xff1a;绝对单位 和 相对单位。 设备像素&#xff1a;物理像素&#xff0c;指设备能控制显示的最小物理单位…

计算机视觉的应用8-基于ResNet50对童年数码宝贝的识别与分类

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用8-基于ResNet50对童年数码宝贝的识别与分类&#xff0c;想必做完90后的大家都看过数码宝贝吧&#xff0c;里面有好多类型的数码宝贝&#xff0c;今天就给大家简单实现一下&#xff0c;他们的分类任…

计网大题(6/18)

1.奈奎斯特定理和香农公式 1.奈奎斯特 B1/T ,T是波特 &#xff0c;B成为波特率 奎氏定理&#xff1a;R2Wlog2&#xff08;N&#xff09; &#xff08;W是理想信道带宽&#xff0c;单位是hz&#xff09; 香农公式 R是最大信道容量 信道带宽是W 信噪比是S/N ,(S是平均信号功率…