PostgreSQL 官方宣称它是世界上最先进的开源对象-关系型数据库管理系统(ORDBMS)。相信大家对于关系型数据库并不陌生,它基于关系模型(由行和列组成的二维表),定义了完整性约束并且使用 SQL 作为操作语言。
不过今天我们的主题不是关系模型,而是 PostgreSQL 提供的面向对象特性。面向对象编程(OOP)的三大特性包括数据封装、继承和多态,那么 PostgreSQL 作为对象-关系型数据库,有哪些面向对象的特性体现呢?
封装
OOP 将同类对象(Instance)封装成类(Class),并且提供方法保护数据的访问。例如以下 Java 示例:
publicclassMain{publicstaticvoidmain(String[] args){Person animal =newAnimal();
animal.setId(1);
animal.setName("大黄");System.out.println(animal.getId()+", "+ animal.getName());}}classAnimal{privateInteger id;privateString name;publicvoidsetId(Integer id){this.id = id;}publicStringgetId(){returnthis.id;}publicvoidsetName(String name){this.name = name;}publicIntegergetname(){returnthis.name;}publicvoideat(){System.out.println("The animal eats.");}}
其中,Animal 是一个类,包含 id 和 name 属性,并且通过 getter 和 setter 方法提供数据访问。
PostgreSQL 作为数据库,目的就是提供数据的存储和访问,其中的关系(表、索引、序列、视图、复合类型等)对应类,数据行对应对象,字段对应对象的属性。例如:
CREATETABLE animal(id integer, name varchar);INSERTINTO animal(id, name)VALUES(1,'大黄');SELECT id, name FROM animal;
PostgreSQL 使用 SQL 访问表中的数据,不同之处在于表中的字段都是 Public 属性。如果需要实现数据的隐藏,可以通过表的访问权限控制,或者利用存储过程提供数据访问方法。
PostgreSQL 提供了一个系统表 pg_class,存储了关于表、索引、序列、视图、复合类型等的元数据。
以下是一个空类,没有任何属性和方法:
classEmptyClass{}
与此类似,PostgreSQL 可以定义没有任何字段的空表:
CREATETABLE empty_table();
另外,PostgreSQL 不仅支持复杂的数据类型,例如几何、网络、数组、范围、XML、JSON 等,而且可以创建自定义的扩展类型。下面是一个自定义复合类型作为字段类型的示例:
CREATETYPE people AS(id integer, name varchar);CREATETABLE emp(p people);INSERTINTO emp(p)VALUES((1,'who'));SELECT(p).id,(p).name FROM emp;
id|name|--+----+1|who |
继承
OOP 通过继承让子类复用父类的数据和行为,从而实现代码的重用。例如:
publicclassCatextendsAnimal{privateInteger legs;@Overridepublicvoideat(){// 覆盖父类的方法System.out.println("The cat eats.");}...}
其中,Cat 类继承了 Animal 类,可以拥有额外的属性和方法。
PostgreSQL 同样支持表的继承,例如:
CREATETABLE cat(legs integer) INHERITS (animal);INSERTINTO cat(id, name, legs)VALUES(2,'橘猫',4);
数据表 cat 继承了数据表 animal,并且增加了额外的字段。
PostgreSQL 支持多继承,子表可以继承多个父表。
多态
OOP 另一个重要的特性是多态,它可以在运行时根据对象的实际类型来调用相应的方法。例如:
publicclassMain{publicstaticvoidmain(String[] args){Animal animal1 =newAnimal();
animal.eat();// 输出 "The animal eats." Animal animal2 =newCat();
animal2.eat();// 输出 "The cat eats."}}
其中,animal2 的实际类型为 Cat,调用 eat() 方法时,运行的是 Cat.eat(),而不是 Animal.eat()。
-- 查询全部动物SELECT id, name FROM animal;
id|name|--+----+1|大黄 |2|橘猫 |-- 只查询animalSELECT id, name FROM ONLY animal;
id|name|--+----+1|大黄 |-- 只查询猫科动物SELECT id, name FROM cat;
id|name|--+----+2|橘猫 |
另外,PostgreSQL 函数也支持重载(Overloading),也就是相同的函数名具有不同的函数参数。例如:
CREATEORREPLACEFUNCTION add2(p1 integer, p2 integer)RETURNSintegerAS $$
BEGINreturn p1+p2;END; $$
LANGUAGE plpgsql;CREATEORREPLACEFUNCTION add2(p1 numeric, p2 numeric)RETURNSnumericAS $$
BEGINreturn p1+p2;END; $$
LANGUAGE plpgsql;
版权归原作者 不剪发的Tony老师 所有, 如有侵权,请联系我们删除。