由 John Doe 十月 26, 2022
有时将数据引入代码很有用,而其他时候,将代码引入数据是有用的。
存储过程和应用代码
软件开发者经常会纠结的一个问题是,一类业务逻辑是应该放到存储过程实现,还是放在应用代码中实现?
将业务逻辑放到存储过程实现,开发者担心会对数据库产品产生依赖。存储过程的语法并没有一套 SQL 标准,数据库厂商对于存储过程都有自己的语法定义和特殊实现。如果以后业务访问流量和数据量上涨,需要对数据库进行分布式改造,那还需要将存储过程再转换成应用代码。很多具有互联网行业从业经验的开发者,一般都会有这样的担心。
一些大型互联网公司,在刚起步时因为人力投入不足和业务流量也可控,选择将业务逻辑放到存储过程实现,快速构建起了早期的产品业务架构。当业务发展到一定规模后,因为业务架构已不适用和商业数据库支付成本等问题,不得已将存储过程再转换成应用代码。此后更是确立研发规章,要完全抛弃数据库存储过程,就像是患上了“存储过程恐惧症”。
而在传统IT行业里面,有些软件厂商倒是不怎么排斥使用存储过程,主要有几点原因:
- 基于存储过程的应用软件产品,更具有通用性。对于客户的定制化需求,只需要在客户现场新增或修改存储过程实现,并不需要去修改代码发布版本。
- 应用软件产品的通用性越高,业务覆盖的客户越多,企业发展也越好。
- 应用软件产品的通用性越高,需要雇佣的软件开发者也更少,因为不需要频繁地去修改代码发布版本。
- 培养和雇佣一个会写存储过程的工作人员,人力成本往往比一个软件开发者要低。
面向对象编程
在软件开发者群体中,面向对象的编程思想是非常受到欢迎的。当他们构造完一个接口或抽象类后,往往都会产生一种发自内心的欣喜之情,恨不得立刻要告诉全世界:快看,我刚刚构造了一个多么完美的抽象类,以后老板再让我实现相关的业务需求时,我就只需要轻松添加一个具体实现的类就可以了!
但是,不管面向对象的编程思想是多么的先进,最后,你还是需要修改代码发布版本才能满足新的业务需求。
代码即数据
PostgreSQL 的过程语言赋予了软件开发者一种新的能力,你可以在数据库中使用常规的编程语言实现业务逻辑。甚至,你还可以结合数据库关系模型的基础能力,应用面向对象的编程思想。
下面我们用一个示例,介绍如何基于面向对象的编程思想,将代码存放在数据库中:
CREATE DOMAIN scheme_code AS TEXT CHECK(VALUE ~ '^\(.*\)$');
CREATE FUNCTION calc(code scheme_code, x numeric)
RETURNS numeric
AS $$
(apply (eval (read (open-input-string code)))
(list x))
$$ LANGUAGE plscheme;
CREATE TABLE shape (
type text,
length scheme_code,
area scheme_code
);
其中表shape
包括的列如下:
名称 | 描述 |
---|---|
type |
形状的名称 |
length |
计算形状的长度的代码 |
area |
计算形状的面积的代码 |
我们可以将各种形状的相关信息插入到数据表shape
。
type | length | area |
---|---|---|
triangle | (lambda (x) (* x 3)) | (lambda (x) (/ (* x x) 2)) |
square | (lambda (x) (* x 4)) | (lambda (x) (* x x)) |
circle | (lambda (r) (* 2 3.14 r)) | (lambda (r) (* 3.14 r r)) |
有关 PL/Scheme 的更多详细信息,请参阅 PL/Scheme 文档。