PostgreSQL教程FG206-PG原生语言支持:底层实现与扩展
本文档风哥主要介绍PostgreSQL数据库的原生语言支持,包括PL/pgSQL、PL/Tcl、PL/Perl、PL/Python等过程化语言的底层实现与扩展,风哥教程参考PostgreSQL官方文档Native Language Support内容,适合数据库开发者和高级DBA人员在学习和测试中使用。更多视频教程www.fgedu.net.cn
Part01-基础概念与理论知识
1.1 PostgreSQL原生语言支持的概念
PostgreSQL原生语言支持是指PostgreSQL数据库内置的过程化语言支持,允许用户使用各种编程语言编写存储过程、函数、触发器等数据库对象。PostgreSQL支持多种过程化语言,包括内置的PL/pgSQL和可扩展的PL/Tcl、PL/Perl、PL/Python等。
- 内置支持PL/pgSQL语言
- 可扩展支持多种外部语言
- 提供统一的语言接口
- 支持复杂的业务逻辑实现
- 可以访问数据库内部结构
1.2 PostgreSQL原生语言支持的特性
PostgreSQL原生语言支持的主要特性包括:
- 多语言支持:支持PL/pgSQL、PL/Tcl、PL/Perl、PL/Python等多种语言
- 集成性:与SQL无缝集成,可以在SQL语句中调用
- 性能优化:编译执行,提高性能
- 安全性:提供权限控制和安全隔离
- 可扩展性:可以自定义语言处理器
1.3 PostgreSQL原生语言支持的架构
PostgreSQL原生语言支持的架构包括:
- 语言处理器:负责解析和执行过程化语言代码
- 语言接口:提供统一的API接口
- 编译系统:将过程化语言代码编译为可执行形式
- 运行时环境:提供执行过程化语言代码的环境
- 安全机制:确保过程化语言代码的安全执行
Part02-生产环境规划与建议
2.1 PostgreSQL语言安装与配置
PostgreSQL语言安装与配置建议:
$ psql -U pgsql -d fgedudb
postgres=# CREATE EXTENSION plpgsql;
# 安装PL/Tcl
$ sudo apt-get install postgresql-pltcl
$ psql -U pgsql -d fgedudb
postgres=# CREATE EXTENSION pltcl;
# 安装PL/Perl
$ sudo apt-get install postgresql-plperl
$ psql -U pgsql -d fgedudb
postgres=# CREATE EXTENSION plperl;
# 安装PL/Python
$ sudo apt-get install postgresql-plpython3-18
$ psql -U pgsql -d fgedudb
postgres=# CREATE EXTENSION plpython3u;
# 查看已安装的语言
postgres=# SELECT lanname FROM pg_language;
lanname
———-
internal
c
sql
plpgsql
pltcl
plperl
plpython3u
(7 rows)
2.2 PostgreSQL语言安全性
PostgreSQL语言安全性建议:
# 查看语言权限
postgres=# SELECT lanname, lanpltrusted FROM pg_language;
lanname | lanpltrusted
———-+————–
internal | f
c | f
sql | t
plpgsql | t
pltcl | f
plperl | f
plpython3u | f
# 可信语言与不可信语言
# 可信语言(如plpgsql、sql):不能执行系统命令
# 不可信语言(如pltcl、plperl、plpython3u):可以执行系统命令
# 安全配置
# 只允许可信语言
postgres=# REVOKE USAGE ON LANGUAGE pltcl FROM PUBLIC;
postgres=# REVOKE USAGE ON LANGUAGE plperl FROM PUBLIC;
postgres=# REVOKE USAGE ON LANGUAGE plpython3u FROM PUBLIC;
# 只授予特定用户使用不可信语言的权限
postgres=# GRANT USAGE ON LANGUAGE plpython3u TO fgedu;
2.3 PostgreSQL语言性能优化
PostgreSQL语言性能优化建议:
- 使用编译语言:对于性能要求高的场景,使用C语言编写函数
- 优化PL/pgSQL:使用PL/pgSQL的执行计划缓存
- 减少函数调用:避免频繁调用函数,特别是在循环中
- 使用合适的语言:根据任务选择合适的语言
- 内存管理:注意内存使用,避免内存泄漏
Part03-生产环境项目实施方案
3.1 PostgreSQL PL/pgSQL实现
3.1.1 PL/pgSQL基础语法
CREATE OR REPLACE FUNCTION fgedu_get_customer(IN customer_id INTEGER, OUT name VARCHAR, OUT email VARCHAR)
RETURNS RECORD AS $$
BEGIN
SELECT c.name, c.email INTO name, email
FROM fgedu_customers c
WHERE c.id = customer_id;
IF NOT FOUND THEN
RAISE EXCEPTION ‘Customer not found: %’, customer_id;
END IF;
END;
$$ LANGUAGE plpgsql;
# 调用函数
SELECT * FROM fgedu_get_customer(1);
name | email
——–+—————–
Alice | alice@fgedu.net.cn
(1 row)
3.1.2 PL/pgSQL高级特性
CREATE OR REPLACE PROCEDURE fgedu_update_customer(IN customer_id INTEGER, IN new_email VARCHAR)
LANGUAGE plpgsql AS $$
BEGIN
UPDATE fgedu_customers
SET email = new_email
WHERE id = customer_id;
IF NOT FOUND THEN
RAISE EXCEPTION ‘Customer not found: %’, customer_id;
END IF;
COMMIT;
END;
$$;
# 调用存储过程
CALL fgedu_update_customer(1, ‘alice.new@fgedu.net.cn’);
# PL/pgSQL触发器函数示例
CREATE OR REPLACE FUNCTION fgedu_customer_trigger()
RETURNS TRIGGER AS $$
BEGIN
IF TG_OP = ‘INSERT’ THEN
NEW.created_at := NOW();
ELSIF TG_OP = ‘UPDATE’ THEN
NEW.updated_at := NOW();
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
# 创建触发器
CREATE TRIGGER fgedu_customer_trigger
BEFORE INSERT OR UPDATE ON fgedu_customers
FOR EACH ROW EXECUTE FUNCTION fgedu_customer_trigger();
3.2 PostgreSQL外部语言支持
3.2.1 PL/Python示例
CREATE OR REPLACE FUNCTION fgedu_python_example(text)
RETURNS text AS $$
return “Hello, ” + args[0]
$$ LANGUAGE plpython3u;
# 调用函数
SELECT fgedu_python_example(‘World’);
fgedu_python_example
———————-
Hello, World
(1 row)
# PL/Python高级示例
CREATE OR REPLACE FUNCTION fgedu_python_sum(integer[])
RETURNS integer AS $$
return sum(args[0])
$$ LANGUAGE plpython3u;
# 调用函数
SELECT fgedu_python_sum(ARRAY[1, 2, 3, 4, 5]);
fgedu_python_sum
——————
15
(1 row)
3.2.2 PL/Perl示例
CREATE OR REPLACE FUNCTION fgedu_perl_example(text)
RETURNS text AS $$
my $name = shift;
return “Hello, $name”;
$$ LANGUAGE plperl;
# 调用函数
SELECT fgedu_perl_example(‘World’);
fgedu_perl_example
——————–
Hello, World
(1 row)
3.3 PostgreSQL语言扩展
PostgreSQL语言扩展方法:
# 注意:需要超级用户权限
CREATE LANGUAGE mylanguage HANDLER mylanguage_handler VALIDATOR mylanguage_validator;
# 示例:创建一个简单的语言扩展
# 1. 编写C语言处理器
/* mylanguage.c */
#include “postgres.h”
#include “executor/spi.h”
#include “commands/trigger.h”
#include “fmgr.h”
PG_MODULE_MAGIC;
Datum mylanguage_handler(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(mylanguage_handler);
Datum
mylanguage_handler(PG_FUNCTION_ARGS)
{
/* 实现语言处理器 */
PG_RETURN_NULL();
}
Datum mylanguage_validator(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(mylanguage_validator);
Datum
mylanguage_validator(PG_FUNCTION_ARGS)
{
/* 实现语言验证器 */
PG_RETURN_NULL();
}
# 2. 编译成共享库
$ gcc -I$(pg_config –includedir-server) -shared -o mylanguage.so mylanguage.c
# 3. 安装共享库
$ sudo cp mylanguage.so $(pg_config –pkglibdir)
# 4. 创建语言
CREATE LANGUAGE mylanguage HANDLER mylanguage_handler VALIDATOR mylanguage_validator;
Part04-生产案例与实战讲解
4.1 PostgreSQL语言实战案例
4.1.1 业务逻辑封装
CREATE OR REPLACE FUNCTION fgedu_process_order(IN order_id INTEGER)
RETURNS BOOLEAN AS $$
DECLARE
order_rec RECORD;
customer_rec RECORD;
BEGIN
— 获取订单信息
SELECT * INTO order_rec
FROM fgedu_orders
WHERE id = order_id;
IF NOT FOUND THEN
RAISE EXCEPTION ‘Order not found: %’, order_id;
END IF;
— 获取客户信息
SELECT * INTO customer_rec
FROM fgedu_customers
WHERE id = order_rec.customer_id;
— 处理订单逻辑
UPDATE fgedu_orders
SET status = ‘processed’,
processed_at = NOW()
WHERE id = order_id;
— 记录日志
INSERT INTO fgedu_order_logs(order_id, action, performed_at)
VALUES(order_id, ‘Order processed’, NOW());
RETURN TRUE;
EXCEPTION
WHEN OTHERS THEN
— 记录错误
INSERT INTO fgedu_error_logs(error_message, error_time)
VALUES(SQLERRM, NOW());
RETURN FALSE;
END;
$$ LANGUAGE plpgsql;
# 调用函数
SELECT fgedu_process_order(1);
fgedu_process_order
——————–
t
(1 row)
4.2 PostgreSQL语言工具使用
4.2.1 使用pgAdmin管理语言
1. 打开pgAdmin,连接到数据库
2. 展开”Languages”节点
3. 右键点击语言,选择”Properties”查看详细信息
4. 右键点击”Languages”节点,选择”Create” -> “Language”创建新语言
# 使用psql管理语言
# 查看语言
postgres=# \dL
4.3 PostgreSQL语言常见问题
PostgreSQL语言常见问题及解决方法:
# 错误信息
ERROR: language “plpython3u” does not exist
# 解决方法
$ sudo apt-get install postgresql-plpython3-18
postgres=# CREATE EXTENSION plpython3u;
# 常见问题2:权限不足
# 错误信息
ERROR: permission denied for language plpython3u
# 解决方法
postgres=# GRANT USAGE ON LANGUAGE plpython3u TO fgedu;
# 常见问题3:函数执行错误
# 错误信息
ERROR: syntax error at or near “RETURN”
# 解决方法
检查PL/pgSQL函数语法,确保语法正确
Part05-风哥经验总结与分享
5.1 PostgreSQL语言支持最佳实践
PostgreSQL语言支持最佳实践:
- 选择合适的语言:根据任务选择合适的过程化语言
- 优化函数性能:避免在函数中执行复杂的查询
- 使用参数化查询:避免SQL注入
- 错误处理:完善的错误处理机制
- 文档化:为函数编写详细的文档
- 权限管理:合理设置语言权限
- 性能监控:监控函数执行性能
- 代码审查:对过程化语言代码进行审查
5.2 PostgreSQL语言支持检查清单
– [ ] 所需语言是否已安装
– [ ] 语言权限是否正确设置
– [ ] 函数语法是否正确
– [ ] 函数性能是否优化
– [ ] 错误处理是否完善
– [ ] 安全性是否考虑
– [ ] 文档是否完整
– [ ] 测试是否充分
# 生产环境检查清单
– [ ] 只启用必要的语言
– [ ] 不可信语言权限是否严格控制
– [ ] 函数执行是否有监控
– [ ] 性能是否满足要求
– [ ] 安全漏洞是否存在
5.3 PostgreSQL语言工具推荐
PostgreSQL语言工具推荐:
- pgAdmin:图形化管理工具,支持语言管理
- psql:命令行工具,支持语言管理
- PL/pgSQL Debugger:PL/pgSQL调试工具
- PostgreSQL Extension Network:扩展库
- pg_prove:PostgreSQL测试工具
- pgtap:PostgreSQL测试框架
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
