我了解到 PostgreSQL 是用 C 编写的。我想扩展它
- 自定义索引结构
- 定制的最近邻检索(具有各种距离函数)
- 自定义数据类型
到目前为止,我一直害怕使用 PostgreSQL,因为它是用 C 编写的。但是,我在 PostgreSQL 的关于页面 ( http://www.postgresql.org/about/ ) 上看到它们支持“库接口”,例如用于 Java。因此,我可以使用 Java 来实现(至少)最近邻检索和自定义数据类型(我猜不是索引结构,因为它非常低级)?
我了解到 PostgreSQL 是用 C 编写的。我想扩展它
到目前为止,我一直害怕使用 PostgreSQL,因为它是用 C 编写的。但是,我在 PostgreSQL 的关于页面 ( http://www.postgresql.org/about/ ) 上看到它们支持“库接口”,例如用于 Java。因此,我可以使用 Java 来实现(至少)最近邻检索和自定义数据类型(我猜不是索引结构,因为它非常低级)?
这里的答案是“这很复杂”。实际上,您可以使用过程语言(包括 pl/java)走得更远,但您永远无法获得使用 C 可以获得的灵活性。从根本上缺少的是能够在 PL/Java 中提供适当的索引支持,因为一个不能创建新的基元。更多信息,您可能想查看我的博客,尽管大多数示例都在 pl/pgsql 中。
类型
现在,您实际上可以使用 PL/Java(或 PL/Perl,或 PL/Python,或任何您喜欢的东西)走得很远,但有些事情将是遥不可及的。这也是对 db 中的过程语言可以实现什么以及不可以实现什么的一个非常高的概述。
有两种有效的方法可以处理过程语言中的类型。您可以使用域(基元的子类型),也可以使用复杂类型(具有属性的对象,每个属性都是另一种类型,可以是基元、域或复杂类型本身)。一般来说,在索引复杂类型本身方面你不能做太多事情,但你可以索引它们的成员。另一件不安全的事情是输出格式,但您可以提供其他功能来替换它。
例如,假设我们想要一个类型来存储 PNG 文件并为数据库中的某些属性处理它们。我们可以通过以下方式做到这一点:
CREATE DOMAIN png_image as bytea check value like [magic number goes here];
然后我们可以创建一堆存储过程来以各种方式处理 png。例如,我们可能会在函数 is_sunset 的顶部附近寻找橙色。我们也许可以这样做:
SELECT name FROM landmark l
JOIN landmark s ON (s.name = 'San Diego City hall'
and ST_DISTANCE(l.coords, s.coords) < '20')
WHERE is_sunset(photo)
ORDER BY name;
没有理由不能用 Java、Perl 或任何您喜欢的语言处理 is_sunset。由于 is_sunset 返回一个布尔值,我们甚至可以:
CREATE INDEX l_name_sunset_idx ON landmark (name) where is_sunset(photo);
这将通过允许我们缓存日落照片名称的索引来加快查询速度。
在 Java 中你不能做的是创建新的原始类型。请记住,诸如索引支持之类的东西处于原始级别,因此,例如,您不能创建支持 GiST 索引的新 IP 地址类型(这不是您需要的,因为 ip4r 可用)。
因此,在您可以重用和使用已经存在的原语的范围内,您可以使用 Java 或任何您喜欢的方式进行开发。您实际上只受到可用原语的限制,并且有足够多的人用 C 编写了新的原语,您可能根本不需要接触这些原语。
索引
索引代码几乎只是 C 原语。您不能在过程语言中自定义索引行为。您可以做的是使用其他开发人员的原语等等。这是您最有可能不得不降到 C 的区域。
(更新:在我看来,可以使用CREATE OPERATOR CLASS
andCREATE OPERATOR
命令挂钩到现有的索引类型,以添加对基于其他 PL 函数的各种索引的支持。虽然我没有这样做的经验。)
表现
请记住,PL/Java 意味着您在每个后端进程中运行一个 JVM。在许多情况下,如果您可以在 pl/pgsql 中执行您想做的事情,您将获得更好的性能。当然,其他语言也是如此,因为您需要在后端进程中使用解释器或其他环境。