PostgreSQL 标识符 63 字节上限:截断机制、_fkey 后缀保护与 NAMEDATALEN 源码解析
文档教程知识库【免费下载链接】til:memo: Today I Learned项目地址https://gitcode.com/gh_mirrors/ti/til点击查看免费下载PostgreSQL 对表名、列名、约束名等所有标识符施加了 63 字节的硬性长度上限超长标识符并不会报错而是被自动截断这一行为在日常建表、加约束时极易被忽视并引发隐患。本文将结合本仓库的 PostgreSQL 系列笔记完整解析 63 字节限制的来龙去脉、截断时的 NOTICE 提示、自动生成标识符的“保后缀”策略以及该上限的源码出处NAMEDATALEN - 1。63 字节PostgreSQL 标识符的硬性上限在 PostgreSQL 中所有标识符——表名table names、列名column names、约束名constraint names等——的长度都被限制为最多 63 字节。这个限制并不是“超过就报错”而是更隐蔽可以写入超过 63 字符的标识符但 PostgreSQL 会将其截断到允许的 63 字节长度并给出一条 NOTICE 提示。这与本仓库中另一则笔记 表名默认被当作小写处理 所揭示的行为类似PostgreSQL 会在处理标识符时对名称进行规范化折叠大小写、截断超长部分因此开发者实际写下的名字与数据库最终存储的名字可能并不一致。理解这套标识符处理规则是避免“名字对不上”“约束找不到”等困惑的前提。超长标识符不会报错而是被截断直接看效果最直观。在 psql 中执行下面这条alter table尝试添加一个明显超过 63 字节的 CHECK 约束名 alter table articles add constraint this_constraint_is_going_to_be_longer_than_sixty_three_characters_id_idx check (char_length(title) 0); NOTICE: identifier this_constraint_is_going_to_be_longer_than_sixty_three_characters_id_idx will be truncated to this_constraint_is_going_to_be_longer_than_sixty_three_characte ALTER TABLE两个关键信息值得注意操作本身成功命令返回ALTER TABLE约束照常创建全程没有报错只有一条NOTICE。NOTICE 明确告知截断结果PostgreSQL 会明确指出超长标识符将被截断为哪个名字。上例中原本 78 字节的约束名被截断为 63 字节的this_constraint_is_going_to_be_longer_than_sixty_three_characte——注意末尾少了s_id_idx几个字符。这种“静默截断 NOTICE 提醒”的设计意味着只要没盯着服务端日志或 psql 输出你可能永远不会发现约束名、索引名已经被悄悄改写了。截断后的名字才是真实存在的名字截断一旦发生之后所有针对该对象的操作都必须使用截断后的名字。例如删除约束时必须写alter table articles drop constraint this_constraint_is_going_to_be_longer_than_sixty_three_characte;如果按自己书写的全名去drop constraint会得到 “constraint does not exist” 之类的错误——因为数据库里存的是截断后的版本。想确认表上约束的真实存储名字可以查询系统目录pg_constraint并用pg_get_constraintdef(oid)重建约束定义。仓库笔记 Show Reconstructed Constraints For A Table 给出了完整的示例 select conname, pg_get_constraintdef(oid) from pg_constraint where conrelid reading_statuses::regclass; conname | pg_get_constraintdef ----------------------------------------------------------------------------------------------------- reading_statuses_pkey | PRIMARY KEY (id) fk_rails_17ee7cb2c4 | FOREIGN KEY (user_id) REFERENCES users(id) fk_rails_0d3729339f | FOREIGN KEY (book_id) REFERENCES books(id) reading_statuses_valid_status_check | CHECK (...) (4 rows)通过conname看到的名字就是经过 PostgreSQL 规范化含截断后的最终名字也是你在所有后续 SQL 中真正需要引用的名字。自动生成的标识符从中间截断保住_fkey等后缀超长标识符不仅会发生在开发者手写的名字上PostgreSQL 自动生成的标识符同样受 63 字节限制。最常见的场景是外键约束当你在alter table中省略约束名时PostgreSQL 会按约定自动生成xxx_fkey这类名字。仓库笔记 Add Foreign Key Constraint Without A Full Lock 展示了这种命名约定alter table books add constraint fk_books_authors foreign key (author_id) references authors(id) not valid;这里手写了fk_books_authors但如果省略constraint子句PostgreSQL 生成的默认名通常是表名_列名_fkey而在 Rails 等框架下则常见fk_rails_hash这样的短名如上面的fk_rails_17ee7cb2c4。问题在于当表名、列名本身较长时自动拼出的_fkey全名可能轻松超过 63 字节。此时 PostgreSQL 的截断策略与手写标识符不同——它会在中间某个位置截断而不是从尾部硬切目的是保住约定俗成的后缀例如以_fkey结尾。这样生成的名字依然符合“一眼看出是外键约束”的命名惯例。这也解释了为什么在真实生产库中你会看到诸如books_authors_very_long_column_name_fk截断版这样的名字——命名习惯被保留了但可读性已经大打折扣。63 字节的由来NAMEDATALEN - 163 这个数字并非拍脑袋定下的它直接来自 PostgreSQL 源码中的一个编译期常量NAMEDATALEN - 1默认情况下NAMEDATALEN的值为64因此标识符上限为 63。这个值是编译期硬编码的而不是运行时配置项无法通过postgresql.conf之类的配置文件调整。如果确实需要可以在 PostgreSQL 源码中修改NAMEDATALEN位于源码的pg_config_manual.h中后重新编译数据库。之所以预留 1 字节的余量是为了容纳字符串的结尾空字符\0即内部缓冲区大小为NAMEDATALEN64 字节其中最多 63 字节用于标识符本身。正如原文所说“Yay, open-source database implementations”——开源数据库的好处在于这种底层限制的出处是透明的需要时甚至可以亲自改掉它。不过在实际生产环境中修改后需要重新编译并可能导致与生态工具迁移工具、ORM 生成的名称的不兼容绝大多数团队不应走到这一步。注意上限单位是字节不是字符限制单位是63 字节而非“63 个字符”。对于纯 ASCII 标识符1 字节 1 字符63 字符即上限但一旦使用多字节字符如中文、日文、emoji 命名的标识符每个字符可能占用 24 字节实际可用的字符数会显著少于 63。截断也是按字节进行的因此含多字节字符的超长标识符被截断后其边界不一定落在完整的字符边界上。实用建议无论是 ASCII 还是多字节命名都留足余量远离 63 字节这条红线。工程实践如何避开 63 字节陷阱结合本仓库 PostgreSQL 相关笔记的实践可以从以下几个层面规避截断带来的麻烦命名从源头保持精简约束名、索引名、外键名都采用“表名 关键列 类型后缀”的短命名例如fk_books_authors、uq_users_email把长度控制在 63 字节以内让截断根本不发生。沿用 snake_case 小写命名仓库笔记 Table Names Are Treated As Lower-Case By Default 强调PostgreSQL 默认把未加引号的标识符折叠为小写。保持全小写 snake_case 既能规避大小写混淆也让名字更短、更符合约定。了解框架的自动命名Rails 等框架默认生成fk_rails_16 位 hash这类固定长度短名见上文pg_constraint查询结果天然不会超长手写长表名与长列名组合时才最容易踩中自动拼接超长的坑。改名前留意连带命名仓库笔记 Renaming A Table 提醒alter table ... rename to ...会更新外键引用但与旧表同名的序列、约束等名字不再遵循原约定——这些名字若因重命名变得更长同样可能触及 63 字节截断需一并检查。用系统目录自查建完约束后通过pg_constraint.conname与pg_get_constraintdef()核对实际存储的约束名方法见 Show Reconstructed Constraints For A Table确保迁移脚本后续引用的名字与库中真实名字一致。小结PostgreSQL 的标识符上限是 63 字节来源于编译期常量NAMEDATALEN - 1默认NAMEDATALEN 64。超长标识符不会被拒绝而是被截断并给出 NOTICE自动生成的标识符如外键的_fkey名则会从中间截断以保住后缀约定。理解这一机制能帮你解释许多“名字对不上”的怪象并在设计表结构、编写迁移脚本时提前规避。更多 PostgreSQL 命名与约束相关的实践可继续翻阅本仓库的 PostgreSQL 笔记目录。赞分享文档教程知识库【免费下载链接】til:memo: Today I Learned项目地址https://gitcode.com/gh_mirrors/ti/til点击查看免费下载相关推荐PostgreSQL技术解析标识符最大长度限制为63字节PostgreSQL技术解析标识符最大长度限制为63字节 标识符长度限制概述 在PostgreSQL数据库中各种标识符包括表名、列名、约束名等都有一个明文档教程知识库curl --max-filesize 使用详解文件大小上限限制机制、字节后缀语法与退出码 63curl max filesize 使用详解文件大小上限限制机制、字节后缀语法与退出码 63 max filesize 是 curl 命令行工具中用于限制下载CLI网络通信零运行时原子 CSS 框架vanilla-extract Sprinkles 完整实战指南零运行时原子 CSS 框架vanilla extract Sprinkles 完整实战指南 vanilla extract 生态中 Sprinkles ht前端开发工具上一篇用 Firehose 构建实时 Web 数据流监控Marketing Skills 仓库中的 SSE 竞争情报集成指南下一篇open-design 仓库中的 IBM Carbon 设计系统还原指南从 --cds-* Token 体系到 Agent 提示词工程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

learnxinyminutes-docs 意大利语版 JavaScript 快速入门指南:从基础语法到原型链的完整速成教程

learnxinyminutes-docs 意大利语版 JavaScript 快速入门指南:从基础语法到原型链的完整速成教程

文档教程 【免费下载链接】learnxinyminutes-docs Code documentation written as code! How novel and totally my idea! 项目地址: https://gitcode.com/gh_mirrors/le/learnxinyminutes-docs 点击查看 免费下载 本仓库(learnxinyminutes-docs&#x…

2026/10/10 17:50:39 阅读更多 →
SQLDelight 自定义投影(Custom Projections)实战:Typesafe Mapper 与 SQL 侧投影的正确用法

SQLDelight 自定义投影(Custom Projections)实战:Typesafe Mapper 与 SQL 侧投影的正确用法

后端ORM 【免费下载链接】sqldelight SQLDelight - Generates typesafe Kotlin APIs from SQL 项目地址: https://gitcode.com/gh_mirrors/sq/sqldelight 点击查看 免费下载 本指南围绕 SQLDelight 官方文档 docs/common/custom_projections.md 展开,讲…

2026/10/10 13:24:06 阅读更多 →
看懂人群,然后远离人群:普通人逆袭的路径

看懂人群,然后远离人群:普通人逆袭的路径

看懂人群,然后远离人群:普通人逆袭的唯一路径 你有没有发现一个诡异的现象—— 从小到大,所有人都在告诉你"合群"的重要性。 上学时,老师说:别标新立异,跟大家保持一致。 找工作时,父…

2026/10/9 13:04:34 阅读更多 →

最新新闻

Python爬虫实战:手机APP数据抓取与解析全流程

Python爬虫实战:手机APP数据抓取与解析全流程

简介:这份PDF资料面向具备Python基础、对网络请求与爬虫开发感兴趣的技术爱好者与研发工程师,围绕手机APP数据传输的抓取与解析展开,重点讲解如何借助Fiddler抓包定位登录与话题接口,再通过urllib2构造HTTP请求、携带Header与表单…

2026/10/14 3:04:31 阅读更多 →
C++ 对接 S3 对象存储实战:SDK 选型、分片上传与避坑指南

C++ 对接 S3 对象存储实战:SDK 选型、分片上传与避坑指南

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

2026/10/14 3:04:31 阅读更多 →
SQLite安装全指南:嵌入式数据库跨平台配置与常见坑

SQLite安装全指南:嵌入式数据库跨平台配置与常见坑

第一次折腾SQLite的时候,我找了一圈“Setup.exe”,愣是没找到。下载页面全是压缩包,网上一堆教程各写各的,有人说不用装,有人说得编译源码,看得人发懵。后来我才搞明白:SQLite的“安装”逻辑跟M…

2026/10/14 3:04:31 阅读更多 →
C++手写数据结构实战:动态数组、哈希表、AVL树与图算法

C++手写数据结构实战:动态数组、哈希表、AVL树与图算法

简介:《Implementing Useful Algorithms in C》由Dmytro Kedyk撰写,面向具备一定C基础、希望深入掌握算法设计与工程实现的开发者与计算机专业学生。全书从算法正确性证明、渐进记法与机器模型等基本原则切入,系统讲解数据类型选择、内存管理…

2026/10/14 3:04:31 阅读更多 →
本地27B模型配Function Calling:工具不触发的原因与实战

本地27B模型配Function Calling:工具不触发的原因与实战

给本地跑的27B模型配了三个专业工具之后,我做的第一件事就是拿它试聊天。你猜怎么着——工具列表明明挂在接口定义里,模型却像一个看见工具箱、却只肯用手拧瓶盖的人,简单问题全凭语言能力直接答,一个工具都不碰。我一度觉得这套配…

2026/10/14 3:04:31 阅读更多 →
容器内nvidia-smi报Unknown Error的排查与根治

容器内nvidia-smi报Unknown Error的排查与根治

凌晨两点半,工作群里弹出一条消息:某个长期跑的容器,前一秒还好好的,后一秒容器里的nvidia-smi直接报Failed to initialize NVML: Unknown Error。宿主机上执行nvidia-smi一切正常,新建一个临时容器也能正常看到卡&…

2026/10/14 3:03:31 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 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/13 22:01:27 阅读更多 →
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/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练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/12 18:11:17 阅读更多 →