PostgreSQL时间函数实战:类型、时区与索引避坑指南

上周帮朋友看一条统计SQL,数据怎么都对不上。他写的条件类似dateadd(day, -1, create_time),我一看就明白了——这是把MySQL或SQL Server的写法直接搬到了PostgreSQL里。PG里根本没有dateadd,正确写法是create_time - interval '1 day'。

这类事碰多了之后我发现,PostgreSQL的时间函数看着简单,真要用起来,处处都是暗坑。now()和clock_timestamp()有什么区别?timestamp和timestamptz到底该选哪个?为什么按天分组统计有时会少一天?为什么时间字段明明建了索引却不用?

这篇文章就把PG里和时间相关的函数按场景完整梳理一遍,从类型体系、当前时刻获取、格式化转换、截断对齐、间隔运算到时区处理,最后再说说索引和性能。适合刚接触PG的读者,也适合写了几年SQL但从没认真体会过时间类型的开发者。搞清楚这些,能帮你少走很多弯路。

1. 动手写SQL之前,先搞懂PG的四类时间类型

很多人栽跟头,不是因为函数不会用,而是因为类型没搞懂。PG里的时间类型不算多,但每个都有自己的脾气。

1.1 timestamp和timestamptz:差的不只是名字

timestamp全称是timestamp without time zone,不带时区;timestamptz全称是timestamp with time zone,带时区。这两个名字极具迷惑性,因为timestamptz其实并不在存储时保存你的时区偏移量,它保存的是一个绝对的UTC时刻,只是在展示的时候会根据会话的TimeZone设置转换成你所在的时区。

可以这么理解:timestamp就像一张照片,上面印着钟表显示的时间,你说它是几点就是几点;timestamptz则更像一个全球通用的绝对时间点,它在内部永远记住“这是地球上的哪个瞬间”,至于显示成北京几点还是伦敦几点,只是换个皮肤的事。

-- 当前会话是东八区 SET timezone TO 'Asia/Shanghai'; SELECT '2024-06-01 12:00:00'::timestamp, '2024-06-01 12:00:00'::timestamptz; -- 结果: -- 2024-06-01 12:00:00 | 2024-06-01 12:00:00+08

当你切换会话时区再查一次:

SET timezone TO 'UTC'; SELECT '2024-06-01 12:00:00'::timestamp, '2024-06-01 12:00:00'::timestamptz; -- 结果: -- 2024-06-01 12:00:00 | 2024-06-01 04:00:00+00

看到了吗?timestamp类型不管你怎么切时区,显示都是12点;而timestamptz会随着时区设置重新换算。国内开发环境大多默认东八区,感觉不出差别,一旦你把数据库迁移到云上或者把连接串里的时区改成UTC,之前写的timestamp字段会瞬间感觉“时间穿越了”。这就是大多数时间错乱问题的根源。

我在实际项目里的建议是:业务时间字段统一使用timestamptz,让数据库存绝对时刻,展示和换算交给会话时区。别自己在一个timestamp字段里存“东八区时间”,因为过了两年没人记得这个字段到底存的是哪个时区的钟表时间。

1.2 date、time和interval:各管一段

这四个类型的分工必须时刻清楚:

类型含义典型值适合场景
date只存日期,无时刻2024-06-01生日、交易日期
time只存时刻,无日期12:30:45营业时间、班次
timestamp/timestamptz日期加时刻2024-06-01 12:30:45业务发生时间
interval时间段/时长1 day、3 hours时间加减、计算时长

特别要说interval,它和时间点完全不是一个维度。可以把timestamp想成尺子上的刻度,interval就是一段长度。刻度加长度得到另一个刻度,这是时间加减的基础。

interval的写法也很有讲究:interval '1 day'和interval '24 hours'在大多数情况等值,但在遇到夏令时切换的地区就不一样了。国内没有夏令时,所以这个坑体会不深,但如果你做的业务面向海外用户,interval '1 day'是“按日历上的一天走”,interval '24 hours'是“按固定的小时数走”,这两种时的语义差异会在跨时区的应用里把人折磨疯。

2. 取当前时间:now()、current_timestamp与clock_timestamp()的选择题

PG里取当前时间的函数多到让人眼花,常用的有这些:

函数返回类型特点
now()timestamptz事务开始时刻,事务内保持不变
transaction_timestamp()timestamptz等价于now()
current_timestamptimestamptz等价于now(),SQL标准写法
statement_timestamp()timestamptz当前语句开始时刻,同一事务内不同语句会变化
clock_timestamp()timestamptz真实时钟时间,每次调用都变化
timeofday()textclock_timestamp()的文本形式
current_datedate当前会话时区的日期

2.1 事务稳定时间与实时时钟的差异

now()的全称语义是“事务开始的时间”。一个显式事务里,不管你执行多少条语句、执行多久,now()返回的都是那个事务最开始的值。这个特性非常有用,比如批量插入一批订单,希望所有订单都带上同一个“入库批次时间”,那用now()就完全正确。

clock_timestamp()则完全不同,它是真正去读系统时钟,每调用一次都会变。即使在同一条SQL里,写两个clock_timestamp(),得到的值都可能差几个微秒。

看个直观的例子:

BEGIN; SELECT now(), clock_timestamp(), pg_sleep(2) IS NOT NULL; SELECT now(), clock_timestamp(), pg_sleep(2) IS NOT NULL; SELECT now(), clock_timestamp(); COMMIT; -- 第二个now()和第一个完全一样 -- 而clock_timestamp()两次差了大约4秒

另一个容易混淆的是statement_timestamp()。它返回当前这条SQL开始执行的时刻,在一个事务里执行多条SQL,每条SQL拿到的statement_timestamp()都不相同。如果你想记录“这条语句什么时候跑的”,用它;如果你想记录“这笔业务什么时候发生”,用now()。

2.2 实际开发中应该选哪个

我的选择逻辑非常简单:

  • 写审计字段、创建时间、更新时间,一律用now()。一个事务内多条记录时间戳一致,排查问题时不会出现“同一笔订单两个时间”的困惑。
  • 做数据同步、CDC采集、日志记录,需要精确到操作发生的真实时刻,用clock_timestamp()。比如你在一个循环里逐行更新数据并记录每行被处理的精确时间,now()会让所有行都变成同一个时间,这明显不对。
  • 取“今天的日期”做业务判断,写current_date,不要写cast(now() as date),前者语义更清晰,也少了隐式转换。

注意:now()在PG里既可以在SQL中用,也可以在存储过程、触发器函数里用,效果一致。很多人以为now()就是“当前时间”而已,其实它背后是“事务快照时间”,理解这一点,很多诡异的用法就明白了。

3. 时间与字符串互转:to_char、to_date、to_timestamp的正确姿势

时间函数另一个大板块是格式化和解析。PG提供了一整套模板模式,灵活但也很容易写错。

3.1 to_char格式化参数速查

to_char把时间转成字符串,常用模板如下:

模板含义示例输出
YYYY4位年份2024
YY2位年份24
MM2位月份06
DD2位日期01
HH2424小时制小时14
HH1212小时制小时02
MI分钟30
SS秒45
D星期几(1-7,周日为1)5
IDISO星期几(1-7,周一为1)4
ddd一年中的第几天153
WW一年中的第几周22
IWISO周22
Q季度2
TZ时区缩写CST

最容易被坑的是D和ID。D返回的数字里,周日是1,周一是2,一直到周六是7,这跟国内习惯的“周一=1”完全相反。要做每周报表的分组排序,用ID更符合直觉。

SELECT to_char('2024-06-01'::date, 'D'), -- 周六,返回7 to_char('2024-06-01'::date, 'ID'); -- 周六,返回6

3.2 to_date与to_timestamp解析时的隐藏规则

to_date('20240601', 'YYYYMMDD')这样的解析很直观,但有几个容易踩的细节:

第一,格式串写错会静默“合理化”。比如to_date('2024-06-31', 'YYYY-MM-DD')并不会报错,PG会把6月31日自动滚成7月1日。做数据校验时别指望它给你抛异常。

第二,FX修饰符可以关掉“宽松匹配”。FX表示精确匹配,比如:

SELECT to_date('20240601', 'FXYYYYMMDD'); -- 正常 SELECT to_date('2024-06-01', 'FXYYYYMMDD'); -- 报错,因为中间多了横杠

第三,to_timestamp返回的是timestamptz,不是timestamp。这个很容易忽略。如果你从字符串解析出来的时间要跟一个timestamp类型的列去比较,PG会先把类型对齐,期间时区转换可能让结果出乎意料。

3.3 从一个慢查询说起:避免在条件里写转换

说一个我常见到的性能反例。业务里想按天查订单,有人这么写:

SELECT * FROM orders WHERE to_char(create_time, 'YYYY-MM-DD') = '2024-06-01';

这个写法在功能上没错,但它对create_time做了函数处理后,普通索引完全用不上,只能全表扫描。数据量上百万之后,查询基本就是灾难。

正确做法是用范围条件:

SELECT * FROM orders WHERE create_time >= '2024-06-01 00:00:00' AND create_time < '2024-06-02 00:00:00';

这样既能走索引,语义也更精确。这个只是索引问题的冰山一角,后面专门讲。

4. extract、date_part与date_trunc:按天/周/月统计的基本功

做报表、做漏斗、做留存分析,本质上都是“把时间对齐到某个周期,再分组聚合”。PG提供了三个核心工具:extract、date_part和date_trunc。

4.1 取时间字段的某个部分

extract(field FROM source)是标准SQL写法,date_part('field', source)是PG的老写法,作用完全相同。常用字段有:

字段含义注意
year年
month月1-12
day月中的日1-31
dow星期几周日为0,周六为6
isodowISO星期几周一为1,周日为7
week一年的第几周按ISO标准
quarter季度
epoch距离Unix纪元的秒数含小数,可当时间戳用

epoch是一个被低估的字段。它可以把timestamptz转成数值型,方便在Redis、缓存、外部系统里传递时间。

SELECT extract(epoch FROM now()), extract(epoch FROM now() AT TIME ZONE 'UTC');

这里有个附加的坑:now()是timestamptz,直接extract(epoch FROM now())没问题;但如果你的列是timestamp,PG会先把它当作会话时区的本地时间再转成UTC计算epoch,前后结果可能对不上。最稳妥的做法是统一走timestamptz。

4.2 date_trunc:按自然周期对齐,报表分组利器

date_trunc的单位很丰富:microseconds、milliseconds、second、minute、hour、day、week、month、quarter、year、decade、century、millennium。

它的作用是把时间截断到指定周期的起点:

SELECT date_trunc('day', '2024-06-15 23:59:59'::timestamp); -- 2024-06-15 00:00:00 SELECT date_trunc('week', '2024-06-15 23:59:59'::timestamp); -- 2024-06-10 00:00:00,周一 SELECT date_trunc('month', '2024-06-15 23:59:59'::timestamp); -- 2024-06-01 00:00:00 SELECT date_trunc('quarter', '2024-06-15 23:59:59'::timestamp); -- 2024-04-01 00:00:00

注意week对齐的是周一。如果你希望“周”从周日开始,就需要自己偏移处理。

实际报表场景最能体现它的价值。比如统计某订单表最近7天每天的订单数:

SELECT date_trunc('day', created_at) AS day, count(*) AS order_cnt, sum(total_amount) AS gmv FROM orders WHERE created_at >= now() - interval '7 days' GROUP BY date_trunc('day', created_at) ORDER BY day;

按月统计、按季度统计,只需要把day换成对应单位,SQL骨架完全不用动。这就是date_trunc相比to_char(x, 'YYYY-MM')做分组的优势:返回的仍然是时间类型,排序和后续处理都比字符串方便。

经验:GROUP BY date_trunc(...)时,SELECT里也最好写同样的date_trunc(...),不要只在GROUP BY里写而SELECT里写别的别名表达式,否则语义容易混乱,也容易被其他同事误解。

5. 时间加减与间隔计算:interval和age()的实战组合

时间加减是业务里永远躲不掉的需求:往前推30天、计算两个时间点相隔多久、判断用户是否连续登录。

5.1 时间点直接加减:别把数字当interval

PG里时间加减遵循一个原则:时间点只能加减长度,不能加减普通数字。写create_time + 7是错的,必须写成create_time + interval '7 days'。

不过有个例外:date类型可以直接加减整数,整数表示天数。

SELECT '2024-06-01'::date + 7; -- 2024-06-08 SELECT '2024-06-01'::date + interval '7 days'; -- 2024-06-08 00:00:00

date + 7返回date,date + interval返回timestamp。两个写法结果都正确,但返回类型不同,后续如果还要精确到时分秒,就要考虑类型匹配。

5.2 两个时间相减:结果不是数字

很多人会把两个时间相减后直接当“天数”用,这是PG里最容易出错的点之一。

timestamp - timestamp的结果是interval,不是数值。比如:

SELECT '2024-06-10 12:00:00'::timestamp - '2024-06-01 00:00:00'::timestamp; -- 结果是 9 days 12:00:00,是interval

如果你想要纯粹的天数,该用什么?常见的办法是extract(day FROM ...),但要注意interval里的“天”和“小时”是分开存储的字段,直接extract(day FROM interval)只会把days部分取出来,剩下的时间部分会被丢弃。比如上面那个例子,extract(day FROM result)返回9,但你其实丢掉了12小时。

更稳妥的取“两个时间点之间的总天数”方法:

SELECT extract(epoch FROM ('2024-06-10 12:00:00'::timestamp - '2024-06-01 00:00:00'::timestamp)) / 86400; -- 9.5 天

先把interval换算成秒,再除以一天的秒数,这才是真正完整的天数。

如果是date类型相减,结果就是整数,不存在这个问题:

SELECT '2024-06-10'::date - '2024-06-01'::date; -- 9

5.3 age():算年龄、算工龄的正确打开方式

age()函数按年月日结构返回间隔,适合人类可读的时长表达:

SELECT age('2024-06-10'::date, '2000-01-01'::date); -- 24 years 5 mons 9 days

如果你用普通的timestamp相减去算年龄,得到可能是几千天,可读性太差。age()会自动借位换算成年月日,用来算用户年龄非常合适。

5.4 连续签到类场景的时间窗口判断

判断“最近7天是否有活跃”这类需求,关键的SQL写法是:

SELECT user_id, count(DISTINCT date_trunc('day', active_at)) AS active_days FROM user_actions WHERE active_at >= now() - interval '7 days' AND active_at < now() GROUP BY user_id;

这里的两个细节值得注意:第一,用count(DISTINCT date_trunc(...))而不是直接count(*),因为用户一天可能有多条行为记录,直接count(*)会把同一天算多次;第二,时间窗口用左闭右开>=和<,避免同一时刻的数据被两个窗口重复统计。

顺带一提,判断“用户是否连续登录N天”时,很多人想当然用last_login + interval '1 day' = today这种逐日判断,其实效率很差。更合理的方式是把登录日期序列用窗口函数拉出相邻差值,再判断差值为1的连续段长度。时间函数和窗口函数配合,能做到很多看起来复杂的分析。

6. 时区一致性问题:一次线上统计错位的排错全过程

时区是PG时间函数里最隐蔽的坑,我单独用一节来讲,因为它值得。

6.1 问题现象:凌晨的订单跑去了前一天

有一回做订单报表,按天统计某地区成交额,发现每天早上8点前出的报表,“今日订单”数量总是比前一天的“凌晨订单”少。把明细拉出来一看,明明是当天凌晨0点到8点的订单,统计结果却被算到了前一天。最诡异的是,数据本身看起来没毛病。

6.2 从数据到连接串再到会话时区的逐层排查

排查过程大致分了三步。

第一步,检查数据本身。直接查表,看订单的created_at原始值。发现表里存的值确实是今天凌晨的时间,没有问题。

第二步,检查查询会话的时区。执行SHOW timezone;,结果发现连接串建立后,会话时区是UTC。而业务同事在应用层往里写数据时,没有指定时区,直接用的字符串或者本地时间插入。

第三步,分析问题根因。这个表的created_at是timestamptz类型。应用层用“东八区本地时间”字符串写入时,PG会把这个字符串当成会话时区(UTC)的时间来理解,再转换成UTC绝对时刻存入。于是,本地8点的数据,换算成UTC就是当天0点,而到了次日凌晨0到8点,换算成UTC就成了前一日的16点到23点59分。等到出报表时,数据库又按UTC会话时区读出并展示,看起来自然就差了一天。

6.3 修复方案与长期建议

修复分两层。短期修复,把应用连接串里的时区参数显式指定为东八区,让写入的本地时间字符串能被正确理解;同时把报表查询会话的时区统一设置为业务所属时区。长期建议有三条:

  • 数据库连接串里显式写options=-c timezone=Asia/Shanghai这类参数,杜绝依赖数据库服务端的默认时区。
  • 应用层写入timestamptz字段时,优先传入带时区信息的对象,比如Java里用OffsetDateTime,Python里用带tzinfo的datetime,不要用纯字符串。
  • 所有报表、统计、定时任务,执行前先SET timezone或者统一在连接层约定好,避免某条SQL在错误的时区下运行。

时区问题之所以麻烦,是因为它往往不报错、只出看似“差一点”的数据。查错时如果只盯着SQL本身,很难定位到根因。

经验:遇到时间错位问题,第一件事永远是SHOW timezone;和SELECT * FROM pg_settings WHERE name = 'TimeZone';,把会话时区、数据库默认时区、连接串时区三层全部对齐,再谈别的。

7. 别让函数坑了索引:时间条件查询的性能红线

最后说性能。前面简单提过函数包裹列会导致索引失效,这里展开讲透。

7.1 函数包裹列导致索引失效的案例

假设订单表orders的created_at上有普通B-tree索引,下面这些写法都会让索引失效:

-- 错误写法1:格式化后比较 SELECT * FROM orders WHERE to_char(created_at, 'YYYY-MM-DD') = '2024-06-01'; -- 错误写法2:截断到天再比较 SELECT * FROM orders WHERE date_trunc('day', created_at) = '2024-06-01'::timestamp; -- 错误写法3:只按日期部分比较 SELECT * FROM orders WHERE created_at::date = '2024-06-01'::date;

原因很简单:B-tree索引是按原始列值排序的,当你用函数把列的值变换之后,索引里存的原始顺序就不再适用了,数据库只能全表扫描,逐行计算函数值再比较。

有人问:为什么PG这么“笨”,不能自动识别出date_trunc('day', created_at) = 某天等价于一个范围条件?确实,PG的优化器没聪明到做这种等价变换。这不是BUG,是设计选择。

7.2 日期范围条件的推荐写法

正确的写法永远是范围条件:

SELECT * FROM orders WHERE created_at >= '2024-06-01 00:00:00' AND created_at < '2024-06-02 00:00:00';

如果只查当天,动态写法可以这样:

SELECT * FROM orders WHERE created_at >= current_date AND created_at < current_date + 1;

这样的查询可以直接走created_at上的B-tree索引。我在某次实际优化中,把一条用了to_char(created_at, 'YYYY-MM-DD')的统计查询改成范围条件后,执行时间直接从几百毫秒降到几十毫秒,数据量大约百万级,效果立竿见影。

7.3 如果确实需要在函数上建索引

当然,有些业务实在绕不开函数条件。比如你经常要按date_trunc('day', created_at)来分组或过滤,并且数据量大到必须用索引,PG也支持表达式索引:

CREATE INDEX idx_orders_created_day ON orders (date_trunc('day', created_at));

建了表达式索引后,WHERE date_trunc('day', created_at) = ...就能走这个索引。代价是每次插入、更新都要多算一次表达式并维护索引,写入性能会略降。所以我的建议是:能改写法走普通索引,就别建表达式索引;实在要建,也要先确认查询频率远高于写入频率。

7.4 时间范围查询的边界细节

范围查询有一个必须养成的习惯:永远用“左闭右开”。

-- 推荐:包含起始,排除结束 WHERE created_at >= '2024-06-01 00:00:00' AND created_at < '2024-06-02 00:00:00'; -- 不推荐:用between WHERE created_at BETWEEN '2024-06-01 00:00:00' AND '2024-06-01 23:59:59';

BETWEEN是包含两个端点的闭区间。如果数据里有一条2024-06-01 23:59:59.500,它就不在BETWEEN范围里,但业务上它很可能属于当天。虽然可以写成BETWEEN ... AND '2024-06-01 23:59:59.999999'来补救,但不如直接养成左闭右开的习惯干净。

另外,当created_at是timestamptz而对比值是字符串时,字符串会被隐式转换成timestamptz,转换规则取决于会话时区。这又绕回了时区问题:保证会话时区正确,再写范围条件,否则边界上一样会错。

写到最后,分享一个我现在的固定习惯:任何涉及时间字段的SQL,先问三件事——字段类型是timestamp还是timestamptz、会话时区是什么、条件是否能用上索引。这三件事确认完,大部分和PG时间函数有关的坑都能避开。如果你过去也遇到过“时间错一天”“索引没走”“统计数字对不上”之类的问题,回头看看这些点,基本都能找到答案。

相关新闻

分布式电源接入对配电网故障定位的影响:Python仿真与分析

分布式电源接入对配电网故障定位的影响:Python仿真与分析

1. 为什么分布式电源一进来&#xff0c;故障定位就开始"犯迷糊" 先说点我自己的体会。搞配电网的人都知道&#xff0c;传统配电网的设计思路是"单电源、辐射状"&#xff0c;电能从变电站流向用户&#xff0c;路径清晰&#xff0c;方向和大小都很好预测。所…

2026/10/19 19:59:32 阅读更多 →
MySQL ERROR 1055深度解析:ONLY_FULL_GROUP_BY报错原因与五种解决方案

MySQL ERROR 1055深度解析:ONLY_FULL_GROUP_BY报错原因与五种解决方案

干后端这几年&#xff0c;MySQL 报错里跟开发者打交道最频繁的&#xff0c;我觉得 1055 得排前三。尤其是项目从 5.6 升到 5.7 之后&#xff0c;原来跑得好好的统计查询突然一夜之间全炸了&#xff0c;控制台刷出一串 ERROR 1055 (42000) &#xff0c;后面还挂着一长串 Expr…

2026/10/19 19:59:32 阅读更多 →
个人能力盘点指南:用三层模型和杠杆点系统提升skills

个人能力盘点指南:用三层模型和杠杆点系统提升skills

1. 从“skills”这个词说起&#xff1a;它到底指什么“skills”这个词看起来简单&#xff0c;但放在不同语境里&#xff0c;含义差别很大。有人看到它想到的是简历上那一栏“专业技能”&#xff0c;有人想到的是游戏里的技能树&#xff0c;还有人想到的是团队协作中每个人各自擅…

2026/10/19 19:59:32 阅读更多 →

最新新闻

2026 最新抖音 SEO 推广全攻略,吃透抖音 SEO 视频排名逻辑

2026 最新抖音 SEO 推广全攻略,吃透抖音 SEO 视频排名逻辑

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

2026/10/19 20:50:01 阅读更多 →
菲涅尔衍射模型解析WiFi呼吸检测:从原理到工程实践

菲涅尔衍射模型解析WiFi呼吸检测:从原理到工程实践

1. 从光学衍射到无线感知&#xff1a;这个项目到底在做什么 菲涅尔衍射和WiFi呼吸检测&#xff0c;乍一看是两个八竿子打不着的领域。一个是光学课本里的经典波动光学内容&#xff0c;一个是近几年火起来的无线感知应用。但把这两个东西放在一起&#xff0c;恰恰说明了一个很有…

2026/10/19 20:48:59 阅读更多 →
西门子1200与FactoryIO机械手仿真:状态机实现虚拟调试全流程

西门子1200与FactoryIO机械手仿真:状态机实现虚拟调试全流程

做工业自动化调试&#xff0c;最怕设备还没到场、程序就得交付&#xff1b;最怕机械没接线、电气没上电&#xff0c;写好的逻辑只能在脑子里跑。我前阵子捣鼓的一套FactoryIO机械手仿真取料程序&#xff0c;算是把这个困局撕开了一个口子&#xff1a;FactoryIO提供虚拟车间&…

2026/10/19 20:48:59 阅读更多 →
图表设计实战指南:从认知到维护的完整方法论

图表设计实战指南:从认知到维护的完整方法论

1. 从"diagram-design"这个标题能读出什么 第一次看到"diagram-design"这个标题&#xff0c;我的直觉是&#xff1a;这大概率不是一个单纯的"画图工具推荐"或者"设计规范文档"&#xff0c;而是一个把 图表设计 这件事当成一个完整工…

2026/10/19 20:46:54 阅读更多 →
图表设计方法论:从沟通逻辑到视觉规范的完整实践指南

图表设计方法论:从沟通逻辑到视觉规范的完整实践指南

1. 图表设计&#xff1a;从“画出来”到“讲清楚”这些年我看了不少技术文档、项目方案和系统说明&#xff0c;发现一个共性问题&#xff1a;大部分人根本不把图表当“设计”来做&#xff0c;而是当“画图”来应付。打开绘图工具&#xff0c;拖几个方框&#xff0c;连几条线&am…

2026/10/19 20:43:51 阅读更多 →
Python+Vue游戏装备交易商城系统:架构设计与实战全解析

Python+Vue游戏装备交易商城系统:架构设计与实战全解析

“基于PythonVue的游戏装备交易商城系统”这个标题&#xff0c;我太熟了。这几乎是每一届想做点东西但又不想只写个管理系统的同学都会碰到的题&#xff0c;也是后台私信里被问得最多的项目类型之一。但说句实话&#xff0c;真正把“交易”两个字做明白的&#xff0c;十个里可能…

2026/10/19 20:42:50 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介&#xff1a;本资源为电源技术方向的学术研究文档&#xff0c;聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略&#xff0c;面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 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/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址&#xff1a; https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集&#xff0c;共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 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/19 2:54:50 阅读更多 →
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/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练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/18 12:16:16 阅读更多 →