news 2026/9/14 12:46:42

ClickHouse v23.10.1.1976-stable 版本解析:S3Queue 全面重写、新 SQL 函数与倒排索引优化

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ClickHouse v23.10.1.1976-stable 版本解析:S3Queue 全面重写、新 SQL 函数与倒排索引优化

ClickHouse v23.10.1.1976-stable 版本解析:S3Queue 全面重写、新 SQL 函数与倒排索引优化

【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse

本文基于 ClickHouse 官方变更日志 docs/changelogs/archive/v23.10.1.1976-stable.md 展开,逐条解读 v23.10.1.1976-stable 版本(commit13adae0e42f,对比基线为 v23.9.1.1854-stable,commit8f9a227de1f)的全部变更:哪些行为发生了不兼容变化、新增了哪些函数与 SQL 能力、性能优化集中在哪些路径,以及升级前必须处理的配置项。读完本文,你可以在升级该版本时准确评估风险点,并能结合源码路径验证每项功能的实现位置。

一、版本定位与变更结构

该版本是 2023 年 10 月发布的稳定版,变更日志按官方惯例分为六个区块:

区块含义升级关注度
Backward Incompatible Change不兼容变更,可能直接改变既有行为高,升级前必读
New Feature新函数、新语法、新存储能力中,按需采用
Performance Improvement性能优化
Improvement行为改进与增强中低
Build/Testing/Packaging Improvement构建与打包改进低(自构建者关注)
Bug Fix官方 stable 版本可见缺陷修复按问题域关注

下面按区块逐条解析,并在可溯源处给出当前仓库中的源码位置。

二、不兼容变更:升级前必须了解的 7 个行为变化

2.1 S3Queue 引擎完全重写

这是本版本最大的架构级变更。S3Queue 存储引擎被整体重写:

  • 改变了 ZooKeeper 中的状态保存方式:减少 ZooKeeper 请求量,并在"确定状态不会变化"的场景下缓存 ZooKeeper 状态;
  • S3 轮询策略调整:轮询 S3 的频率降低,行为更温和;
  • TTL 与最大条数限制的维护方式变化:被追踪文件的 TTL / max 限制现在由后台进程维护;
  • 新增系统表system.s3queuesystem.s3queue_log,用于观察队列状态。

对应 PR 为 #54422,解决了 issue #54998。从源码结构看,S3Queue 相关实现位于src/Storages目录下的 S3Queue 模块,升级后可通过新增的两张系统表验证队列运行状态。

2.2 不再自动删除损坏数据分片

此前 ClickHouse 存在一个"自动移除 broken data parts"的选项,本版本起该选项被移除(PR #55184,issue #55174)。这意味着损坏分片不再被静默清理,需要用户显式处理。

与此相关的两个配套变化值得注意:

  • 内存型数据分片(in-memory parts)不再能从前写日志(WAL)中恢复。如果此前配置过 in-memory parts,升级前必须先将其移除(PR #55186);
  • 后续补丁(#55557)保证用户引用已删除的 MergeTree 设置时不会落入UNKNOWN_SETTING错误,而是给出友好提示——这是对删除损坏分片相关设置后的兼容性补救。

2.3 移除 Meilisearch 集成

Meilisearch 集成被移除(PR #55189)。原因是它仅与旧版 0.18 兼容,而 Meilisearch 新版本改变了协议导致无法工作。官方同时表示欢迎社区协助将其修复后重新引入。如果你的应用依赖该集成,升级前需要改用其他全文检索方案。

2.4 directory monitor 更名为 background INSERT

"目录监控"概念被正式更名为background INSERT,所有*directory_monitor*前缀设置全部改名为distributed_background_insert*。官方明确说明向后兼容得到保留:旧设置名作为别名仍然有效(PR #55978)。建议在配置中尽早迁移到新名称。

2.5 区分 send_timeout 与 receive_timeout

网络超时处理中,send_timeoutreceive_timeout被明确区分开(PR #56035),此前两者会被混用。对依赖超时行为调优的部署(例如慢查询、大结果集拉取)可能观察到超时触发时机的差异。

2.6 不同单位的 TimeInterval 比较将抛异常

对单位不同的时间区间(例如IntervalYearIntervalDay)做比较时,本版本起将抛出异常(PR #56090,issue #55942)。此前行为是比较底层的数值而忽略单位——如果你的业务代码恰好依赖了这一旧行为,升级后需要显式转换为同一单位再比较。

三、新特性:函数、语法与存储能力

3.1 新增标量函数

arrayFold:对多个等长数组做归约。函数形式为arrayFold(accum -> expression, accum_init, array1, ..., arrayn),对 n 个基数相同的数组应用 lambda 函数并将结果累积到累加器中(PR #49794)。注意:合并后参数顺序经过调整("arrayFold: Switch accumulator and array arguments",PR #55948),累加器与数组参数的相对位置以最终版本为准。实现位于 arrayFold.cpp。

arrayRandomSample(arr, k):随机采样。从输入数组中返回 k 个元素的随机样本(PR #54391)。此前只能通过arrayReduce('groupArraySample(3)', ...)之类的较繁琐语法实现。

jsonMergePatch:JSON 字符串合并。处理 JSON 对象字符串时,可将多个 JSON 对象字符串按 RFC 7386(JSON Merge Patch)语义合并为一个(PR #54364,后续补丁 #56020 修正了实现细节)。实现位于 jsonMergePatch.cpp。

byteSwap:无符号整数字节序反转。特别是用于内部以无符号整数表示的类型(如 IPv4)的字节反转场景(PR #55211,后续 #55607 补充了 16/32 字节整数支持)。实现位于 byteSwap.cpp。

formatQuery()/formatQuerySingleLine():SQL 字符串格式化。前者返回可能跨多行的格式化查询,后者返回不含换行的单行版本(PR #55239)。两者都可用于在查询中动态生成、美化 SQL 文本。

getHttpHeader:获取 HTTP 请求头。返回发起请求到 ClickHouse 服务器时所用 HTTP 请求头的值;非 HTTP 协议请求或不存在的头返回空字符串(PR #54813)。需要留意:变更日志的 "NO CL ENTRY" 区块记录了该 PR 曾一度被 revert(#56109),说明该功能的最终可用性以实际版本二进制中的函数注册表为准,升级后可直接SELECT getHttpHeader('Host')验证。

3.2 新增聚合函数与组合器

lttb聚合函数:LTTB 降采样。使用 Largest-Triangle-Three-Buckets 算法对数据降采样,专为图表可视化场景设计(PR #53145)。实现位于 AggregateFunctionLargestTriangleThreeBuckets.cpp。典型用法如:

SELECT lttb(100)(x, y) FROM measurements

-ArgMin/-ArgMax聚合组合器。允许"只按最小值/最大值聚合"(PR #54947),并借此将组合器实现整理到独立目录。典型用例是求某指标在组内取极值时的关联字段,同时避免argMin(arg, val)中额外排序开销。

3.3 新增 SQL 语法与语句

  • SHOW SETTING setting_name(PR #55979):SHOW SETTINGS的简化版,查看单个设置项的当前值、默认值与描述;
  • CHECK TABLE ... PART 'part_name'(PR #53404):CHECK TABLE性能与可用性改进——支持发送进度更新、支持取消,并可对指定 part 执行校验;
  • SHOW MERGES(PR #55815,后续 #56124 美化输出):查看正在进行的 merge 过程;
  • RENAME db.t1 TO db.t2省略TABLE关键字(PR #55373);
  • 分区 DDL 支持查询参数ALTER TABLE t DROP PARTITION等语句可使用{name:Type}参数(PR #49516,... ACTION PARTITION的参数支持由 #55604 补齐);
  • SYSTEM DROP SCHEMA FORMAT CACHE [FOR Protobuf](PR #55064):可手动丢弃 Protobuf 等格式的 schema 缓存;
  • DESCRIBE行为增强:新增describe_include_virtual_columns(结果中包含虚拟列)与describe_compact_output(仅返回列名和类型,PR #55129)。

3.4 输入/输出格式扩展

  • DWARF 输入格式(PR #55450):从 ELF 可执行文件/库/目标文件读取调试符号,典型用途是把 coredump 的符号信息灌入表中做分析;
  • Npy 格式(PR #55982):支持读取 NumPy 数组文件,例如:
SELECT * FROM file('example_array.npy', Npy)

3.5 日志引擎的错误处理模式

RabbitMQ、NATS 与 FileLog 引擎支持保留解析失败记录(PR #55477,issue #36035),语义与kafka_handle_error_mode对齐:

引擎设置项出错时填充的虚拟列
NATSnats_handle_error_mode_error_raw_message
RabbitMQrabbitmq_handle_error_mode_error_raw_message
FileLoghandle_error_mode_error_raw_record

取值为default时解析失败抛异常;取值为stream时错误与原始记录写入虚拟列,不中断消费。

3.6 存储引擎与索引

空间填充曲线键的条件下推。若表按空间填充曲线排序(例如ORDER BY mortonEncode(x, y)),则对参数列的范围条件(如x >= 10 AND x <= 20 AND y >= 20 AND y <= 30)可以被用于索引分析(PR #55642,issue #41195 及更早一系列 issue 的延续)。开关设置analyze_index_with_space_filling_curves可启用或禁用该分析,已在 Settings.cpp 中注册。

倒排索引的max_rows_per_postings_list倒排索引不再保存"匹配行过多"的 token,以节省空间并避免低效的索引查找(PR #55616)。旧定义中的density参数(控制何时不保存 token)被移除,替换为更直观的max_rows_per_postings_list(默认 64k),直接限制 posting list 中允许的最大行号数量。该设置同样在 Settings.cpp 中定义。

其他存储侧新能力:

  • optimize_trivial_approximate_count_query:为 EmbeddedRocksDB 存储启用count()近似,并为 StorageJoin 启用 trivial count(PR #55806);
  • force_optimize_projection_name:传入投影名后,ClickHouse 会强制校验该投影在查询中至少被使用一次(PR #56134,issue #55331);
  • create_table_empty_primary_key_by_default:默认ORDER BY ()的控制开关(PR #55899);
  • materialized_postgresql_use_unique_replication_consumer_identifier:允许多个 MaterializedPostgreSQL 表跟随同一张 Postgres 表,默认关闭以保持兼容(PR #55145,issue #54918);
  • 外部 HTTP Basic 认证器(PR #55199):支持将认证委托给外部 HTTP 服务;
  • Replicated 数据库引擎引入 replica groups(PR #54421,issue #53620)。

3.7 Keeper 客户端

新增两条命令(分别由 PR #55485 与 #55898 引入):

  • get_all_children_number:返回某路径下所有后代节点的数量(含间接子节点);
  • get_direct_children_number:返回某路径下直接子节点的数量。

两者配合system.zookeeper可低成本估算子树规模,避免拉取完整节点列表。

四、性能改进

本版本性能条目数量较多,按主题归纳如下:

查询执行与并发

  • query_plan_preserve_num_streams_after_window_functions(PR #50771):窗口函数求值后保留流数量,使并行流处理可以延续到窗口函数之后;
  • 小数据量时释放更多 num_streams(PR #53867);
  • 修复 Context 锁竞争:对大量短并发查询的性能有显著提升(PR #55121);
  • ColumnVector::insertMany/insertManyFrom优化(PR #55714);
  • IN函数中 set 元素类型与列类型不完全一致时的 cast 函数执行期缓存(PR #55712)。

索引

  • 倒排索引创建性能提升 30%:std::unordered_map替换为absl::flat_hash_map(PR #55210);
  • 倒排索引 posting list 在序列化前优化为最小表示,按数据重复度可显著降低索引空间占用(PR #55069);
  • 为二级索引的 marks 缓存设置合理的默认大小,避免反复加载 marks(PR #55654);
  • 读取 skip 索引时避免不必要的 index granule 重建(PR #55683,issue #55653)。

外部聚合与 Map 类型

  • 产生大量临时文件时外部聚合的性能(PR #55489)与内存占用优化(PR #54798);
  • Map 取值的键位置预测优化:实践中同一 Map 列内键结构通常一致,可预测下一行键位置以减少比较(PR #55929)。

数据源

  • ORC 下推过滤(rowgroup 级别,PR #55330);
  • Parquet 结构体字段裁剪在部分场景下不生效的问题修复(PR #56117);
  • RoaringBitmap 序列化前优化(PR #55044)。

五、其他改进(Improvement)

除性能条外,Improvement 区块包含大量行为增强,择要说明:

兼容性与生态

  • Kusto 查询语言方言支持的第二阶段(PR #42510,第一阶段为 #37961);
  • 多项 MySQL 兼容增强:information_schema.tables新增table_rowsinformation_schema.columns新增extra字段(PR #55215);toDayOfWeek()/toYearWeek()/toWeek()支持 String 参数(PR #55589);(add|subtract)(Year|Quarter|...)系列函数支持字符串日期参数(PR #55869);(add|sub)Date()与加/减运算符支持字符串日期 + INTERVAL(PR #55960)。官方明确说明这些改动是为了 MySQL 兼容性,并且是 Tableau Online 集成的需要;
  • untuple()对命名字段元组的结果列名生成规则变化:有别名时列名由 untuple 别名与元组元素别名组合(PR #55123)。

可靠性与易用性

  • async_socket_for_remote模式下分布式查询现在遵守max_threads限制(PR #53504):此前部分查询可能创建多达max_distributed_connections数量的线程,拖垮服务器性能——这是集群环境下容易被忽视的隐患,升级可获得直接收益;
  • 分区内 part 数量超过 1000 时的整体韧性增强,可能减少TOO_MANY_PARTS错误(PR #55526);
  • ReplicatedMergeTree 启动时检查意外 part(本地存在但 ZooKeeper 中没有):意外 part 移入 detached 目录并尝试恢复祖先 part,本版本改为优先恢复最近的祖先而非随机 covered part(PR #55645);
  • 损坏 part 在服务器关闭前打印其磁盘路径(PR #56181):此前 part 损坏导致服务器无法启动时几乎无从定位是哪个 part;
  • date_time_overflow_behavior设置(PR #55696):取值ignore/throw/saturate,控制 Date/Date32/DateTime64/整型/浮点向日期时间类型转换的溢出行为;
  • apply_deleted_mask关闭后可读取被轻量级 DELETE 标记删除的行,便于调试(PR #55952);
  • 日志中更完善地隐藏机密信息(PR #55089);
  • system.parts_columns新增substreamsfilenames字段(PR #55108);system.clusters新增internal_replication字段(PR #55377)。

协议与接口

  • http_write_exception_in_output_format场景下异常输出使用声明的查询格式(PR #55739),并修复了该设置下错误查询结果的问题(PR #56135);
  • use_mysql_types_in_show_columns仅影响SHOW COLUMNS(PR #55481),并新增mysql_map_string_to_text_in_show_columnsmysql_map_fixed_string_to_text_in_show_columns控制String/FixedString输出为TEXT还是BLOB(PR #55617);
  • 异步插入支持原生协议的外部数据(此前仅限内联数据,PR #54730);
  • 查询参数在自定义 HTTP handler 下可用(PR #55521);
  • clickhouse-keeper支持使用内嵌配置运行(PR #56086);
  • clickhouse-local中删除当前数据库后仍可执行部分查询并切换数据库,行为与clickhouse-client一致(PR #55853);
  • 所有字典支持dictionary_use_async_executor设置(PR #55839);
  • RocksDB 写入性能改进(PR #55732);
  • Kusto 实现中的竞态条件修复(PR #55615)。

其他值得注意的行为修正

  • 直接字典配置 lifetime 字段时在建表期即被拒绝(PR #49043,issue #27861);
  • zookeeper_connection重构并新增xid列(PR #50702);
  • OPTIMIZE配合optimize_throw_if_noop=1时,不同 part 投影不同导致的 "unknown reason" 报错被修复(PR #55130);
  • 投影分析现在仅基于查询计划顶层进行,query_plan_optimize_projection设置随之废弃(PR #55112);
  • 按行估计动态调整并行副本数量(PR #51692);
  • 数学减号字符(Unicode 减号)在查询中可用(PR #54100);
  • CSV 格式允许未加引号字符串中包含 CR(PR #56046,issue #39930);
  • minSampleSizeContinous拼写错误修正为minSampleSizeContinuous,旧名保留兼容(PR #56143)。

六、构建 / 测试 / 打包改进

对自构建与 CI 用户而言,本版本包含:

  • AVX 构建修复(PR #55049):此前启用-DENABLE_AVX=ON -DENABLE_AVX2=ON -DENABLE_AVX2_FOR_SPEC_OP=ON构建时,snappy 会因未启用SNAPPY_HAVE_X86_CRC32而报unknown type name '__m256i'编译错误;
  • Docker 初始化逻辑:数据库已初始化则跳过重复初始化,可修复超大库/多节点环境下 1000 次加载失败后容器无限重启的问题(PR #50724);
  • Darwin 专用构建任务:产出包含子模块源码的资源包,可免 checkout 子模块构建(PR #51435);
  • 包完整性:为 tgz 校验 sha512,TGZ.sha512 文件只写文件名;keeper 使用独立仓库(PR #55717);
  • 从 clickhouse-server 包中独立启动 clickhouse-keeper 的问题解决(PR #55226);
  • 测试侧:RabbitMQ 升级至 3.12.6 并改进日志收集(PR #55424)、集成测试新增instance_env_variables选项(PR #55208)、s390x 平台的 HDFS 支持(PR #56128)、jbod balancer 测试去抖动(PR #56175)。

七、缺陷修复(Bug Fix)

该区块修复了 50+ 个用户可见缺陷,按问题域归纳(括号内为 PR 号):

MergeTree / 副本 / Part 管理

  • mutation 中跳过倒排索引文件的硬链接(#47663);
  • adaptive granularity 下ALTER UPDATE的 skip 索引重算修复(#55202);
  • S3 上非 zero-copy 的 ReplicatedMergeTree 无法 drop detached partition 的修复(#55309);
  • SummingMergeTree 的SELECT FINAL中 Nested 列错误合并修复(#55276);
  • 轻量级删除 part 的storage.has_lightweight_delete_parts标记在 part 加载时正确设置;
  • DROP_RANGE与已有 block 提交之间的竞态修复;
  • least_used JBOD 策略的空闲空间统计错误修复(#56030)。

查询执行与崩溃

  • MergeSortingPartialResultTransform中因remerge()后零块导致的 SIGSEGV(#55335);
  • CreatingSetsTransform在错误路径上的数据竞争(#55338,v2 修复 #55786);
  • 稀疏列上的函数执行(#55275)与窗口函数(#55895)修复;
  • 虚拟列 OR 过滤条件查询的过滤逻辑修复(#55418,重提版 #55678);
  • 表函数内子查询求值时标量缺失问题(#56057);
  • Buffer 表并发 ALTER 与 INSERT 导致 "Block structure mismatch"(#55995,最终修复 #56140);
  • QueryNormalizer循环别名崩溃修复(#55602);
  • 窗口函数、show databases limit等多项修正。

外部系统与格式

  • Iceberg 存储的文件获取与一系列修复改进(#55144、#55695);
  • MongoDB 连接问题(#55419)、ODBC 与 MS SQL Server 交互 "Invalid cursor state"(#55558)、MySQL 接口布尔表示(#55427)与文本协议 DateTime 格式化(#55479);
  • AvroConfluent 从 schema registry 拉取 schema 的修复(#55991);
  • Native/ORC 输入格式可能的段错误(#55891);Arrow 字典列输入输出修复(#55989);
  • dateTime64ToSnowflake64()非默认 scale 修复(#55983);
  • 精确浮点解析开启时非法字符串转浮点抛异常(#55861);
  • CTE 含状态函数时禁用谓词下推(#55871);
  • 压缩器在 buffer 未 finalize 时的潜在内存泄漏(#55262);
  • StorageHDFS 内存泄漏(#55370);
  • LDAP 授权角色更新死锁(#55119)与备份死锁(#55132);
  • accurateCastOrNull()修复重新合入(#54629);
  • AS创建的 Distributed 表 DEFAULT 检测修复(#55060)。

八、NO CL ENTRY 与 NOT FOR CHANGELOG 区块说明

变更日志末尾两个区块记录了不对外承诺行为的内部提交,阅读时应注意:

  • NO CL ENTRY区块包含 10 条记录,多为Revert 操作:例如 Revert "Support SAMPLE BY for VIEW"(#55357)、Revert "Add function getHttpHeader"(#56109)、Revert "Fix output/input of Arrow dictionary column"(#56150),以及 dashboard 单图表按钮、pdqsort 排序优化等回滚。这说明这些特性在本版本内不稳定或被撤回,使用相关能力前应在目标版本上实测验证;
  • NOT FOR CHANGELOG / INSIGNIFICANT区块(约 90 条)主要是测试修复、CI 调整、Analyzer/Planner 内部重构、依赖版本提升(croaring 2.0.x、curl 8.4、gRPC 多次升级、protobuf 升级)等内部提交,不影响用户行为。

九、升级建议与仓库内验证路径

结合本文解析,升级到 v23.10.1.1976-stable 前建议按顺序检查:

  1. S3Queue 用户:确认 ZooKeeper 中队列元数据的兼容性与system.s3queuesystem.s3queue_log可用性,这是最大的行为变化;
  2. 使用过 in-memory parts 的部署:升级前移除相关 part 配置(WAL 不再能恢复内存 part);
  3. 依赖自动清理损坏 part 的运维流程:改为显式处理 broken part,并利用新能力——关闭前打印损坏 part 路径(Improvement #56181)定位问题;
  4. 配置迁移*directory_monitor*distributed_background_insert*(旧名仍作别名保留);
  5. 依赖旧行为的 SQL:不同单位 TimeInterval 比较、按底层数值比较的场景需改写;
  6. 验证新能力lttbarrayFoldarrayRandomSamplejsonMergePatchbyteSwapSHOW SETTINGSHOW MERGES、DWARF/Npy 格式等均可通过直接执行 SQL 验证,实现文件分别位于 src/Functions 与 src/AggregateFunctions 目录,设置项定义可查 src/Core/Settings.cpp;
  7. 集群并发短查询场景:Context 锁竞争修复(#55121)与max_threads限流修复(#53504)升级后可观察 QPS 与延迟指标的改善。

变更日志原文(含全部 PR 编号与贡献者署名)见 v23.10.1.1976-stable 变更日志,同目录下的其他归档版本日志可用于做跨版本对比。

【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 12:45:33

可口可乐经典广告《Hilltop》的音乐营销技术解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 12:40:13

OpenClaw+腾讯云实战:广告营销Agent基建部署与成本优化复盘

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 12:38:58

基于狐獴搜索算法的无人机三维路径规划MATLAB实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 12:36:09

PyQt6+MySQL球员管理系统开发:数据库设计、CRUD与打包全攻略

简介&#xff1a;这是一份基于Python、PyQt与MySQL实现球员信息管理的完整教学项目&#xff0c;适合正在学习桌面GUI开发与数据库联动应用的Python初学者&#xff0c;也可作为课程设计或毕业设计的实用参考。压缩包共收录21个文件&#xff0c;包含Python源代码、Qt界面文件&…

作者头像 李华