MySQL 正式引入 JavaScript 支持!
近期,MySQL
官方宣布了正式在 MySQL
中引入了 JavaScript
支持!
下面是 MySQL
官方的描述:
MySQL
正在持续推动创新,现在已在数据库内部包含丰富的过程式编程能力。开发者现在可以在MySQL
数据库服务器中编写JavaScript
存储程序(函数和过程)。这些存储程序将使用GraalVM
运行时进行运行。
这一举措还是相当炸裂的,继浏览器、服务端、客户端之后, JavaScript
语言终于卷到数据库上面了!
JavaScript 存储过程
JavaScript
是开发人员中最流行的编程语言。除了简单的语法和对现代语言特性的支持外,它的流行之处在于丰富的生态系统,提供了大量可重用的代码模块。
当需要持久性存储时,MySQL
作为最流行的开源数据库,将成为 JavaScript
开发人员的自然选择。通过支持存储过程中的 JavaScript
,开发人员将能够用熟悉的语言编写 MySQL
存储过程,并利用广泛的 JavaScript
生态系统!
支持 JavaScript
存储过程不仅可以通过利用大型生态系统提高开发人员的生产力,还可以让更多的开发人员掌握编写存储过程所必需的技能。换句话说,公司现在可以利用广泛可获得的 JavaScript
技能集进行后端开发,从而吸引更广泛的开发人才。
存储过程通过减少数据库服务器和应用程序之间的数据移动,提供了一个重要的优势。
传输大量数据,尤其是用于批处理,可能会带来很多问题:
- 这需要耗费时间,并且可能会导致网络开销增加。
- 当应用程序进行频繁交互时,增加的延迟可能会变得明显。
- 在中间层或应用层处理大容量数据需要大量的内存和存储资源,增加了成本。
- 由于安全风险和数据保护要求,通常需要避免在机器之间传输大量数据,尤其是在云环境中。
- 将大量数据移出数据库服务,将增加出口费用。
使用存储过程在数据库内部处理数据是解决这些问题的常见方法。
使用场景
MySQL-JavaScript
为应用程序设计提供了新的机会,这些机会在过去受到权衡的限制。JavaScript
存储过程使开发人员能够回避数据移动,并轻松地在数据库内部实现高级数据处理逻辑。以下是一些简单用例的示例:
- 数据提取:从数据库中常用的复杂对象中提取信息,例如
URL
字符串。 - 数据格式化:使用广泛使用的模板化方案(如
JavaScript
的Mustache
包)生成格式化的字符串。 - 近似搜索:在
SELECT
查询中使用相似性评分函数,例如从表中检索相似的字符串。 - 数据验证:使用复杂的验证规则清理数据。例如,使用
JavaScript
的Validator
。 - 压缩/编码:使用
MySQL
中未包含的自定义算法进行数据压缩和加密。 - 数据转换:更改数据表示,例如将字符串列转换为特征工程中使用的稀疏矩阵表示。
这些示例只是最简单和常见的案例,实际上还会有很多复杂的场景,例如部署完整的数据管道和设置机器学习应用程序的分段环境等。
MySQL-JavaScript
MySQL
现在引入了对 JavaScript
存储过程的支持,用户现在可以在数据库内部表达丰富的过程逻辑。JavaScript
运行时通过 GraalVM
集成,用户可以免费使用 GraalVM
企业版(EE)的所有功能,如编译器优化、性能和安全功能。
此版本支持以下功能:
- 基于
ECMAScript 2021
的JavaScript
语言 - 存储过程和存储函数
-
MySQL
数据类型,如各种整数、浮点数和CHAR/VARCHAR
类型
ECMAScript
标准库包括许多基本的使用操作和数据结构,使实现变得简单和表达性强。开发人员还可以从在线软件包管理器(如 “npm”
)中重复使用数百万个可用的第三方软件包。
GraalVM
GraalVM
是 Oracle
的编译器生态系统,包括 JDK、JavaScript、R、Python、Ruby
和 Java
等语言实现。它包含即时编译(JIT
)和预编译(AOT
)技术。它还提供了一个完全托管的虚拟机,具有沙箱能力和工具支持。MySQL-JavaScript
与 GraalVM
企业版集成在一起。
定义 JavaScript 存储过程
要在 MySQL
中创建 JavaScript
存储过程,你可以使用用于传统存储函数和存储过程的 SQL
语句的变体:
CREATE FUNCTION gcd_js (a INT, b INT) RETURNS INT
LANGUAGE JAVASCRIPT AS $$
let [x, y] = [Math.abs(a), Math.abs(b)];
while(y) [x, y] = [y, x % y];
return x;
$$;
从上面的示例中可以看出,JavaScript
代码直接嵌入在 SQL
可调用函数的定义中。参数的名称可以直接在 JavaScript
代码中引用,在调用函数时,SQL
类型和 JavaScript
类型之间会进行隐式类型转换。要调用 JavaScript
存储过程,应使用 CALL
语句,类似于常规 SQL
存储过程。存储过程支持输入和输出参数。
在 SQL 语句中执行 JavaScript 代码
JavaScript
函数可以在任何传统 SQL
函数可以被调用的地方被 SQL
语句调用;在 SELECT
表达式、WHERE、GROUP BY
和 ORDER BY
子句、DMLs、DDLs
、视图等等。以下是一个 SQL
语句的示例,它调用了我们上面定义的函数:
SELECT col1, col2, gcd_js(col1,col2)
FROM my_table
WHERE gcd_js(col1, col2) > 1
ORDER BY gcd_js(col1, col2);
CREATE TABLE gcd_table
AS SELECT gcd_js(col1,col2)
FROM my_table;
在 MySQL 中调试 JavaScript 代码
调试与软件开发紧密相连,MySQL-JavaScript
特性提供了额外的 SQL
接口以帮助故障排查,同时 JavaScript
程序在数据库中运行。
CREATE PROCEDURE division (IN a INT, IN b INT,
OUT result DOUBLE) LANGUAGE JAVASCRIPT AS $$
function validate(num) {
console.log("validating input value: ", num);
if (num === 0) throw ("Division by Zero!");
}
validate(b);
result = a / b;
$$
JavaScript
异常到 MySQL
错误的转换是完全透明的。开发人员也可以访问 JavaScript
堆栈跟踪,以及标准输出。
CALL division( 5, 0, @res);
ERROR 6000 (HY000): JavaScript> Division by Zero!
SELECT mle_session_state("stdout");
validating input value: 0
SELECT mle_session_state("stack_trace");
<js> validate(division:9:187-214)
<js> division(division:11:222-232)
<js> :anonymous(division:15:256-265)
</js></js></js>
安全、性能、兼容性
安全、性能、兼容性这三个方面可谓是开发者对一项技术最重要的关注点了。
-
安全:
MySQL
对JavaScript
的支持提供了最高级别的安全性、隔离性和数据保护。虚拟机沙盒确保恶意代码不能妨害MySQL
服务器的其他模块。每个存储程序都在其自己的上下文中解析和执行。这种隔离策略不允许一个存储程序读取或修改其他存储程序的数据或代码。JavaScript
用户代码中的线程生成或操作被限制,JavaScript
用户代码无法访问网络通信或文件系统。JavaScript
存储程序建立在标准的MySQL
权限模型之上。只有拥有特权的用户才允许创建存储程序。 -
性能:采用特定用途定制的
VM
,MySQL
和JavaScript
的集成能提供最优的端对端性能。该定制基于GraalVM
的预编译(AOT
),即把语言实施编译为原生二进制形式,以加快处理速度。 -
兼容性:
JavaScript
存储程序与传统的SQL
存储程序无缝协同工作。这个特性对存储引擎保持中立,可以从InnoDB,Lakehouse
和HeatWave
中透明地访问数据。MySQL Heatwave
服务现在带有预安装和配置的JavaScript
,可在OCI,AWS
和Azure
服务部署中使用。
大家对这项支持怎么看?欢迎在评论区留言~