PostGraphile v4 数据库函数指南:用 PostgreSQL Functions 扩展 GraphQL Schema 的三种方式
后端API网关【免费下载链接】crystal Graphiles Crystal Monorepo; home to Grafast, PostGraphile, pg-introspection, pg-sql2 and much more!项目地址https://gitcode.com/gh_mirrors/cry/crystal点击查看免费下载本文是 PostGraphile v4 的数据库函数Database Functions实战指南核心讲解如何利用 PostgreSQL 函数为 PostGraphile schema 添加能力以计算列Computed Columns、自定义查询Custom Queries和自定义变更Custom Mutations三种形态暴露到 GraphQL。读者将掌握函数语言选型、命名参数规则、命名冲突消解、VOLATILE/STABLE/IMMUTABLE 易变性语义对暴露形态的影响以及 SETOF 函数与 Relay Connection 分页的结合方式并看到这些机制在当前仓库测试库中的真实落地形态。三种暴露方式PostGraphile 中数据库函数的核心用法在 PostGraphile 中把业务逻辑下沉到 PostgreSQL 数据库是给 schema 增加能力的最便捷路径之一。根据函数签名与易变性声明PostGraphile 会自动把函数映射为三种 GraphQL 形态暴露形态说明对应文档计算列Computed Columns为某个表类型table type添加一个计算字段computed-columns自定义查询Custom Queries在根级Query上添加字段可返回标量、列表、自定义类型、表行甚至表连接connectioncustom-queries自定义变更Custom Mutations在根级Mutation上添加字段可修改数据库并返回void、标量、列表、自定义类型、表行或表行列表但不能返回连接因为无法对变更进行分页custom-mutations一个函数最终被暴露为哪种形态取决于它的易变性声明VOLATILE/STABLE/IMMUTABLE与返回类型详见后文。理解数据库函数为什么业务逻辑要下沉到数据库要构建最强大的 PostGraphile 服务理解 PostgreSQL 函数至关重要。函数允许你用 SQL 或多种其他脚本语言在数据库中定义业务逻辑。把业务逻辑放在数据库层往往比放在应用层性能更好——因为 PostgreSQL 针对数据密集型场景做了精细调优函数执行与数据访问发生在同一进程内避免了应用与数据库之间的往返开销。想要获取可运行的函数示例可以查看当前仓库 v4 测试库中的函数定义集合 kitchen-sink-schema.sql其中包含数十个用于验证查询、变更行为的真实函数覆盖了本文将要讲到的命名参数、默认值、STRICT、VOLATILE/STABLE/IMMUTABLE、SETOF等全部要点例如a.add_1_query(int, int)、a.add_4_mutation(int, b int default 2)、c.table_set_query()等。推荐阅读PostgreSQLCREATE FUNCTION文档——实际创建函数的语法依据。PostgreSQLCREATE TRIGGER文档。StackOverflow 上关于 PostgreSQL 计算列 的回答。过程语言选型SQL、PL/pgSQL 与脚本语言PostgreSQL 函数要求使用 SQL 或某种过程语言procedural language编写。最常见的 PostgreSQL 过程语言是 PL/pgSQL。SQL 可能是最容易上手的选择因为开发者大多已熟悉它PL/pgSQL 是 PostgreSQL 自带的过程语言上手不难且 StackOverflow 等社区资源丰富。如果打算写触发器trigger就必须学习 PL/pgSQL或其它过程语言因为 SQL 不能用于触发器。不过不必焦虑——没有深入的 PL/pgSQL 知识也能构建出色的应用。一个用LANGUAGE sql编写的简单函数CREATE FUNCTION add(a int, b int) RETURNS int AS $$ select a b; $$ LANGUAGE sql IMMUTABLE STRICT;同一个函数用LANGUAGE plpgsql编写CREATE FUNCTION add(a int, b int) RETURNS int AS $$ BEGIN RETURN a b; END; $$ LANGUAGE plpgsql IMMUTABLE STRICT;如果你不想用 PL/pgSQL 或 SQL许多流行的脚本语言也可以在 PostgreSQL内部编写函数JavaScriptplv8Rubyplruby例如用 JavaScript 定义的函数与 PL/pgSQL 版本外观几乎一致-- 这看起来与 PL/pgSQL 示例几乎相同…… CREATE FUNCTION add(a int, b int) RETURNS int AS $$ return a b; $$ LANGUAGE plv8 IMMUTABLE STRICT; -- 这是来自 plv8 仓库的更好示例…… CREATE FUNCTION plv8_test(keys text[], vals text[]) RETURNS text AS $$ var object {} for (var i 0; i keys.length; i) { object[keys[i]] vals[i] } return JSON.stringify(object) $$ LANGUAGE plv8 IMMUTABLE STRICT;命名参数GraphQL 只认名字匿名参数会被自动编号PostgreSQL 允许在函数中混用命名参数与位置参数匿名参数。但 GraphQL只允许命名参数。因此如果某个参数没有名字PostGraphile 会自动为它取名arg1、arg2、arg3……依此类推。一个使用匿名参数的函数示例CREATE FUNCTION add(int, int) RETURNS int AS $$ SELECT $1 $2; $$ LANGUAGE sql IMMUTABLE STRICT;而命名参数版本如下CREATE FUNCTION add(a int, b int) RETURNS int AS $$ select a b; $$ LANGUAGE sql IMMUTABLE STRICT;当前仓库的测试库对这两种形态都有真实覆盖见 kitchen-sink-schema.sqlcreate function a.add_1_query(int, int) returns int as $$ select $1 $2 $$ language sql immutable strict; create function a.add_2_query(a int, b int default 2) returns int as $$ select $1 $2 $$ language sql stable strict; create function a.add_3_query(a int, int) returns int as $$ select $1 $2 $$ language sql immutable; create function a.add_4_query(int, b int default 2) returns int as $$ select $1 $2 $$ language sql stable;对应的 GraphQL 调用在 procedure-mutation.test.graphql 中可见add1Mutation(input: { arg0: 1, arg1: 2 }) { clientMutationId integer } add2Mutation(input: { clientMutationId: hello, a: 2, b: 2 }) { clientMutationId integer } add3Mutation(input: { clientMutationId: world, arg1: 5 }) { clientMutationId integer } add4Mutation(input: { arg0: 1, b: 3 }) { integer }可以看到匿名参数被自动命名为arg0、arg1命名参数如a、b保持原名带default默认值的参数在 GraphQL 侧成为可选输入项如add3Mutation只传了arg1。注意自动编号从arg0开始而非文档早先提到的arg1风格——这是测试库实测呈现的行为以实际生成的 schema 为准。解决命名冲突参数名与列名的碰撞有时你为函数参数选的名字会与函数内部可访问的列名或其它标识符冲突。要避免这类冲突可以使用数字参数如$1表示第一个参数、$2表示第二个依此类推并用表名消除歧义create function get_user(id int) returns users as $$ select * from users where users.id $1; $$ language sql stable;如果更倾向于使用参数名而非数字$n参数可以用函数名本身来消歧create function get_user(id int) returns users as $$ select * from users where users.id get_user.id; $$ language sql stable;这种方法总体可行但某些场景仍不够用。例如在plpgsql函数中写 upsertINSERT...ON CONFLICT语句时create function upsert_value(id int, value text) returns void as $$ begin insert into my_table (id, value) values(id, value) on conflict (id) -- 这里会报错 do update set value excluded.value; end; $$ language plpgsql volatile;这里的on conflict (id)会引发问题PL/pgSQL 无法判断id指的是表列还是函数参数而在括号内加表名又是语法错误。解决办法之一是改用sql语言——SQL 会优先把标识符当作列来解析。另一个办法是显式告知函数用列来解决冲突create function upsert_value(id int, value text) returns void as $$ #variable_conflict use_column begin insert into my_table (id, value) values(id, value) on conflict (id) do update set value excluded.value; end; $$ language plpgsql volatile;要更深入理解这些冲突与解决方案请参阅 PostgreSQL 文档中关于变量替换的部分。VOLATILE易变函数PostGraphile 的自定义变更来源默认情况下函数是 volatile易变的。例如CREATE FUNCTION my_function(a int, b int) RETURNS int AS $$ … $$ LANGUAGE sql;等价于CREATE FUNCTION my_function(a int, b int) RETURNS int AS $$ … $$ LANGUAGE sql VOLATILE;PostgreSQL 文档中的定义VOLATILE表示函数值即使在单次表扫描中也可能改变因此无法做任何优化……但任何有副作用的函数都必须归类为 volatile即使其结果相当可预测也要防止调用被优化掉例如setval()。简单说VOLATILE基本意味着你在修改数据或存储状态。熟悉 HTTP 的开发者可以把VOLATILE函数类比为 不安全 的 HTTP 方法如POST、PUT、PATCH和DELETE。某些VOLATILE函数会被 PostGraphile 暴露为自定义变更custom mutations。仓库测试中的典型VOLATILE变更函数见 kitchen-sink-schema.sqlcreate function a.add_1_mutation(int, int) returns int as $$ select $1 $2 $$ language sql volatile strict; create function a.add_2_mutation(a int, b int default 2) returns int as $$ select $1 $2 $$ language sql strict; -- 默认即 volatile create function a.add_4_mutation_error(int, b int default 2) returns int as $$ begin raise exception Deliberate error; end $$ language plpgsql;注意add_4_mutation_error这类函数会故意抛出异常用于验证 PostGraphile 的错误处理路径同时命名参数a、b与匿名参数自动命名在同一个 mutation 中混用也是被支持的。STABLE / IMMUTABLE查询函数PostGraphile 的自定义查询与计算列来源如果你的函数不修改任何数据或状态应当声明为STABLE。如果函数只依赖其参数、不从表等其它来源取数则可以声明为IMMUTABLE——它是STABLE更严格的形式。将函数标记为STABLE或IMMUTABLE后PostgreSQL 知道可以应用多种优化包括记忆化memoization从而避免在同一个语句中对相同输入多次调用该函数。定义 STABLE/IMMUTABLE 函数的示例CREATE FUNCTION my_function(a int, b int) RETURNS int AS $$ … $$ LANGUAGE sql STABLE; -- 或者…… CREATE FUNCTION my_function(a int, b int) RETURNS int AS $$ … $$ LANGUAGE sql IMMUTABLE; -- 或者想返回表中的一行…… CREATE FUNCTION my_function(a int, b int) RETURNS my_table AS $$ … $$ LANGUAGE sql STABLE;PostgreSQL 文档中的定义IMMUTABLE表示函数不能修改数据库并且在给定相同参数值的情况下始终返回相同结果也就是说它不做数据库查找也不使用参数列表中未直接呈现的信息。若给出此选项任何使用全常量参数的函数调用都可以立即替换为函数值。以及……STABLE表示函数不能修改数据库并且在单次表扫描内对相同的参数值会一致地返回相同结果但其结果可能在不同 SQL 语句之间变化。这适合结果依赖数据库查找、参数变量如当前时区等的函数。不适合想要查询当前命令所修改行的 AFTER 触发器。继续用 HTTP 类比IMMUTABLE和STABLE相当于 安全 的 HTTP 方法如GET和HEAD。某些STABLE/IMMUTABLE函数会被 PostGraphile 暴露为自定义查询custom queries或计算列computed columns。仓库测试中的典型STABLE/IMMUTABLE查询函数见 kitchen-sink-schema.sqlcreate function a.add_1_query(int, int) returns int as $$ select $1 $2 $$ language sql immutable strict; create function a.add_2_query(a int, b int default 2) returns int as $$ select $1 $2 $$ language sql stable strict; create function c.table_query(id int) returns a.post as $$ select * from a.post where id $1 $$ language sql stable; create function c.person_exists(person c.person, email b.email) returns boolean as $$ … $$ language sql stable; create function c.edge_case_computed(edge_case c.edge_case) returns text as $$ select hello world::text $$ language sql stable;其中person_exists以表类型为参数并返回布尔值是计算列的典型形态edge_case_computed同样是标准的计算列函数。关于 STRICTNULL 处理在上面的示例中多次出现的STRICT也是影响函数暴露行为的关键修饰符STRICT等价于RETURNS NULL ON NULL INPUT表示当任一参数为NULL时函数不执行且直接返回NULL。PostGraphile 在生成 GraphQL 字段时会依据STRICT与否决定输入参数的nullable语义。仓库中对此有专门的对照测试见 kitchen-sink-schema.sqlcreate function b.mult_1(int, int) returns int as $$ select $1 * $2 $$ language sql; -- 默认 called on null input create function b.mult_2(int, int) returns int as $$ select $1 * $2 $$ language sql called on null input; create function b.mult_3(int, int) returns int as $$ select $1 * $2 $$ language sql returns null on null input; -- 即 strict create function b.mult_4(int, int) returns int as $$ select $1 * $2 $$ language sql strict;SETOF 函数与 Connections返回集合即可分页除了标量、复合类型及其数组之外PostgreSQL 函数还可以返回集合sets。集合模拟表因此 PostGraphile 很自然地把它们用连接connections暴露到 GraphQL。SETOF 函数是向用户暴露一次性给太多、需要分页处理的数据的有力方式。要创建返回连接的函数可以使用如下 SQL-- 假设我们已经有一张名为 person 的表…… CREATE FUNCTION my_function(a int, b int) RETURNS SETOF person AS $$ … $$ LANGUAGE sql STABLE;该函数会被识别为自定义查询custom query可以这样查询{ myFunction(a: 1, b: 2, first: 2) { pageInfo { hasNextPage hasPrevPage } edges { cursor node { id } } } }关于构造高级查询的更多信息可参见custom-queries 文档。仓库测试库中对 SETOF 连接的覆盖非常全面见 kitchen-sink-schema.sqlcreate function c.table_set_query() returns setof c.person as $$ select * from c.person order by id asc $$ language sql stable; create function c.table_set_query_plpgsql() returns setof c.person as $$ begin return query select * from c.person order by id asc; end $$ language plpgsql stable; create function c.table_set_query_volatile() returns setof c.person as $$ select * from c.person order by id asc $$ language sql volatile; create function b.type_function_connection() returns setof b.types as $$ select * from b.types order by id asc $$ language sql stable; create function c.person_type_function_connection(p c.person) returns setof b.types as $$ select * from b.types order by id asc $$ language sql stable;注意其中的规律同名同返回类型的函数仅因stable与volatile或省略的不同就被分别映射为自定义查询与自定义变更——这正是上文易变性决定暴露形态规则的直接体现。SETOF函数在变更侧同样被支持例如c.table_set_mutation() returns setof c.person它作为变更返回的是表行列表而非连接因为无法对变更结果分页。小结从函数签名预判 GraphQL 暴露形态综合全文可以形成一条判断规则编写一个数据库函数后PostGraphile 会结合易变性声明与返回类型决定其 GraphQL 暴露形态VOLATILE或省略易变性声明默认即 volatile→ 暴露为自定义变更Mutation 根字段STABLE/IMMUTABLE→ 暴露为自定义查询Query 根字段若首个参数为表类型则可能成为该表类型的计算列返回SETOF table时 → 查询侧暴露为可分页的ConnectionRelay 风格edges/pageInfo变更侧暴露为表行列表匿名参数会被自动命名为arg0、arg1……命名参数保持原名带default的参数在 GraphQL 侧为可选项STRICT声明影响参数的 null 语义与字段可空性。掌握这些规则后你便可以在数据库层自由组合 SQL、PL/pgSQL 甚至 plv8 等语言来定义业务逻辑并准确预判 PostGraphile 会为你的函数生成怎样的 GraphQL API——所有结论均可在当前仓库的 kitchen-sink-schema.sql 与 procedure-mutation.test.graphql 测试中逐一验证。赞分享后端API网关【免费下载链接】crystal Graphiles Crystal Monorepo; home to Grafast, PostGraphile, pg-introspection, pg-sql2 and much more!项目地址https://gitcode.com/gh_mirrors/cry/crystal点击查看免费下载相关推荐HsMod完整指南55个功能轻松解锁炉石传说高级体验HsMod完整指南55个功能轻松解锁炉石传说高级体验 你是否厌倦了炉石传说中重复的等待时间想要更流畅的游戏体验和个性化定制HsMod正是为你准备的解决方案后端API网关PostGraphile v4 自定义查询Custom Queries实战指南用 PostgreSQL 函数自动生成 GraphQL 根字段PostGraphile v4 自定义查询Custom Queries实战指南用 PostgreSQL 函数自动生成 GraphQL 根字段 导读 本文围后端API网关PostGraphile 数据库自省Introspection机制解析从 PostgreSQL 系统目录到 GraphQL SchemaPostGraphile 数据库自省Introspection机制解析从 PostgreSQL 系统目录到 GraphQL Schema PostGrap后端API网关上一篇mmsegmentation 语义分割可视化实战指南从单图演示到训练监控的完整链路下一篇如何快速掌握NanoKVMRISC-V多媒体子系统的视频采集与处理核心技术创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Claude Code知识工作插件实战:斜杠命令与技能配置指南

Claude Code知识工作插件实战:斜杠命令与技能配置指南

1. 从"knowledge-work-plugins"这个命名说起:它到底指什么第一次看到knowledge-work-plugins这个仓库名,我的直觉是:这不是一个普通的工具库,而是一套"知识工作者的能力扩展包"。拆开来看,knowled…

2026/9/25 22:09:05 阅读更多 →
Python核心容器详解:序列、字典、集合的原理、操作与实战

Python核心容器详解:序列、字典、集合的原理、操作与实战

Python 学了一段时间,写过变量、分支、循环、函数之后,你八成会撞上同一个问题:数据多了往哪放?一堆人名、几组成绩、多段文本,总不能一个变量一个变量地存吧。这时候就得认识 Python 里三张王牌——序列、字典、集合。…

2026/9/25 22:58:43 阅读更多 →
认知科学视角下的高效自我管理系统设计

认知科学视角下的高效自我管理系统设计

1. 为什么市面上的自我管理方法总是失效?市面上充斥着各种"高效能人士的7个习惯"、"21天养成好习惯"之类的技巧清单,这些内容往往存在三个致命缺陷:第一,它们假设所有人都处于相同的心理状态和环境条件下。实…

2026/9/25 12:55:41 阅读更多 →

最新新闻

Windows下MinGW-w64完整包安装教程:从选型、配置到避坑全指南

Windows下MinGW-w64完整包安装教程:从选型、配置到避坑全指南

简介:面向Windows平台C/C开发者的MinGW mingw64完整配置包,适合刚接触GNU工具链、需要快速搭建本地编译环境的初学者。压缩包共2000个文件,约129.46MB,以h/hpp头文件和Python脚本为主,另有c源码、txt说明、shell脚本与…

2026/9/25 22:59:21 阅读更多 →
ModLens Guard 机制源码解读:如何精准嗅探模型有无视觉能力,杜绝无效图片调用

ModLens Guard 机制源码解读:如何精准嗅探模型有无视觉能力,杜绝无效图片调用

ModLens Guard 机制源码解读:如何精准嗅探模型有无视觉能力,杜绝无效图片调用 【免费下载链接】modlens The first vision plugin for DeepSeek Harness, and the vision bridge for every text-only coding agent. Paste an image, get structured JSON…

2026/9/25 22:59:21 阅读更多 →
bb SDK 编程指南:用 BBSdk 以代码驱动你的 AI 编码工作流

bb SDK 编程指南:用 BBSdk 以代码驱动你的 AI 编码工作流

bb SDK 编程指南:用 BBSdk 以代码驱动你的 AI 编码工作流 【免费下载链接】bb The agent IDE that builds itself 项目地址: https://gitcode.com/gh_mirrors/bb14/bb bb 是一款「自我构建的智能体 IDE(agentic IDE)」,而 …

2026/9/25 22:59:21 阅读更多 →
Flutter实战:AI对话App开发环境搭建与核心链路解析

Flutter实战:AI对话App开发环境搭建与核心链路解析

1. 立项复盘:这个AI对话App为什么最终选了Flutter那周产品例会开了二十分钟,需求就一句话:"我们要做一个AI对话App,手机上能用,先上Android和iOS。"听完这句话,我脑子里先闪过三个技术选型&#…

2026/9/25 22:59:21 阅读更多 →
C# + OpenVINO + 异步推理:YOLO 实时检测流水线优化与 FPS 提升实践

C# + OpenVINO + 异步推理:YOLO 实时检测流水线优化与 FPS 提升实践

简介:这份资源是一套C#结合OpenVINO部署YOLO模型并实现异步推理的完整工程与教程资料,面向希望在高帧率场景下(如150FPS以上)做实时目标检测的开发者。资源涵盖模型转换、IR格式优化、C#环境配置及异步推理关键代码,适…

2026/9/25 22:59:21 阅读更多 →
七星卫通技术专业吗

七星卫通技术专业吗

从北斗卫星导航系统完成全球组网,到天通一号卫星移动通信系统建成,国产卫星通信产业从追赶到并跑,从单点突破到体系成型,走过了十余年的攻坚旅程。在这片关乎信息安全、关乎极端场景通信保障的蓝海中,北京七星卫通科技…

2026/9/25 22:58:20 阅读更多 →

日新闻

AI元人文:从工具使用到思维重构的深度探索

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:00:41 阅读更多 →
Python+CNN车牌识别实战:从数据预处理到模型训练与部署

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:00:41 阅读更多 →
Vim基础操作全攻略:保存退出、模式切换与高频命令实战

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/25 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/25 19:27:14 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/25 11:15:26 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/25 20:29:09 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/25 20:29:43 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/25 20:29:31 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/25 19:27:26 阅读更多 →