需要使用 Base64 格式吗?那么本网站正好适合您!使用我们的在线工具对数据进行编码或解码,便捷好用。

SQL 中的 Base64 编码:完整指南

数据库时不时要跟外面的世界打交道,而外面的世界并不总是讲字节。一个 API 要把你的 logo 塞进 JSON 字符串里。一个配置导出要一个密钥,能塞进 YAML 的一行里,无引号、无反斜杠。一个维护脚本要把一个文件穿过一个只运文本的系统。那就是你的数据穿上字母外衣的时刻,而这件外衣的名字叫 base64。

格式本身在首页已经讲过了(64 个可打印字符,每四个顶替三个输入字节,最后一组最多用两个 = 号做填充),所以本文跳过那堂课,直接上手干机器活。有两件事要攥紧:编码是数据变得更大的方向,列宽和数据包限制会对它的每一个字节都感同身受;而这个 SQL 家族里的编码器,在两件事上意见不一,而这两件事恰恰是事后最难撤销的:当你的列里装的是文本时它们读的是哪些字节,以及它们把换行放在写出物的哪里。

编码器速查表

谁在值班、它们吃什么、它们的输出会在哪里出问题。最后两列才是咬人的地方,因为一个塞满不请自来的换行的字符串,和一个换了字母表的字符串,都是完全合法的 base64 字符串,而你的消费者照样会拒收:

方言 调用 输入类型 76 字符折行吗? URL-safe 选项 从何时起
MySQL 8.x / MariaDB 10.x TO_BASE64(str) 字符串(字符集生效) 没有 MySQL 5.6(2013)
PostgreSQL encode(bytea, 'base64') bytea 是,仅 LF 没有 7.2(2002)
SQLite(CLI 3.41+) base64(blob) BLOB 是,在 72 没有 3.41.0(2023)
DuckDB to_base64(blob) BLOB 没有 较新版本
ClickHouse 18.16+ base64Encode(x) 任意,转成 String base64URLEncode() 18.16(2018)
SQL Server 2025+ BASE64_ENCODE(bin [, url_safe]) varbinary 第二个参数 2025
Oracle UTL_ENCODE.BASE64_ENCODE(raw) RAW 没有 9i 年代
Snowflake BASE64_ENCODE(binary) BINARY 没有 当前版本

从左到右读这张表,这份工作就落进两个决定。第一,你的字节怎么到场:输入类型那一列正是字符集惊吓的出生地,因为"同一段文本"在不同的排序规则下是不同的字节。第二,另一边出来的是什么:折行列决定你的结果是一整条平铺的长行,还是一首每 76 个字符断一次行的诗;URL-safe 列决定你究竟能不能把结果放进链接里。

先决定你要的是哪些字节

编码器打包的是字节,但你的列里通常装的是字母,而字母只有在你说清按哪种字节字母表时才是字节。MySQL 的 TO_BASE64() 按连接字符集读取它的参数,这在大多数时候是便利,在少数时候是事故:同一个 'héllo',在 latin1 客户端和 utf8mb4 客户端下发出不同的 base64。当你指的是存储原样时,先用二进制转换把它冻住:

SELECT TO_BASE64('hello') AS from_text;
SELECT TO_BASE64(CAST('héllo' AS BINARY)) AS utf8_bytes;

第二行回来时是 aMOpbGxv,中间那两个十六进制字节 C3 A9 就是 UTF-8 拼写 é 的方式。PostgreSQL 在前端更严格:encode() 拒绝看任何不是 bytea 的东西,所以文本值必须先指认自己的编码,而裸字节可以以十六进制字面量的形式到场:

SELECT encode(convert_to('héllo', 'UTF8'), 'base64') AS text_as_utf8;
SELECT encode('\x68656c6c6f'::bytea, 'base64') AS raw_bytes;

其他每个方言都有自己通向同一个想法的前门,它们全都归结为"拿到字节,然后打包":

方言 文本转字节 编码器调用
T-SQL 经列排序规则的 CAST('héllo' AS VARBINARY(8000)) BASE64_ENCODE(bin)
Snowflake TO_BINARY('héllo', 'UTF-8') BASE64_ENCODE(binary)
Oracle UTL_RAW.CAST_TO_RAW('héllo') UTL_ENCODE.BASE64_ENCODE(raw)
DuckDB encode('héllo') 给出一个 BLOB to_base64(blob)
SQLite CLI 一个 BLOB 字面量,例如 X'68656C6C6F' base64(blob)

实用规则和解码那边一样:编码之前定好字符集,以字面量写进查询,然后在你信任这一列之前,先让一个带重音的载荷完整走一遍管道。一个 héllo 能抓住每一种错误的排序规则,而且成本为零。

然后,盯着出来的是什么

字节一旦打包完毕,编码器们就在换行上分道扬镳。三个会把输出折行:MySQL 和 PostgreSQL 在 76 字符处,这是邮件留下的习惯;SQLite CLI 在 72 处;其余的不管多长都还你一整条平铺的长行。这个差异很容易漏掉,发现起来却代价不菲,因为一个藏着换行的 base64 字段,就是一个会在半路弄崩 JSON 解析器的字段:

SELECT LENGTH(TO_BASE64(REPEAT('x', 300))) AS wrapped,
      LENGTH(REPLACE(TO_BASE64(REPEAT('x', 300)), '\n', '')) AS flat;

三百个输入字节回来时是 400 个 base64 字符,而同一次调用量出来是 405,因为五个换行搭了顺风车。背后的算术小得足以记在脑子里:平铺长度是输入长度除以三、向上取整、再乘以四。如果你的编码器折行,就在每 76 个字符的行之间加一个换行,也就是平铺长度除以 76、向上取整、再减一。三百字节:平铺 400,折行 405。一百一十一字节:平铺 148,折行 149。比你预算多出来的那一个换行,就是一个 VARCHAR(500) 列开始悄悄截断 VARCHAR(480) 载荷的方式。

两条值得写下来的后果。如果写的一方可能会折行,就把文本列按平铺长度加一点余量来设计;或者干脆禁止写的一方折行,然后按平铺设计。还要记住,你的结果要硬碰的那个限制,是字符串的限制,不是字节的限制:在 MySQL 里,折行后的文本要计入 max_allowed_packet(MySQL 8 默认 64 MB),所以一张 50 MB 的照片编码成约 67 MB 的字母后,即便裸文件放得下,默认数据包也装不下它。

URL-safe Base64:会旅行的字母表

RFC 4648 的第 5 节为 base64 定义了第二个字母表,因为原始字母表里有两个字符在 URL 语法里另有职务。加号用来加查询参数,斜杠用来分隔路径段,填充等号一碰到查询字符串就会立刻被百分号编码。URL-safe 变体把 + 换成 -/ 换成 _,而 JWT 规范在此基础上又把填充整个丢掉,于是令牌可以安安静静地待在链接、路径段或文件名里,全程没有一个百分号。

这个家族里只有一个方言原生带着这个开关。SQL Server 2025 的 BASE64_ENCODE() 接受一个可选的第二个参数,打开它之后,结果使用 -_ 并跳过填充:

SELECT BASE64_ENCODE(0xCAFECAFE) AS standard;
SELECT BASE64_ENCODE(0xCAFECAFE, TRUE) AS url_safe;

同样四个字节回来时是 yv7K/g==yv7K_g。ClickHouse 把变体拆成单独的函数,它的 URL-safe 形式也丢掉填充:

SELECT base64URLEncode('https://clickhouse.com') AS url_safe;

结果以 aHR0cHM6Ly9jbGlja2hvdXNlLmNvbQ 到场,标准形式的那两个填充号被裁掉了。其他所有地方的配方都是两次字符翻译加一次修剪,值得写成一次数据库函数,因为每条令牌管道都需要它。在 PostgreSQL 里它长这样:

SELECT rtrim(replace(replace(
        encode(convert_to('https://clickhouse.com', 'UTF8'), 'base64'),
        '+', '-'),
      '/', '_'),
      '=') AS url_safe;

+ 翻译成 -,把 / 翻译成 _,修剪掉末尾的填充,完事。给 SQL Server 人群一条警告:url_safe 输出并不是服务器自己的 XML 和 JSON base64 解码器所期望的,所以一列为了外面世界而按 URL-safe 形式打包的数据,用内置函数在数据库里是解不开的。挑字母表之前先想清楚受众。

JWT:从数据库里盖出令牌

你能用编码器搭出来的最有意思的东西是 JSON Web Token,因为一个 JWT 不过是三段排成一行的 base64:一个头和一个载荷,都是不带填充、按 URL-safe 打包的 JSON 对象,外加一个在前两段上计算出的签名。当一个批处理任务需要铸造令牌(给测试环境播种、重新生成过期的 API 凭据、搭建审计数据流)时,只要你接受用 pgcrypto 做 HMAC(如果还没装,先执行一次 CREATE EXTENSION IF NOT EXISTS pgcrypto; 启用),整场仪式都能装进一条 PostgreSQL 查询里:

WITH head AS (
  SELECT encode(convert_to('{"alg":"HS256","typ":"JWT"}', 'UTF8'), 'base64') AS h
),
body AS (
  SELECT encode(convert_to('{"sub":"1234567890","name":"Dev User"}', 'UTF8'), 'base64') AS p
),
joined AS (
  SELECT rtrim(replace(replace(h, '+', '-'), '/', '_'), '=') AS h64u,
         rtrim(replace(replace(p, '+', '-'), '/', '_'), '=') AS p64u
  FROM head, body
)
SELECT h64u || '.' || p64u || '.' ||
       rtrim(replace(replace(
         encode(hmac((h64u || '.' || p64u)::bytea, 'sql-secret-key'::bytea, 'sha256'), 'base64'),
         '+', '-'),
         '/', '_'),
       '=') AS token
FROM joined;

每一步都是本文已经演示过的动作:把 JSON 打包成 base64,把它重塑成 URL-safe 无填充字母表,然后对前两段签名并把签名用同样的方式重塑。对上文的 JSON 和密钥 sql-secret-key,结果是 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkRldiBVc2VyIn0.7_3VdmM8vH0L2bRBNqXXQXzZIR1l8T4_S4QxPPNBEFM,任何 HS256 检查器都收的令牌。注意事项和这个把戏本身一样值得版面:它只覆盖 HMAC 算法(HS256、HS384、HS512),把共享密钥放进了数据库语句里,而且是为批处理和审计工作而生的,不是为生产令牌服务。验证那一侧,也就是拿密钥证明那个令牌的过程,是应用层或者解码文章里签名检查的活。

文本列里的图像与文件

在 SQL 里编码最常见的理由,是一个必须化身文本旅行的文件:一个选择内联图像而不是引用它的 API,一个给不运二进制的系统做的导出,一个在新服务器上重建数据库的播种脚本。DuckDB 让这次往返近乎琐碎,因为它通过一个接受 glob 模式的表函数把文件读进 BLOB,而编码器会把到达的一切拍平:

SELECT filename, to_base64(content) AS b64
FROM read_blob('/data/pics/*.png');

每个文件一行,每行一条平铺的 base64 字符串,没有折行需要清理,虽然惯常的一两个填充号照样搭车在末尾。把结果写进文本列,图像就能穿过任何搬文本的渠道。然后诚实地谈一谈成本:一张 1 MB 的照片到场时是约 1.33 MB 的字母,从那一刻起,每一次扫描、排序和索引条目都要付这个价。如果你掌控 schema,更好的设计是 BLOB 列加上 API 边界处的编码,只有真正离开大楼的字节才被穿上外衣。

HTTP、JSON 与 API 流量

头和载荷是 base64 干安静日常工作的地方。Basic 认证头是字面前缀 Basic 加上 username:password 的 base64,在 SQL 里构造一个就是拼接加一次编码:

SELECT 'Basic ' || encode(convert_to('alice' || ':' || 's3cret', 'UTF8'), 'base64') AS header;

这样就搭出了 Basic YWxpY2U6czNjcmV0,客户端会发送的那条头原样不差。拿它来生成集成测试拿来对比的夹具,或者在审计一列存好的头之前先把它们归一化。JSON 这边,MySQL 能在一个表达式里打包一个字段并嵌进文档,应用代码完全不掺和:

SELECT JSON_OBJECT('img', TO_BASE64(CAST('hello file' AS BINARY))) AS doc;

结果是 {"img": "aGVsbG8gZmlsZQ=="},一个随时可发的载荷。同样的形状适用于证书、公钥以及你的 API 决定内联的任何其他文件,而且当你自己是流量的生产者、而不是在解码别人的东西时,这才是要紧的方向。

配置文件、密钥与环境变量

有一个导出习惯值得单独占一个段落,因为它无处不在:以 base64 形式存在配置表里的密钥。Kubernetes 让这个习惯活了下来,那里的密钥值落盘时就是 base64,好塞进 YAML 的一行里,无引号、无换行、无反斜杠,而每一个遇过 Kubernetes 管道的自研配置系统都把它学了过去。打包方向是每个值一次编码,字符集的活由二进制转换来干,这样导出的文本就和存储的字节一模一样:

SELECT name, TO_BASE64(CAST(value AS BINARY)) AS for_config
FROM app_config
WHERE name LIKE '%_secret%';

每个不超过 57 字节的值都会出一条平铺的、可直接粘贴的字符串;更长的值进 YAML 前需要一个 REPLACE() 把折行去掉,新环境在另一边再把它解码回来。用配得上这份结果的谨慎对待它:你刚刚把一列存起来的密钥变成了一列任何人类十秒左右就能读出来的存起来的密钥,而配置里存 base64 的习惯,在你站得离明文这么近的时候,就值得再审视一遍。Base64 是传输,不是保险箱。如果环境里有真正的密钥保险库,那这个 base64 列距离迁走只差一个迁移。

邮件与 76 字符的习惯

76 字符的折行比这一页上的每一个数据库都老。MIME,那套让邮件能携带二进制附件的标准(RFC 2045 第 6.8 节,1996 年),把 base64 输出在 76 字符处折行,每行以回车加换行收尾,因为老的邮件网络不敢信任更长的行。这里的三个编码器把折行继承为默认(MySQL、PostgreSQL、SQLite CLI),这对最终落进邮件的东西是礼物,对没落进邮件的东西是陷阱。而且它们继承得不完整:PostgreSQL 用单个换行符结束每一行,而不是 MIME 标准规定的回车加换行,所以一段本该粘进真实邮件附件的输出还需要再过一道:

WITH t AS (
 SELECT replace(encode(attachment::bytea, 'base64'), chr(10), '') AS s
 FROM email_outbox
)
SELECT regexp_replace(s, '(.{1,76})', '\1' || chr(13) || chr(10), 'g') AS mime_ready
FROM t;

去掉 PostgreSQL 已经加上的换行,然后按 76 重新折行,每行后面跟完整的 CRLF,一个表达式就让字符串变成 MIME 合规。让三百个字节走一遍,你打包的 400 个字符变成 412:六个折行,六对 CRLF,十二个字符的传输仪式。同一形状的问题也出现在 PEM 块上(它在 64 而不是 76 处折行),以及出现在那些完全不要折行的 API 上(它们的 JSON 解析器不允许字段中间出现换行)。对它们的规则是一样的:编码之前先搞清楚消费者签的是哪份约定,因为给一列存好的 base64 重新折行,是一次迁移,不是一条查询。

陷阱:编码器对你撒谎的地方

这份清单里的每个陷阱都是某个特定方言设的,而不是 base64 设的,而且每一个都至少有一个代码库在生产里发现了它:

  • 不请自来的折行。MySQL 和 PostgreSQL 默认在 76 处折行,SQLite CLI 在 72 处,而你的查询里没有人要求它这么做。你 JSON 里的 base64 字段现在装着换行,而那个按规范接受这种格式的消费者在现实里拒收了它。平铺形式就是对换行字符跑一次 REPLACE(),在写的一方应用,这样列里存的就是读的一方想要的。
  • 字符集滑倒。不带二进制转换的 TO_BASE64('héllo') 会编码连接字符集认为那些字母是什么的东西,而 latin1 客户端和 utf8mb4 客户端认为的东西不一样。同一条查询文本,两个不同的 base64 结果,错误的那个解码出来是乱码,而没人会把乱码追溯到编码器。二进制转换,或显式的 convert_to(),才是这条查询唯一诚实的版本。
  • BLOB 这扇门。DuckDB 的 to_base64() 要的是 BLOB:喂它文本它会隐式转换,所以一列非 UTF-8 编码的 varchar 可能悄悄编码出错误的字节。诚实的路子是 to_base64(encode(...)),这就是这一页上的示例对文本输入总展示这对搭档的原因。
  • 26.7 的空白变化。ClickHouse 的 base64Decode()base64URLDecode() 多年来对输入很严格,但从 26.7 起它们忽略空白(空格、制表符、换行符、回车符、换页符)而不是拒绝,所以一个过去在折行列上报错的脚本现在会悄悄成功,这本身就是一种回归。相信解码之前先查服务器版本。
  • 6000 字节的边界。SQL Server 的 BASE64_ENCODE() 在输入是 n 不超过 6000 的 varbinary(n) 时返回 varchar(8000),超过则返回 varchar(max);映射看的是声明的尺寸,不是值,所以一个 varbinary(8000) 列即使只有三个字节也返回 varchar(max)。与此同时,同一个函数的 url_safe 输出,服务器自己的 XML 和 JSON base64 解码器读不了,它们期望的是带填充的标准字母表。按将来读它的受众来挑变体。
  • 2000 字节的 RAW。在 Oracle 里,普通 SQL 语句中的 RAW 值上限是 2000 字节。既然编码器收 RAWRAW,单语句编码最多只能收约 1500 字节的输入(它 2000 个字符的输出放得下,再多的就放不下了),而单语句解码最多只能收 2000 个字符的 base64。更大的载荷要搬进 PL/SQL,那里的 RAW 变量装得下 32767 字节,一次调用能带走其中大部分,只有那些 base64 输出会超过那道天花板的载荷才需要分块循环,那个循环来自一个从未移动过的 1990 年代限制。
  • 数据包税。MySQL 把编码后的字符串计入 max_allowed_packet,而不是裸字节。一张离表格上限绰绰有余的照片,变大 33 再折行之后可能撑爆数据包,而失败的样子是被截断的值或一个看起来像数据损坏的 NULL。检查列宽的同时顺手检查一下这个限制。
  • 末尾换行。SQLite CLI 的 base64() 在最后一行末尾也加上换行符,行尾习惯一视同仁地施于最后一行。把 shell 输出粘进 JSON 字段,你就发出去了一条里面装着换行的 base64 字符串,不请自来的折行换了顶帽子。
  • 字母表假设。按标准字母表造的消费者遇上你的 URL-safe 输出(或反过来),会看到它不认识的字符。大多数解码器卡在下划线上大声失败;少数会跳过它安静失败。在 schema 注释里记录每一个 base64 列的字母表,因为下一个开发者不会记得是哪条令牌管道写了那行。

尺寸何时真正要紧

尺寸算术是平铺长度加上你的编码器追加的一切折行,比例的完整推导在首页。这里值得做的是走过数字不再只是趣闻的那些地方。一个按输入字节数定尺寸的 VARCHAR 列,会在载荷第一次长到需要额外余量时悄悄截断输出,因为三个输入字节要花四个字符。一个建在 base64 文本列上的索引要交两遍税:一次在存储,一次在每一次比较,因为索引条目是那些折行后的字母,不是字节。MySQL 的 max_allowed_packet 和 PostgreSQL 1 GB 的 bytea 天花板是大多数人最先撞上的两堵墙,而两者都是对着文本检查的,也就是这笔交易里更大的那一侧。设计答案很少是关于换另一个编码器(base64 只有一个);它关于选择编码发生在哪。BLOB 列、用于查找的哈希列、在边界处编码:base64 只存在于流量里,那里才是它的归属。

安全:Base64 不是什么

Base64 不是加密,而那个必须说出口的习惯就是前面配置表那个:以 base64 形式存储的密钥,只是换了种字体存储的密钥。这个变换是一个无密钥的双射,地球上每一种编程语言一次函数调用就能反转它,它唯一真正的效果是让值留在 YAML 的一行里。如果威胁模型里包括这个数据库的另一个用户、另一个读取导出的服务、或一条捕获了那行的日志,base64 对防御的贡献精确地等于零。它把值从人眼里藏几秒,这就是为什么它在代码评审里像保护、又在事故里失效。该保密的就加密,用一个有人真能守住的密钥加密,然后让 base64 干它擅长的活:把字节运过只运文本的渠道。

各方言何时学会折行

发布说明讲着和解码那边一样的故事,只是字母朝反方向走,而时间表说出了每个引擎的脾性:

2002 年。PostgreSQL 7.2 把 base64 列为 encode()decode() 的一等格式,与 9i 年代 Oracle 的 UTL_ENCODE 同期,以微弱优势成为这个家族里最年长的 base64 机械装置。一个拥有真正二进制类型和格式参数的数据库早早到位,因为答案只隔一个枚举值。

2000 年代初。Oracle 的 UTL_ENCODE 包在 9i 年代发布,BASE64_ENCODE() 和它的 MIME 头、quoted-printable 与 uuecode 兄弟排在一起。RAW 进,RAW 出,一个世纪的四分之一过去,这个包依然没有改变主意。

2013 年。MySQL 5.6 以一对搭档的身份加入 TO_BASE64()FROM_BASE64(),MariaDB 10.0 把两个都继承了过去。这对搭档的约定从此没动过:出门时 76 字符的行,进门时空白宽容。

2018 年。ClickHouse 18.16(2018 年 12 月)带着 MySQL 风格别名一起发布 base64Encode()base64Decode(),因为列式世界正在导入那些日志 schema 里已经带着 base64 的工作负载。

2023 年。SQLite 3.41.0 把 base64() 作为应用定义函数加进命令行 shell。核心库一如既往地什么都没得到;shell,人类真正动手戳 SQLite 文件的地方,得到了工具。

2025 年。SQL Server 2025,2025 年 11 月 GA,终于发布 BASE64_ENCODE()BASE64_DECODE(),那是产品发布三十六年后的事,也是它的用户把 XML 变通方案背得滚瓜烂熟之后整整一代人的事。

模式和解码文章收尾的那个是同一个,镜像而来:拥有真正二进制类型和格式参数的引擎,在需求显而易见的那天就得到了 base64;而万事皆字符串的引擎把它排到了后面。

值得知道的小怪癖

  • SQLite CLI 的 base64() 是这个家族的变形者,而在编码方向上它把这招展示得最清楚:喂它 BLOB 它还你带末尾换行的折行文本,喂它文本它还你一个 BLOB。一个名字,两份工作,由参数类型挑选,这个家族里没有第二个编码器会这么干。
  • ClickHouse 的 base64Decode() 家族在 26.7 变宽容了:输入里的空白现在被忽略而不是被拒绝,所以同一条查询在折行列上老服务器会失败,新服务器则悄悄返回一个值。解码器没有坏;它放松了,而这不知怎么反而更难调试。
  • PostgreSQL 像 1996 年的 MIME 标准一样正好在 76 字符处折行,只是它用单个换行符结束每一行,而不是标准的回车加换行。规范颁布二十多年后,每行少一个字符,这场叛乱除非你 diff 字节否则不可见。
  • mysql 客户端里,你编码的字节作为 base64 文本打印得好好的,但只要你用 CAST(... AS BINARY) 看一眼裸列,客户端就切到十六进制显示(binary-as-hex),一个完全没问题的 hello 到达屏幕上时是 0x68656C6C6F。这个设置已经让成千上万的开发者相信自己的编码器坏了。
  • Snowflake 在每个结果集里都把 BINARY 值显示为十六进制,所以你编码查询里的 TO_BINARY() 输入列读起来像个校验和,哪怕一切都工作正常。两种方言,两种十六进制显示,一种如出一辙的不安感。
  • Oracle 的 SQL 层 RAW 上限是 2000 字节,所以一份 3 KB 的证书根本无法作为 RAW 字面量贴进 SQL 语句。编码必须在 PL/SQL 里发生,那里的 RAW 变量装得下 32767 字节,所以这份 3 KB 的证书是一次调用,只有那些 base64 输出会超过那道天花板的载荷才需要分块循环,那个循环来自 1990 年代。
  • MIME base64 的一行是 76 个字符,也就是 57 个裸字节,因为四个字符承载三个。出现在三个编码器默认值里的那个数字 76,与其说是个限制,不如说是一个打包密度:你在老邮件附件里看到的每一条折行,都精确地携带着你数据里的 57 个字节。

另一个方向

这篇文章一直在讲如何穿上外衣:决定你要的是哪些字节,盯着出来的是什么,为受众挑选字母表,以及在列截断之前把尺寸算术做掉。脱下外衣是另一种完全不同的脾气:有的方言耸耸肩给出静默的 NULL,有的方言会大声报错,还有一套 URL-safe 字母表半个家族根本不认识。这一切,从 FROM_BASE64()decode()BASE64_DECODE(),都在关联的 SQL Base64 解码文章里深入展开,链接就在下面。在这里编码,在那里解码,整个往返一个下午就装得下。

最后更新: 2026-09-08

相关文章: SQL 中的 Base64 解码:完整指南