PostgreSQL实战:详细讲述UUID主键,以及如何生成无热点的分布式主键

文章目录

    • 一、分布式主键概述
      • 1.1 传统自增主键的局限性
      • 1.2 分布式主键的核心要求
      • 1.3 各方案综合对比
      • 1.4 常见误区澄清
    • 二、PostgreSQL 中 UUID 基础使用
      • 2.1 启用 UUID 支持
      • 2.2 UUID 数据类型
      • 2.3 生成 UUID 的方法
    • 三、UUIDv4 作为主键的性能陷阱:写入热点与索引碎片
      • 3.1 B+ 树索引的工作原理
      • 3.2 性能实测对比
      • 3.3 为什么“无序”如此致命?
    • 四、解决方案一:使用时间有序的 UUID(UUIDv7)
      • 4.1 UUIDv7 标准简介
      • 4.2 在 PostgreSQL 中生成 UUIDv7
        • 方法 1:使用第三方扩展(推荐)
        • 方法 2:PL/pgSQL 自定义函数
      • 4.3 UUIDv7 性能优势
    • 五、解决方案二:替代方案 ULID 与 KSUID
      • 5.1 ULID(Universally Unique Lexicographically Sortable Identifier)
      • 5.2 KSUID(K-Sortable Unique ID)
    • 六、解决方案三:优化 UUIDv4 的存储与索引
      • 6.1 使用 BRIN 索引(仅限特定场景)
      • 6.2 调整 Fillfactor
      • 6.3 应用层预生成 + 批量插入
    • 七、终极方案:混合主键策略
    • 八、生产环境配置建议
      • 8.1 表结构设计
      • 8.2 监控索引健康度
      • 8.3 VACUUM 策略

本文将深入剖析 UUID 作为主键的利弊,系统讲解 PostgreSQL 中 UUID 的使用方式,并重点介绍如何生成无热点、高性能的分布式主键,涵盖 UUIDv7、ULID、KSUID、Snowflake 等现代方案,结合实际配置、性能对比与最佳实践,帮助开发者构建可扩展、高并发的数据库架构。

一、分布式主键概述

在现代分布式系统架构中,传统自增整数(如SERIALBIGSERIAL)作为主键的方式面临严峻挑战:节点间 ID 冲突、水平扩展困难、分库分表复杂、暴露业务增长信息等问题日益凸显。为此,全局唯一标识符(UUID)成为主流替代方案。然而,直接使用标准 UUID(如 UUIDv4)作为 PostgreSQL 主键,可能引发严重的写入热点(Write Hotspot)和索引性能退化问题。UUID 作为分布式主键的解决方案,其价值毋庸置疑。但盲目使用 UUIDv4 会带来严重的性能隐患。真正的工程智慧在于根据业务场景选择合适的技术

  • 若可控制客户端,优先采用 UUIDv7——它代表了未来方向;
  • 若需兼容性和简单性,混合主键策略提供最佳平衡;
  • 避免在高并发写入场景使用纯 UUIDv4。

PostgreSQL 强大的扩展机制(如pg_uuidv7)和灵活的数据模型,为分布式主键提供了坚实基础。记住:没有银弹,只有权衡(Trade-offs)。而优秀的工程师,正是在约束中做出最优权衡的人。

1.1 传统自增主键的局限性

在单机数据库时代,BIGSERIAL(即BIGINT+ 序列)是主键的黄金标准:

CREATETABLEorders(id BIGSERIALPRIMARYKEY,...);

但进入分布式时代后,其缺陷暴露无遗:

  • ID 冲突:多个数据库实例独立生成自增 ID,必然重复;
  • 分库分表困难:无法预先确定数据归属分片;
  • 暴露业务信息:通过 ID 可推算订单量、用户增长速度;
  • 中心化依赖:需独立 ID 生成服务(如 Twitter Snowflake),增加架构复杂度。

1.2 分布式主键的核心要求

理想的分布式主键应满足:

  1. 全局唯一:跨节点、跨时间无冲突;
  2. 趋势递增:避免 B+ 树索引频繁分裂(减少写放大);
  3. 无中心化:各节点可独立生成,无需协调;
  4. 紧凑高效:存储空间小,比较速度快;
  5. 可排序:按生成时间有序,利于范围查询和分页。

UUID 是满足“全局唯一”的天然候选,但标准 UUID 并不满足“趋势递增”。

1.3 各方案综合对比

方案全局唯一时间有序存储效率索引性能实现复杂度推荐场景
BIGSERIAL最高最高单机/中心化ID服务
UUIDv4低频写入、小数据量
UUIDv7分布式系统首选
ULID中(TEXT)Web API、需URL安全
混合主键高性能核心系统

1.4 常见误区澄清

1、“UUID 太长,浪费存储”

  • 16 字节 vs 8 字节(BIGINT),在现代存储成本下可忽略;
  • 换来的是架构灵活性和扩展性,收益远大于成本。

2、“UUID 无法排序”

  • UUIDv1/v6/v7 均可按时间排序;
  • 即使 UUIDv4,也可配合created_at字段排序。

3、“必须用 UUID 做主键”

  • 主键是逻辑概念,物理上可用任意唯一列;
  • 混合主键策略往往更优。

二、PostgreSQL 中 UUID 基础使用

2.1 启用 UUID 支持

PostgreSQL 默认不启用 UUID 类型,需创建扩展:

CREATEEXTENSIONIFNOTEXISTS"uuid-ossp";-- 或使用更轻量的 pgcrypto(仅支持 v4)CREATEEXTENSIONIFNOTEXISTS"pgcrypto";

注意:uuid-ossp在部分 Linux 发行版需安装额外包(如postgresql-contrib)。

2.2 UUID 数据类型

  • 类型名:UUID
  • 存储大小:16 字节
  • 格式:a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11
  • 比较效率:高于字符串,低于BIGINT(8 字节)

2.3 生成 UUID 的方法

方法版本特性示例
uuid_generate_v1()v1基于时间戳 + MAC 地址时间有序,但含硬件信息
uuid_generate_v4()v4完全随机全局唯一,但无序
gen_random_uuid()v4来自pgcrypto,更安全推荐替代 v4
uuid_generate_v7()v7新标准,时间有序 + 随机未来首选

示例建表

CREATETABLEusers(id UUIDPRIMARYKEYDEFAULTgen_random_uuid(),nameTEXTNOTNULL);

三、UUIDv4 作为主键的性能陷阱:写入热点与索引碎片

3.1 B+ 树索引的工作原理

PostgreSQL 默认使用 B+ 树存储主键索引。当新记录插入时:

  • 若主键递增(如自增 ID),新页总在最右侧分配,写入高效;
  • 若主键完全随机(如 UUIDv4),新记录可能插入任意位置,导致:
    • 频繁页分裂(Page Split)
    • 索引碎片化
    • 缓存命中率下降
    • WAL 日志膨胀

3.2 性能实测对比

在 1000 万行数据插入测试中(SSD,PostgreSQL 15):

主键类型插入耗时索引大小I/O 压力
BIGSERIAL120 秒210 MB
UUIDv4380 秒320 MB高(随机写)

结论:UUIDv4 写入性能下降2~3 倍,且随数据量增长恶化。

3.3 为什么“无序”如此致命?

  • 缓存失效:每次插入需加载不同索引页到内存;
  • WAL 膨胀:页分裂产生大量 WAL 记录;
  • VACUUM 压力:碎片化导致更多 dead tuples。

四、解决方案一:使用时间有序的 UUID(UUIDv7)

4.1 UUIDv7 标准简介

RFC 9562(2024 年正式发布)定义了 UUIDv7:

  • 前 48 位:Unix 时间戳(毫秒级)
  • 中间 12 位:随机或序列计数器(防同一毫秒冲突)
  • 后 62 位:随机熵

格式示例:018e5b5a-fc8f-7000-b5a3-ece0e5d8e8a1

优势

  • 全局唯一
  • 时间趋势递增
  • 无硬件依赖
  • 兼容现有 UUID 生态

4.2 在 PostgreSQL 中生成 UUIDv7

截至 PostgreSQL 16,官方尚未内置 UUIDv7 函数,但可通过以下方式实现:

方法 1:使用第三方扩展(推荐)

安装pg_uuidv7扩展:

# 编译安装(需 PostgreSQL dev 包)gitclone https://github.com/fx/pg_uuidv7cdpg_uuidv7make&&sudomakeinstall

SQL 使用:

CREATEEXTENSION pg_uuidv7;CREATETABLEevents(id UUIDPRIMARYKEYDEFAULTuuid7(),...);
方法 2:PL/pgSQL 自定义函数
CREATEORREPLACEFUNCTIONuuid7()RETURNSUUIDAS$$DECLAREtime_msecBIGINT;time_hexTEXT;rand_hexTEXT;BEGIN-- 获取当前时间(毫秒)time_msec :=FLOOR(EXTRACT(EPOCHFROMclock_timestamp())*1000);-- 转为 12 字节十六进制(48 位)time_hex :=LPAD(TO_HEX(time_msec),12,'0');-- 生成 18 字节随机(72 位)rand_hex :=SUBSTR(REPLACE(gen_random_uuid()::TEXT,'-',''),1,18);-- 拼接并设置版本位(第13字符为'7')RETURN(SUBSTR(time_hex,1,8)||'-'||SUBSTR(time_hex,9,4)||'-7'||SUBSTR(rand_hex,1,3)||'-'||SUBSTR(rand_hex,4,4)||'-'||SUBSTR(rand_hex,8))::UUID;END$$LANGUAGEplpgsql;

⚠️ 注意:此实现简化,生产环境需处理同一毫秒内重复问题(可加序列计数器)。

4.3 UUIDv7 性能优势

  • 插入性能接近BIGSERIAL(因趋势递增)
  • 索引碎片率低
  • 支持按时间范围高效查询:
    SELECT*FROMeventsWHEREid>=uuid7_min('2025-01-01')LIMIT100;

五、解决方案二:替代方案 ULID 与 KSUID

若无法使用 UUIDv7,可考虑以下兼容方案。

5.1 ULID(Universally Unique Lexicographically Sortable Identifier)

  • 长度:128 位(同 UUID)
  • 结构
    • 48 位时间戳(毫秒)
    • 80 位随机
  • 编码:Base32(Crockford),如01H9Z1W0QZJ4XK5Y7V8N9M0P1R
  • 特性
    • 字典序 = 时间序
    • 无连字符,更紧凑(26 字符 vs UUID 36)
    • 可安全用于 URL

PostgreSQL 实现
需通过应用层生成(如 Pythonulid-py、Node.jsulid),或使用 PL/V8 扩展。

5.2 KSUID(K-Sortable Unique ID)

  • 由 Segment.io 提出
  • 结构
    • 32 位时间戳(秒)
    • 128 位随机
  • 编码:Base62,如aWgEPRSg12pFw86Kq2uqTtYZG88
  • 优势:比 ULID 时间粒度粗,但随机性更强

注意:ULID/ KSUID 非标准 UUID,需用TEXT存储,丧失UUID类型的比较效率。


六、解决方案三:优化 UUIDv4 的存储与索引

若必须使用 UUIDv4,可通过以下手段缓解性能问题。

6.1 使用 BRIN 索引(仅限特定场景)

BRIN(Block Range Index)适合物理存储有序的数据。但 UUIDv4 随机分布,不适用

6.2 调整 Fillfactor

降低页填充率,预留空间减少页分裂:

CREATETABLEt(id UUIDPRIMARYKEY,...)WITH(fillfactor=70);

代价:存储空间增加 30%。

6.3 应用层预生成 + 批量插入

  • 应用批量生成 UUID 并排序后插入,使写入局部有序;
  • 适用于离线批处理,不适用于实时高并发。

七、终极方案:混合主键策略

在严格性能要求下,可采用“内部整数主键 + 外部 UUID”模式:

CREATETABLEorders(id BIGSERIALPRIMARYKEY,-- 内部主键,高效 JOINpublic_id UUIDNOTNULLDEFAULTgen_random_uuid(),-- 对外暴露...);-- 唯一索引保障 public_id 全局唯一CREATEUNIQUEINDEXidx_orders_public_idONorders(public_id);-- 查询时用 public_idSELECT*FROMordersWHEREpublic_id='...';

优势

  • 内部关系操作(JOIN、外键)使用高效BIGINT
  • 对外 API 使用安全 UUID;
  • 无写入热点。

代价:多一个字段和索引,存储略增。


八、生产环境配置建议

8.1 表结构设计

-- 推荐:UUIDv7 作为主键CREATEEXTENSIONIFNOTEXISTSpg_uuidv7;CREATETABLEevents(id UUIDPRIMARYKEYDEFAULTuuid7(),created_at TIMESTAMPTZNOTNULLDEFAULTNOW(),payload JSONB);-- 创建索引(通常不需要额外索引,因主键已有序)

8.2 监控索引健康度

定期检查索引碎片:

SELECTschemaname,tablename,indexname,pg_size_pretty(pg_relation_size(quote_ident(schemaname)||'.'||quote_ident(indexname)))asindex_size,idx_tup_read,idx_tup_fetchFROMpg_stat_user_indexesWHEREtablename='events';

idx_tup_fetch / idx_tup_read远小于 1,说明索引效率低。

8.3 VACUUM 策略

对高频写入表,调整 autovacuum:

ALTERTABLEeventsSET(autovacuum_vacuum_scale_factor=0.01);ALTERTABLEeventsSET(autovacuum_vacuum_insert_threshold=1000);

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

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

相关文章

YOLOv13检测效果不理想?手把手教你引入注意力机制快速提精度

文章目录 @[toc] 深度解析与实践:在YOLOv13中集成注意力机制 引言:YOLOv13与深度学习的焦点 第一章:理解注意力机制——为什么以及是什么? 1.1 为什么目标检测需要注意力机制? 1.2 注意力机制的分类与基本原理 第二章:精选注意力模块的原理与实现 2.1 模块一:Squeeze-an…

YOLOv8融合HAttention深度解析:激活像素级注意力的新范式

文章目录 《YOLOv8融合HAttention:激活更多像素的注意力机制科研实践指南》 一、为什么HAttention是像素激活的“密钥”? 二、HAttention的原理深度解析 1. 核心设计:层级化像素激活与融合 2. 与传统注意力机制的对比 三、HAttention的代码实现与YOLOv8集成 1. HAttention核…

基于深度学习的苹果新鲜度检测系统(YOLOv10+YOLO数据集+UI界面+模型)

一、项目介绍 YOLOv10苹果检测系统 是一个基于YOLOv10(You Only Look Once version 10)目标检测算法的智能系统,专门用于检测和分类苹果的状态。该系统能够自动识别苹果并将其分类为两类:apple(正常苹果) 和…

2026年国内做得好的离婚律师机构找哪家,北京继承律师哪个好/离婚纠纷律师/北京丰台离婚律师,离婚律师机构推荐榜单 - 品牌推荐师

随着社会观念的演进与家庭结构的多元化,离婚法律服务市场正经历着深刻变革。当事人不再仅仅满足于程序性的诉讼代理,而是对法律服务的专业性、情感支持、隐私保护及财产分割方案的精细化提出了更高要求。尤其在资产构…

多模态大模型架构深度解析:模块化vs原生架构工作原理全解析

文章详细介绍了多模态大模型的两种架构:模块化架构(需连接器转译图像)和原生架构(共享底层逻辑)。解释了图像Token化的原理,对比了两种架构的工作流程、训练阶段和应用场景,指出多模态大模型的终极目标是消除模态间的"翻译感"&…

编写一个Buildroot 内核驱动

编写一个Buildroot 内核驱动PS:内核驱动只能在/kernel/drivers/目录下Makefile文件的编写主要注意Makefile文件的编写(路径,包含) 在该路径下先新建一个用户内核驱动文件夹,用于存放用户编写的驱动 user_rk3566_-k…

基于深度学习的冰箱内食物检测系统(YOLOv10+YOLO数据集+UI界面+模型)

一、项目介绍 YOLOv10冰箱内部成分检测系统 是一个基于YOLOv10(You Only Look Once version 10)目标检测算法的智能系统,专门用于检测和识别冰箱内部的多种食物成分。该系统能够自动识别冰箱中的30种常见食物,包括水果、蔬菜、肉…

AI产品经理思维框架:从技术小白到商业落地的实战指南

文章提出了AI产品经理必备的六大思维能力框架:技术理解力、场景洞察力、数据思维、体验设计力、商业思维和伦理风险意识。强调AI产品经理不仅需要了解AI技术,更需要找到技术与商业的平衡点,将AI技术转化为解决用户问题、创造商业价值的产品。…

大模型技术全景图:从理论到应用,一篇全掌握!建议收藏

本文系统梳理了大模型技术框架,从神经网络基础到实际应用。大模型通过预训练实现智能,但存在知识更新慢和领域适应性差的问题,可通过RAG技术、微调和提示词工程解决。智能体Agent将大模型与外部工具结合实现复杂任务处理。学习大模型需系统性…

基于深度学习的苹果腐烂检测系统(YOLOv10+YOLO数据集+UI界面+模型)

一、项目介绍 基于深度学习的苹果腐烂检测系统 是一个专注于检测苹果腐烂状态的智能系统,采用先进的深度学习技术(如YOLOv10或其他目标检测算法)实现高精度检测。该系统能够自动识别并定位腐烂的苹果(damaged_apple)&a…

课程论文别再凑字数!宏智树 AI 教你高效写出高分范文

作为深耕论文写作科普的教育博主,后台每天都能收到大学生的吐槽:“课程论文到底怎么写?凑够字数就被导师批没逻辑”“找文献花三天,写论文两小时,结果分数惨不忍睹”“格式改了八遍,还是不符合学术规范”。…

哈希表解决两数之和

核心代码如下: class Solution { public: vector twoSum(vector& nums, int target) { unordered_map<int, int> hashTable; for (int i = 0; i < nums.size(); ++i) { //先查询哈希表中是否存在 目标差…

传统产品经理转型AI PM的完整指南,非常详细收藏我这一篇就够了

传统产品经理转型AI PM指南&#xff1a;强调理解AI能力而非编写代码。文章从认知重塑、技能树重构到实战路径三方面展开&#xff0c;通过小红书文案生成器案例&#xff0c;展示从基础Prompt到Few-Shot和RAG思维的进阶过程&#xff0c;提供低代码构建Demo方法&#xff0c;帮助快…

还在手动拼问卷?宏智树 AI:一键搞定实证研究的 “黄金调研工具”

作为深耕论文写作科普的教育博主&#xff0c;后台每天都被粉丝的问卷难题刷屏&#xff1a;“翻遍文献凑量表&#xff0c;设计的问卷却被导师说‘逻辑不通’”“回收的问卷数据一半无效&#xff0c;根本没法用于分析”“好不容易做完调研&#xff0c;却不知道怎么把数据转化为论…

基于深度学习的树上苹果检测系统(YOLOv10+YOLO数据集+UI界面+模型)

一、项目介绍 YOLOv10树上苹果检测系统 是一个基于YOLOv10&#xff08;You Only Look Once version 10&#xff09;目标检测算法的智能系统&#xff0c;专门用于检测树上的苹果。该系统能够自动识别并定位树上的苹果&#xff08;Apples&#xff09;&#xff0c;适用于果园管理、…

基于深度学习的奶牛行为检测系统(YOLOv10+YOLO数据集+UI界面+模型)

一、项目介绍 YOLOv10奶牛行为检测系统 是一个基于YOLOv10&#xff08;You Only Look Once version 10&#xff09;目标检测算法的智能系统&#xff0c;专门用于检测奶牛的行为状态。该系统能够自动识别并分类奶牛的三种主要行为&#xff1a;站立、行走 和 卧倒。通过该系统&a…

数据不会说话?宏智树 AI:论文数据分析的 “智能翻译官”

手握几百份问卷数据、一堆实验记录&#xff0c;却不知道怎么挖掘价值&#xff1f;对着 SPSS、R 语言的教程一脸懵&#xff0c;好不容易算出结果&#xff0c;却写不出一句能支撑论文论点的分析&#xff1f;作为深耕论文写作科普的教育博主&#xff0c;后台收到最多的求助&#x…

DeepSeek V4 vs Kimi K3:国产AI大模型技术对决,谁将引领春节前的新爆发?

文章深度对比了中国两大AI大模型DeepSeek和Kimi即将推出的V4和K3版本。DeepSeek通过Engram技术优化模型架构&#xff0c;将75%资源用于推理&#xff0c;25%用于记忆&#xff0c;显著提升效率&#xff1b;Kimi则采用Kimi Linear架构挑战Transformer计算瓶颈。DeepSeek在编程和性…

ROS1 noetic 中将 Unitree G1 基于 Gazebo/RViz 关节联动【基于 ros_control】

博客地址:https://www.cnblogs.com/zylyehuo/Unitree G1 模型文件下载地址(挑选自己需要的部分,本教程基于 g1_29dof.urdf (以及 .xml 和 meshes 文件夹))有核心的 URDF 文件和 Meshes (STL 网格文件)为 Gazebo 中模…

AI 写论文哪个软件最好?实测揭秘!宏智树 AI 凭 “真研究” 实力领跑

作为深耕论文写作科普的教育测评博主&#xff0c;后台每天都被 “AI 写论文哪个软件最好” 的提问刷屏。市面上的论文工具五花八门&#xff0c;有的是 “文字拼接机”&#xff0c;生成内容空洞无物&#xff1b;有的是 “文献造假犯”&#xff0c;引用的文献查无实证&#xff1b…