Doris三种存储模型详解:Duplicate、Aggregate、Unique怎么选?
做数据开发这些年我接触过的OLAP引擎不少但每次给业务方讲解Doris的存储模型还是觉得这块最值得掰开揉碎讲清楚。很多人建表时随手选一个模型等到数据膨胀、查询变慢、明细对不上才回头查文档结果发现一开始的模型就选错了。Apache Doris 的三种存储模型——Duplicate Key明细模型、Aggregate Key聚合模型、Unique Key唯一键模型是整个导入、查询、更新机制的地基。地基打歪了上层再优化也是事倍功半。这篇文章不打算照着官方文档念一遍我会结合我在实际项目中踩过的坑、做过的选型对比把三种模型的原理、适用场景、建表参数、数据导入和查询表现都讲透。无论你是刚接触Doris还是已经用了很久但对模型选择拿不准这篇都能给你一个可以直接抄作业的参考。全文围绕“什么时候该用哪种模型”这个核心问题展开中间会穿插具体建表语句、数据更新表现对比和排查思路希望能帮你少走弯路。1. 为什么要有三种存储模型它们分别解决什么问题1.1 OLAP场景里的两类典型需求先想一个根本问题Doris 的存储模型到底在解决什么。线上报表、用户行为分析、订单统计、日志检索这些场景对数据的要求很不一样。有的要保留每一条原始记录比如点击流日志每一行都要留着后续想怎么钻取都可以有的只关心最终聚合值比如按天统计的用户活跃数原始明细可能只在当天有用过期后没必要一直占着磁盘还有的则需要按某个唯一键去重更新比如订单表同一个订单可能因为状态变更发来多条记录但查询时只想要最新一条。如果所有数据都按同一种方式存储那么必然有一类场景吃亏。保留明细的模型做聚合时就要额外算只保留聚合值的模型想查明细就无能为力而支持更新的模型如果没有好的实现更新性能会很差。Doris 把这三类需求分别抽象成了三种存储模型让用户在建表时按数据特性和查询模式来选择。1.2 存储模型与数据导入、查询的关系存储模型不是简单地在表上贴一个标签它直接影响数据落盘时的处理逻辑。以 Aggregate 模型为例你在建表语句里指定了聚合列和聚合函数后数据导入时如果出现同一维度键的多行它们会按照聚合函数预先做一次合并也就是说存储层已经帮你把“多条明细”压成了“一条聚合值”。这个过程发生在写入路径上所以查询时不需要再用GROUP BY对全表做一遍聚合速度自然快。Duplicate 模型则完全相反它不做任何合并多行相同键的数据会原样保存查询时想怎么聚合就怎么聚合。Unique 模型则是按唯一键去重保留最新版本它有两种实现方式涉及 Merge-On-Read 和 Merge-On-Write这个后面会专门展开。理解了这层关系你就能明白为什么建表时模型选错后面想改是非常麻烦的因为数据已经按既定逻辑存储改模型基本意味着重新设计表和重新导数据。2. 三种存储模型的核心机制与建表要点2.1 Duplicate Key明细模型最灵活但不做任何自动处理我们项目里最早用 Duplicate Key 的场景是埋点日志明细表。JSON 里有什么字段就存什么字段一行是一条事件不做任何合并。建表语法很直观CREATE TABLE log_detail ( event_time DATETIME, client_ip VARCHAR(64), user_id BIGINT, event_type VARCHAR(32), detail JSON, load_time DATETIME ) DUPLICATE KEY(event_time, client_ip) DISTRIBUTED BY HASH(event_time) BUCKETS 10 PROPERTIES(replication_num 3);这里 DUPLICATE KEY 后面列的用途是排序不是去重。它决定了数据在磁盘上按什么顺序排列对查询过滤性能影响很大。比如我们经常按 event_time 范围查询那么 event_time 作为第一列就很合适。常见误区是以为 DUPLICATE KEY 必须包含所有列其实你可以只挑前几列作为排序键剩下的列会被自动放到后面的位置。不过建议不要贪多排序键过长会增加存储和比较开销。Duplicate 模型最大的好处是“原样保留”数据导入多少行表里就有多少行。你可以随时用任意维度做任意粒度的聚合也可以回溯修复逻辑。但代价是存储成本高查询聚合需要实时计算。如果一张表每天新增上亿行而且报表里只用到几种固定聚合方式那么每次查询都现场算不仅慢还浪费机器资源。需要注意的是Duplicate 模型并不是“没有主键”它的排序键仍然可以包含重复值所以严格来说它支持“多个相同键同时存在”。如果你的业务要求某几个字段全局唯一那么就不能只靠 Duplicate 模型需要用户自己在导入时控制或者选用 Unique 模型。2.2 Aggregate Key聚合模型写入时预聚合查询快但丢失明细Aggregate 模型是在我处理流量统计报表时接触到的。业务方只需要按天、按渠道看一下曝光量、点击量明细数据在入库前已经有过一层清洗没必要把每一条广告曝光都留在报表表里。建表时指定聚合列和聚合函数导入时Doris就会自动做合并。看一个典型示例CREATE TABLE ad_agg_report ( ad_id BIGINT, channel VARCHAR(32), day DATE, expose BIGINT SUM, click BIGINT SUM, cost DECIMAL(18, 4) SUM, last_time DATETIME MAX ) AGGREGATE KEY(ad_id, channel, day) DISTRIBUTED BY HASH(ad_id) BUCKETS 8 PROPERTIES(replication_num 3);这里维度列是 ad_id、channel、day度量列 expose、click、cost 使用了 SUM 聚合last_time 使用了 MAX 聚合。导入同一维度键的多行数据时SUM 列会相加MAX 列会取最大值。查询时如果直接用SELECT ad_id, day, SUM(expose) FROM table GROUP BY ad_id, day因为存储层已经预聚合了所以查询引擎可以更快地合并结果特别是面对海量数据时比 Duplicate 模型现场聚合要高效得多。但 Aggregte 模型的坑也很明显一旦设定了聚合函数某些列就再也拿不到原始值了。比如我们用 SUM 存了 click后面业务想看看某渠道单个用户的点击序列这条SQL是查不出来的因为原始明细已经没了。所以我在选型时会问自己一个问题这张表的明细数据以后还有没有用如果答案是有可能那还是老老实实用 Duplicate 模型或者另外留一份明细表不要让报表表既当聚合表又当明细表。另外Aggregate 模型在导入时如果遇到相同维度键新旧数据会合并而不是覆盖。如果你的业务逻辑不是“累加”而是“替换”那就不能用 SUM、MAX这类函数应该思考是否该用 Replace 或者改用 Unique 模型。官方文档里 Aggregate 模型支持多种聚合函数如 SUM、MIN、MAX、REPLACE、HLL_UNION、BITMAP_UNION 等。我们要按业务语义去选比如“去重计数”用 BITMAP_UNION 或 HLL_UNION比 COUNT(DISTINCT) 性能好很多。2.3 Unique Key唯一键模型去重更新但要理解两种实现方式Unique 模型是我日常使用频率最高的因为绝大多数业务表都是“按主键更新”的逻辑比如用户维表、订单状态表、商品库存表。数据源会不断发来同一条主键的更新我们需要在 Doris 里保留最新版本。在建表时一个简单的写法是这样CREATE TABLE order_info ( order_id BIGINT, status VARCHAR(16), update_time DATETIME, amount DECIMAL(18, 2) ) UNIQUE KEY(order_id) DISTRIBUTED BY HASH(order_id) BUCKETS 8 PROPERTIES( replication_num 3, enable_unique_key_merge_on_write true );这里还有一个关键参数enable_unique_key_merge_on_write。如果你不去设置它Doris 默认采用 Merge-On-Read读时合并模式写入时只追加新版本不去动旧数据查询时再把同一主键的多个版本合并取出最新值。这个模式写入吞吐高但查询时因为要做版本合并代价会变大尤其是当同一主键有大量历史版本时查询性能会明显下降。如果设置enable_unique_key_merge_on_write为 true那么走的是 Merge-On-Write写时合并模式导入时直接找到旧版本并标记、覆盖查询时不需要再做版本合并。这种模式的好处是查询性能稳定接近 Duplicate 模型代价是写入时需要额外的查找和删除操作导入速度会降一些。Doris 后续版本中这个优化已经比较成熟所以我在新建 Unique 模型表时基本都开启了写时合并。特别是订单状态表这种主键更新频率很高、查询很频繁的表用写时合并收益很大。这里要特别提醒一下Unique 模型并不是所有列都是主键非主键列在导入时是“replace”行为即用新值覆盖旧值。如果你的业务需要对某个指标做累加那就不能用 Unique 模型应该考虑 Aggregate 模型加 SUM 聚合。想清楚你的更新语义是“覆盖还是累积”模型选择就不会错。3. 如何根据业务场景选择合适的存储模型3.1 一个决策清单从数据特性出发有人问我说选模型有没有一个固定的套路。我的答案是先回答四个问题这张表需要保留原始明细吗如果每条记录都有独立分析价值且不会被更新选 Duplicate。这张表的更新方式是什么如果同一主键的新数据要覆盖旧数据选 Unique。这张表的核心查询是聚合计算吗如果只关心固定的汇总指标且不需要明细选 Aggregate。要不要对超大维度做精确去重计数比如 UV可以考虑 Aggregate 模型配合 BITMAP 或 HLL。在实际项目中我还遇到过一种情况一张表既需要明细又需要频繁聚合同时主键还会更新。这种需求很难用一种模型完美满足。通常的解法是拆表明细表用 Duplicate汇总表用 Aggregate另外再搞一张 Unique 模型的状态表。Doris 的物化视图也能帮你自动化一部分聚合但是物化视图其实是基于明细表的预计算和 Aggregate 模型的写时预聚合在机制上有区别需要我们单独评估。3.2 从数据导入方式倒推模型选择数据导入方式也会反过来影响模型选择。如果你的数据是 Kafka 实时写入的流比如日志那么 Duplicate 模型加上随机分桶会比较合适因为它不关心顺序写入速度最快。如果你的数据是从 MySQL Binlog 同步过来的变更流那几乎一定是 Unique 模型因为每行都是一次主键更新。如果你的数据是离线统计任务产出的结果集比如每天计算一次的用户标签汇总那更适合 Aggregate 模型因为这样 Doris 可以直接把结果作为聚合值存入查询时再叠加聚合。另外还要考虑数据乱序的情况。Unique 模型和 Aggregate 模型在处理乱序数据时会按照排序键做合并或取最新值。如果数据源本身乱序严重比如上游有多个并发任务写入同一主键的不同字段那么使用普通导入会有版本顺序问题。Doris 提供了 Sequence 列的功能允许你指定一个 sequence 字段通常是时间戳或自增ID来决定合并顺序而不是简单以后到达的数据为准。我在处理订单变更流时就用过这个功能确保即使 Kafka 分区内乱序最终表里的状态也是按业务时间而非摄入时间更新。3.3 三种模型的对比速查表我把三种模型的差别整理成了表格方便你对照判断维度Duplicate KeyAggregate KeyUnique Key核心语义保留明细预聚合主键覆盖写入行为原样写入不去重同键自动聚合同键更新为新值更新能力不支持需自行删除或重导部分支持用REPLACE函数天然支持查询特点灵活任何聚合现场算聚合快但明细缺失按主键点查快读时合并模式查询略慢存储占用最高最低中等典型场景日志、行为明细、审计数据报表汇总、UV统计、监控指标订单、用户、商品、状态表这张表不涵盖所有边缘情况比如 Aggregate 模型也可以用 REPLACE 实现类似覆盖的效果但会牺牲一些灵活性。总的来说我的建议是默认情况下不确定就选 Duplicate明确要求主键去重且字段更新频繁选 Unique只保留统计值、不要明细选 Aggregate。4. 实操演示建表、导数据、看效果4.1 准备环境与数据样例为了让你直观看到三种模型的行为差异我模拟一份用户行为数据三行记录。假设场景是一个视频App有用户ID、观看时间、视频ID、播放次数、播放时长这些字段。我先在本地Doris集群中建三张表分别对应三种模型然后导入相同的数据再查看最终内容。测试数据如下CSV格式u1001,2026-03-19 10:00:00,v2001,1,120 u1001,2026-03-19 11:00:00,v2002,2,300 u1001,2026-03-19 12:00:00,v2001,3,450这三行数据中u1001 出现了三次看视频 v2001 也出现了两次。这个数据设计可以同时展示明细保留、聚合、主键覆盖三种效果。4.2 建三张表并导入相同数据先建 Duplicate 表我们希望按 user_id 、view_time 排序CREATE TABLE test_dup ( user_id VARCHAR(16), view_time DATETIME, video_id VARCHAR(16), play_cnt INT, play_duration BIGINT ) DUPLICATE KEY(user_id, view_time) DISTRIBUTED BY HASH(user_id) BUCKETS 3 PROPERTIES(replication_num 1);Aggregate 表维度选 user_idvideo_id度量选播放次数总和和播放时长总和同时我想保留最近观看时间所以再加一个last_view_time DATETIME MAX列CREATE TABLE test_agg ( user_id VARCHAR(16), video_id VARCHAR(16), play_cnt INT SUM, play_duration BIGINT SUM, last_view_time DATETIME MAX ) AGGREGATE KEY(user_id, video_id) DISTRIBUTED BY HASH(user_id) BUCKETS 3 PROPERTIES(replication_num 1);Unique 表只保留每个 user_id 的最新一条记录不考虑 video_id 维度相当于全局用户最新状态CREATE TABLE test_uniq ( user_id VARCHAR(16), view_time DATETIME, video_id VARCHAR(16), play_cnt INT, play_duration BIGINT ) UNIQUE KEY(user_id) DISTRIBUTED BY HASH(user_id) BUCKETS 3 PROPERTIES( replication_num 1, enable_unique_key_merge_on_write true );然后我用 Stream Load 分别导入相同数据。导入命令就不全部贴了核心是 CSV 按列顺序对应。导入之后分别查询SELECT * FROM test_dup ORDER BY user_id, view_time; SELECT * FROM test_agg ORDER BY user_id, video_id; SELECT * FROM test_uniq ORDER BY user_id;4.3 查询结果解读三种模型的行为差异test_dup里应该还是三行顺序按 user_id、view_time 排序数据完全不变。这说明 Duplicate 模型默认不会对相同主键做任何处理。日常做报表时如果我们想统计 u1001 每个视频的播放总时长只能用 GROUP BY 算SELECT user_id, video_id, SUM(play_cnt), SUM(play_duration) FROM test_dup GROUP BY user_id, video_id;这个SQL在数据量小的时候没什么感觉一旦表里有几亿行每次跑一次 GROUP BY 都要几十秒那种痛楚你应该能体会。test_agg里两行记录被压缩成了一行因为维度键是 user_id 和 video_id。具体结果是u1001,v2001, 4, 570, 2026-03-19 12:00:00 u1001,v2002, 2, 300, 2026-03-19 11:00:00第一行来自第一条和第三条记录play_cnt 134play_duration 120450570last_view_time 取更大值 12:00:00。这里可以看到 SUM 和 MAX 的语义。如果我们直接SELECT *看到的数据已经不再是明细所以该表无法回答“u1001 在 10:00 看了什么视频”这样问题。如果你还有这种需求就需要同时保留明细表。test_uniq里只有一行u1001 的最终状态是 12:00:00 的 v2001play_cnt 为 3play_duration 为 450之前两条记录的新增版本没有影响。这里用的是写时合并模式导入时旧版本已经被标记删除查询时直接读出最新数据速度接近普通扫描。如果不开写时合并则表里面会有三条版本记录查询时才合并虽然结果一致但会让查询多耗费一些 CPU。4.4 模型选择错误时的表现如果你在建表时选错了模型会有什么后果我举一个真实经历。之前做订单表上游每天会更新同一订单的物流状态我们一开始用了 Duplicate 模型导致同一个订单号在表里有多条记录。业务方做订单总数统计时同一个订单被算了多次数字虚高。后来改成 Unique 模型才恢复正常。还有一次我们把一套用户标签明细表建成了 Aggregate 模型并且把标签值配成了 REPLACE 聚合函数。一开始没问题后来需要回看某天用户的历史标签才发现原始数据已经被覆盖了无法追溯。这给了我一个教训能用明细表保留原始历史就不要把明细语义强行塞进聚合模型。5. 常见问题与排查技巧实录5.1 为什么我的表在导入后行数变少了如果你用了 Aggregate 模型或 Unique 模型导入后行数变少是正常现象。Aggregate 会因为维度键相同而合并Unique 会因为主键相同而覆盖。如果你用了 Duplicate 模型行数却变少了那就要检查导入方式是不是插入到了重复分区或者表分区设置与导入数据不匹配。每次排查这种问题我习惯先做一步SHOW TABLES确认表模型然后用SHOW ALTER TABLE看有没有发生过表结构变更最后再检查导入任务返回的统计信息比如过滤行数和错误行数。5.2 Unique 模型在开启写时合并之后导入变慢正常吗正常。Merge-On-Write 模式下导入会在写入前做一次主键索引查询如果主键较多这个开销比单纯追加写入要大。如果导入速度确实慢得不能接受可以评估业务是否真的需要那么高的查询性能。如果同一主键更新频率很低读时合并也不是不行。不过在最近的 Doris 版本里写时合并的成熟度已经不错而且还能配合部分列更新功能特别适合从 MySQL 同步来的宽表更新。部分列更新是一个值得一提的能力。默认 Unique 模型导入时如果某行只有部分列有值未提供的列会被覆盖成 NULL 或默认值这可能破坏数据。开启partial_update后你可以只更新指定的少量列其他列保持原值。我在处理用户画像表时经常用到上游一次只传来一个维度字段的更新如果用全列覆盖这张表早就不成样子了。5.3 Aggregate 模型查询时还能不能看到明细不能。一旦使用非 REPLACE 聚合函数明细值就会在导入时被合并。如果你有“既看明细又看汇总”的需求建议建两张表或者使用物化视图。物化视图的底层仍然是明细表只是在导入或查询时将预计算结果落到另一张物理表。如果想让写入更轻量也可以考虑用 Aggregate 模型做汇总层再用 Duplicate 模型做明细层通过定时同步任务把明细层的增量数据汇总进汇总层。5.4 排序键设计有什么讲究三种模型都有 Key 列Key 列决定了排序顺序。对查询优化来说排序键相当于一级索引。最频繁使用的等值过滤条件、范围过滤条件应该尽量放在排序键的前面。比如订单表如果常用 order_id 查询那么 order_id 作为第一个排序键最合适如果常用create_time范围查询并且要求数据按时间有序那么 create_time 也应该靠前。不过 Key 列并不是越多越好每多一列排序、比较、写入的开销都会增加。我见过有人把二十个字段全部放进 Key结果表膨胀得厉害查询却没快多少。合理选择前几个高频过滤字段即可。5.5 如何查看一张表当前的存储模型用SHOW CREATE TABLE table_name就能看到建表语句从DUPLICATE KEY、AGGREGATE KEY、UNIQUE KEY关键字就能判断模型类型。另外还可以查information_schema.tables不过没那么直观。修改模型是不支持的如果模型选错了只能新建表再用 INSERT INTO SELECT 把旧表数据迁移过去。迁移时要注意如果旧表数据量很大直接跑 INSERT INTO SELECT 可能撑爆内存最好按分区或按时间分批迁移。5.6 实时写入场景下的建议我负责过一套实时大屏数据Kafka 接入点击流一方面要展示实时点击量另一方面要保留最近半小时的明细。我的做法是明细数据写入 Duplicate 模型表按事件时间做分区同时通过一个轻量聚合任务把统计结果写入 Aggregate 模型表用来支撑毫秒级的大屏指标查询。这样既没有丢失明细也保证了聚合查询的性能。有些团队喜欢全部用 Unique 模型但 Unique 模型在做任意维度聚合时并不比 Duplicate 有优势反而因为主键索引增加了写入负担所以实时链路里我很少把 Unique 模型当作默认选项。6. 选型之后的管理与维护经验6.1 分区与分桶是模型之外的另一层设计模型管的是“行如何处理”分区和分桶管的是“数据放哪里”。两张表即便是同一种模型分区键不一样查询性能也会差很多。我的经验是对时间范围查询明显的表用日期做分区配合动态分区功能自动维护历史分区对高基数的用户ID、订单ID用哈希分桶使数据均匀分布。Aggregate 模型的预聚合发生在分桶粒度内如果分桶键设计不合理会导致预聚合效果打折扣。所以建表时不要觉得模型选完就万事大吉分区分桶同样需要你认真设计。6.2 监控模型相关的导入行为在运维层面我会重点关注导入任务中的dpp.abnorm.ALL指标和错误日志。Aggregate 模型导入时如果同一批次内有大量维度键冲突会有额外的合并开销导入延迟会变大。Unique 模型开启写时合并后主键冲突越多写放大越明显。你可以通过查看 BE 日志中的rowset_meta变化或者通过审计表观察导入耗时来判断是否存在主键设计不合理导致的性能问题。一句经验如果一张 Unique 表频繁导入小批次数据且主键基数很高性能会显著下降因为每个批次都要去查主键索引。这种场景下可以尝试让上游尽量攒批减少导入次数。Doris 导入本身支持批量不要做成一条一条写入那样对任何模型都是灾难。6.3 模型和查询优化的结合很多人喜欢问“Doris 查询慢怎么办”其实很多问题在模型阶段就已经决定了。举个例子一个 Duplicate 明细表日增数亿行报表需要按天计算 UV如果只是用COUNT(DISTINCT user_id)执行计划会非常慢。如果你在建表时把 user_id 存入 BITMAP 类型的列建一个 Aggregate 模型的表使用BITMAP_UNION聚合函数那么离线预聚合阶段就压缩了基数查询时计算量会小很多。类似这种精确去重场景用模型 位图索引组合是官方推荐做法。如果你确实需要明细表上支持灵活聚合并且数据量很大也可以使用异步物化视图来预计算一些常见的聚合维度避免每次查询都重算。但要注意物化视图的数据新鲜度需要自己维护刷新与 Aggregate 模型的写时合并机制不同。6.4 数据更新频率很高时考虑Sequence列前面提过 Sequence 列我再补充一个实际细节。我们在同步订单状态时Kafka 里同一个订单可能会先发created后发paid再发completed。但因为是并行消费可能出现completed先到达 Dorispaid后到达的情况。如果没有 Sequence 列Doris 会以后到达的数据为准最终把订单状态错误地覆盖回“paid”。这个坑比较隐蔽排查时数据看起来有变化但状态不对。解决办法是给表加一个sequence_col属性指定用业务时间戳比如update_time作为版本依据。导入时Doris会比较新旧数据的update_time只有新值的 sequence 更大时才允许覆盖。官方文档里有详细说明创建表时可以这样设置PROPERTIES( function_column.sequence_type DATETIME, function_column.sequence_col update_time )这个配置对 Unique 模型尤其重要。如果你在同步数据时发现最终数据偶尔不一致先别急着怀疑Doris检查一下是不是缺乏 Sequence 列。7. 最后分享的一点个人体会三种存储模型里其实没有绝对的“最高级”或“最优”只有最适合你当前数据特征的。我在实际项目里见过不少团队因为担心 Duplicate 模型数据量大、查询慢一上来就选 Aggregate 模型结果后面业务要回溯明细时痛苦不堪也见过团队把所有表都建成 Unique 模型结果写入性能平平查询却并不比 Duplicate 快多少。这其中的平衡点需要你对业务形态有清晰认知。我的做法是新建表之前强制自己画一个简单的数据流图标注哪些表是原始数据、哪些是衍生数据、哪些是状态数据。原始数据用 Duplicate统计数据用 Aggregate状态数据用 Unique。每张表对应一个明确的数据语义。这样不仅建表的时候不纠结后续数据治理、任务维护也会更轻松。Doris 的模型机制并不复杂但真正用好它需要你在每个项目里不断实践、复盘。希望这篇文章能让你在下次建表时少一些犹豫。

相关新闻

射线法判断点在多边形内:原理、实现与边界条件详解

射线法判断点在多边形内:原理、实现与边界条件详解

判断点在多边形内(射线法)是我几乎每天都在用的算法。在地图引擎、游戏碰撞检测、图像标注工具里,它都是最基础的那块拼图。这算法听起来高深,其实核心就一句话:从目标点朝任意方向射出一条射线,数一数它和…

2026/10/12 12:30:45 阅读更多 →
多Agent技能管理实战:用GNU Stow和chezmoi建立唯一事实源

多Agent技能管理实战:用GNU Stow和chezmoi建立唯一事实源

1. 事故现场:同一个 skill,怎么可能存了三份上半年我在团队里搭了一套多 agent 的日常工具链,角色也不复杂:一个负责代码评审,一个负责日志排查,一个负责数据查询。最开始为了赶进度,每个 agent…

2026/10/12 12:29:44 阅读更多 →
MyEclipse 2021安装配置与避坑指南:JDK、Tomcat及编码排错

MyEclipse 2021安装配置与避坑指南:JDK、Tomcat及编码排错

简介:MyEclipse 2021.5.24a 是面向 Java 开发者的一体化 IDE 资源包,覆盖 Java SE/EE/ME 桌面应用与 Web 开发场景,也适合使用 Spring、Struts、Hibernate、Tomcat、GlassFish 以及 MySQL 等数据库连接的企业级项目,初学者搭建环境…

2026/10/12 12:29:44 阅读更多 →

最新新闻

Vue实战进阶:从环境配置到动态路由与多端部署要点

Vue实战进阶:从环境配置到动态路由与多端部署要点

学Vue这几年,从最开始只会照着教程敲todo list,到后来完整负责过好几个基于Spring Boot加Vue的前后端分离项目,中间踩过的坑、绕过的弯,攒下来不少东西。这份Vue网站制作学习心得,我按“从入门到实战的进阶之路”来写&…

2026/10/12 13:21:33 阅读更多 →
豆瓣Top250数据分析大作业:Python爬虫+可视化完整源码与避坑指南

豆瓣Top250数据分析大作业:Python爬虫+可视化完整源码与避坑指南

简介:这份资源是面向高校学生与Python初学者的数据可视化课程设计完整方案,围绕豆瓣电影Top250数据集展开,涵盖数据采集、清洗、统计分析与图表呈现全流程,适合用作毕业设计、期末大作业或课程设计的高分参考。压缩包共221个文件&…

2026/10/12 13:21:33 阅读更多 →
基于SpringBoot+Vue的办公管理系统:全栈设计与实现指南

基于SpringBoot+Vue的办公管理系统:全栈设计与实现指南

每年到这个时间点,都会有一批学弟学妹来问我:"毕设选题到底怎么选?Java后端会不会太难?前端是不是要写很多页面?"我的回答一直很统一:如果方向是Java Web或全栈开发,基于SpringBoot …

2026/10/12 13:21:33 阅读更多 →
claude-mem:为Claude打造跨会话长期记忆的本地记忆管理层

claude-mem:为Claude打造跨会话长期记忆的本地记忆管理层

你有没有过这种体验:跟Claude聊一个项目,前期费了好大劲把背景、依赖、约束讲清楚,刚进入正题,上下文窗口满了,或者新开一个会话,全部打回原形。每次对话就像金鱼一样,七秒记忆,项目…

2026/10/12 13:21:33 阅读更多 →
云数据库HTTP API歌单更新实战:权限、批量与避坑指南

云数据库HTTP API歌单更新实战:权限、批量与避坑指南

1. 从一次歌单同步的诡异失败说起做云音乐类小程序,绕不开的一个核心功能就是歌单管理。用户在小程序端新建、编辑、删除歌单,这些操作最终都要落到云数据库里。我最近在重构一个云音乐小程序的管理系统,前面几篇已经把基础架构、页面路由、用…

2026/10/12 13:21:33 阅读更多 →
C++中判断汉字:从编码原理到跨平台实现

C++中判断汉字:从编码原理到跨平台实现

1. 从一次文本统计翻车说起:为什么“判断汉字”没那么简单前阵子帮一个做数据清洗的朋友处理一批用户提交的文本,需求听起来特别朴素:把每条记录里的汉字挑出来,统计一下字数,非汉字的字符(标点、数字、字母…

2026/10/12 13:20:31 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/11 14:36:54 阅读更多 →