PostgreSQL的数据类型

本文深入探讨PostgreSQL中的各种数据类型,包括serial、字符串、json、jsonb和XML的使用方法,以及如何进行数据查询、插入和转换。通过实例展示了不同数据类型的特性和优势,特别是jsonb类型的高性能特性。

1、serial类型

1)generate_series为数组生成函数,与sql中的for循环类似,例:

使用可选的步长形参来生成整数序列

2、字符串函数

1)填充(lpad、rpad)、修整空白(rtrim、ltrim、trim、btrim)、提取子字符串(substring)以及连接(||)

2)split_part函数可以将指定位置的元素从用固定分隔符分隔的字符串中提取出来,如:

3) string_to_array函数可以将基于固定分隔符的字符串拆分为一个数组。通过和unnest函数结合使用,可以将一个字符串展开为若干记录行,如:

2.1、正则表达式和模式匹配

1)使用逆向引用技术对电话号码进行重新格式化

\\1和\\2是模式匹配表达式中的元素。反斜杠(\) 是转义圆括号,表示此处真的是要作为一个圆括号来用。E' 是postgresql的构造语法,表示后续跟着的字符串是一个表达式,其中类似 \  的特殊字符应该按照字面含义来处理。

2)将文本中的电话号码作为单独的行返回

其中,regexp_matches函数会返回根据一个正则表达式筛选匹配得到的字符串数组。如果不传入g形参,则仅返回第一个被命中的字符串。g表示global, 即需要进行完整搜索并返回所有匹配上的字符串,每一个字符串作为数组的一个元素。unnest函数将一个数组分解为一个行集。

3、json数据类型

1)要想在表中存储json数据,只需建一个json类型的字段即可,语法如下:

CREATE TABLE families_j (id serial PRIMARY KEY, profile json);

2)插入一条json数据记录:

INSERT into families_j(profile) VALUES ('{"name":"Gomez", "members":[{"member":{"relation":"padre","name":"Alex"}},{"member":{"relation":"madre","name":"Sonia"}},{"member":{"relation":"hijo","name":"Brandon"}},{"member":{"relation":"hija","name":"Azaleah"}}]}');

3.1、查询json数据

1)查询json数据块中的元素

SELECT json_extract_path_text(profile, 'name') as family,
 json_extract_path_text( json_array_elements( json_extract_path(profile,'members')    ),'member','name') as member FROM families_j;

① 提取出家庭的名称,以文本格式输出。

② 提取出家庭成员的名称,以文本格式输出。

③ 将家庭成员信息数组中的每个元素展开为独立的json对象。

④ 获取所有家庭成员的信息列表,作为一个独立的json对象输出。

2)运算符 ->> 和 #>> 是json_extract_path_text 的简写。#>> 取用某个路径数组。

使用运算符实现与按路径读取函数相同的功能

SELECT profile->>'name' AS family, json_array_elements((profile->'members')) #>>'{member,name}'::text[] AS member FROM families_j;

json_extract_path 是 json_extract_path_text 是兄弟函数,它对应的运算符是 -> 和 #>。

3)你可以级联使用多个运算符来定位到json对内部的某个子对象

查询members对象的子对象

SELECT id,json_array_length(profile->'members') AS numero, profile->'members'->0#>>'{member,name}'::text[] AS primero from families_j;

上面使用了->运算符的两种形式。-> 运算符的返回结果永远是一个json或者jsonb对象,但该运算符的第二个实参要么是一个text字段(josn_object_element的简写)。因此profile->'members'会返回json对象的members字段,该字段本身含有多条记录的json数组。->0操作提取出了json对象数组的首个元素。在本例中,->0得到的是首个家庭成员的信息。#>>'{member,name}'::text[] 就是json_extract_path_text操作,得到的结果是首个家庭成员json对象中按照“member/name” 路径寻址到的节点的文本格式的值。

3.2、输出json数据

postgresql除了可以查询库中已有的json数据外,还支持将别的数据类型转换为json类型。

示例:将多条记录转换为单个json对象(postgresql9.3及之后的版本才支持该语句)

SELECT row_to_json(f) AS x FROM (SELECT id, profile->>'name' AS name FROM families_j) AS f;

如果要将families表中的所有记录行整体打包转换为一个json对象,可以使用以下语法(postgresql9.2及之后的版本均支持该语法):

SELECT row_to_json(f) FROM families_j AS f;

“查询时将一行记录作为单个字段输出”这种功能只有postgresql才支持。该功能对于创建复合json对象特别有用。

3.3、json类型的二进制版本:jsonb

1)jsonb的性能远好于json。因为jsonb类型在处理过程中不需要再进行文本解析。

jsonb类型由于是解析过的二进制结构,因此jsonb类型的字段上可以直接建立GIN索引

为了更好区别与json类型的不同,新建一张表:

CREATE TABLE families_b (id serial PRIMARY KEY, profile jsonb);

插入数据:

INSERT into families_b(profile) VALUES ('{"name":"Gomez", "members":[{"member":{"relation":"padre","name":"Alex"}},
{"member":{"relation":"madre","name":"Sonia"}},{"member":{"relation":"hijo","name":"Brandon"}},
{"member":{"relation":"hija","name":"Azaleah"}}]}');

示例:jsonb与json类型输出格式对比

SELECT profile as b from families_b WHERE id=1;

SELECT profile as j from families_j WHERE id=1;

① jsonb类型的输出是对输入的内容进行了重新格式化并删掉了输入时文本中的空格,此外relation和name这两个属性字段的显示顺序相比发生了翻转。

② json类型的输出保持了输入时的原样,包括原文文本中的空格以及属性字段的顺序。

2)jsonb比json多支持的运算符有以下几个:等值运算符(=)、包含关系运算符(@>)、被包含关系运算符(<@)、键值已存在运算符(?)、一组键值中是否有任意一个已存在运算符(?|)、一组键值中的每一个是否均已存在运算符(?&)。

示例:jsonb包含关系运算符的使用

SELECT profile->>'name' as family FROM families_b WHERE profile @> '{"members":[{"member":{"name":"Alex"}}]}';

如果在jsonb列上建了GIN索引,那么前述这几个运算符的操作速度是极快的:

CREATE INDEX idx_familes_jb_profile_gin ON families_b USING gin (profile);

4、XML数据类型

1)插入XML字段记录

CREATE TABLE families (id serial PRIMARY KEY,profile xml);

INSERT INTO families(profile) VALUES('<family name="Gomez">
        <member><relation>padre</relation><name>Alex</name></member>
        <member><relation>madre</relation><name>Sonia</name></member>
        <member><relation>hijo</relation><name>Brandon</name></member>
        <member><relation>hija</relation><name>Azaleah</name></member>
        </family>');

2)你可以为XML字段设置一个check约束以确保输入的XML数据都符合某种格式。XPath是一种能够在XML树状结构中指定元素的语法。

示例:确保所有XML字段记录中都有至少一个member节点和一个relation节点

ALTER TABLE families ADD CONSTRAINT chk_has_relation CHECK (xpath_exists('/family/member/relation', profile));

3)查询XML数据

查询XML数据时,xpath函数会发挥重要的作用。该函数的第一个实参是一个XPATH查询表达式,第二个实参是一个XML对象。查询结果是xpath查询语句所要查找的XML元素的列表。

示例:

SELECT family,(xpath('/member/relation/text()', f))[1]::text AS relation,(xpath('/member/name/text()', f))[1]::text AS mem_name FROM  (SELECT (xpath('/family/@name', profile))[1]::text AS family,unnest(xpath('/family/member', profile)) as f from families) x;

 

 

 

 

PostgreSQL 支持多种数据类型,这些类型可以大致分为以下几类: ### 基本数据类型 - **数值类型**:包括整数、浮点数等。例如 `integer`、`bigint`、`smallint`、`decimal`、`numeric`、`real` 和 `double precision`。 - **字符类型**:用于存储文本数据,如 `char`、`varchar` 和 `text`。 - **日期和时间类型**:如 `date`、`time`、`timestamp` 和 `interval`,用于处理日期和时间数据[^2]。 ### 复合数据类型 - **枚举类型**:用户定义的类型,其值是从一个固定的列表中选择的。例如,可以定义一个 `gender` 类型,包含 `male` 和 `female`。 - **阵列类型**:允许字段存储一个数组,例如 `integer[]` 表示整数数组。 - **复合类型**:由多个字段组成的类型,类似于其他编程语言中的结构体或类[^2]。 ### 几何和地理空间数据类型 - **几何数据类型**:用于表示平面几何对象,如 `point`、`line`、`lseg`、`box`、`path`、`polygon` 和 `circle`。 - **地理空间数据类型**:用于存储地理空间数据,如 `geography` 类型,通常与 PostGIS 扩展一起使用[^2]。 ### JSON 和 XML 数据类型 - **JSON 数据类型**:支持存储 JSON 格式的数据,包括 `json` 和 `jsonb` 类型。`json` 保持输入的格式,而 `jsonb` 则以二进制形式存储,更适合查询和索引。 - **XML 数据类型**:用于存储 XML 文档,可以通过 `xml` 类型来实现。 ### 网络地址数据类型 - **IPv4 和 IPv6 类型**:如 `inet` 类型可以存储 IPv4 或 IPv6 地址。 - **网络掩码和网络类型**:如 `cidr` 类型用于存储 CIDR(无类别域间路由)地址块。 ### 位串数据类型 - **位串类型**:用于存储位串,如 `bit` 和 `bit varying`(或 `varbit`),可以用来表示固定长度或可变长度的位序列[^2]。 ### 用户自定义数据类型 - **创建自定义数据类型**:用户可以使用 `CREATE TYPE` 命令创建自己的数据类型。这可以是简单的类型别名,也可以是复杂的组合类型。 - **使用自定义数据类型**:一旦定义了自定义类型,就可以像内置类型一样在表定义中使用它们。 - **管理自定义数据类型**:用户还可以通过 `ALTER TYPE` 和 `DROP TYPE` 命令来修改或删除自定义类型。 ### 伪类型 - **伪类型**:这些类型不能作为表字段数据类型,但可以在函数定义中使用。例如 `anyelement`、`anyarray`、`anynonarray`、`anyenum`、`anyrange`、`cstring`、`internal`、`language_handler`、`record`、`trigger`、`void` 和 `opaque`。伪类型在一个函数不只是简单地接受并返回某种 SQL 数据类型的情况下很有用[^3]。 ### 示例代码 以下是一些 PostgreSQL 数据类型的示例定义: ```sql -- 创建一个包含多种数据类型的表 CREATE TABLE example_table ( id serial PRIMARY KEY, name varchar(100), age integer, salary numeric(10, 2), birth_date date, created_at timestamp, location point, tags text[], user_data jsonb, ip_address inet, bitmask bit(8) ); -- 插入数据 INSERT INTO example_table (name, age, salary, birth_date, created_at, location, tags, user_data, ip_address, bitmask) VALUES ( 'Alice', 30, 50000.00, '1990-01-01', NOW(), POINT(1.0, 2.0), ARRAY['tag1', 'tag2'], '{"name": "Alice", "age": 30}'::jsonb, '192.168.1.1', B'10101010' ); ``` ### 数据类型的性能考虑 选择适当的数据类型对于数据库性能至关重要。例如,使用 `integer` 而不是 `bigint` 可以节省存储空间;使用 `jsonb` 而不是 `json` 可以提高查询性能。此外,合理的数据类型选择还可以减少索引大小,提高查询效率。 ### 数据类型的转换和运算 PostgreSQL 支持隐式和显式的类型转换。隐式转换由数据库自动处理,而显式转换则需要使用 `CAST` 函数或类型转换操作符 `::`。例如: ```sql -- 显式类型转换 SELECT CAST('123' AS integer); SELECT '123'::integer; ``` ### 查看数据类型 可以通过查询系统目录表或使用 `\d` 命令来查看表的结构及其数据类型。例如: ```sql -- 查看表的结构 \d example_table ``` ### 修改数据类型 如果需要更改现有列的数据类型,可以使用 `ALTER COLUMN ... TYPE` 命令。例如: ```sql -- 修改列的数据类型 ALTER TABLE example_table ALTER COLUMN age TYPE bigint; ``` ### 删除数据类型 用户自定义的数据类型可以通过 `DROP TYPE` 命令删除。例如: ```sql -- 删除自定义数据类型 DROP TYPE custom_type; ``` ### 相关问题 1. 如何在 PostgreSQL 中创建和使用用户自定义数据类型? 2. 如何在 PostgreSQL 中进行数据类型转换? 3. 如何查看 PostgreSQL 表的结构及其数据类型? 4. 如何在 PostgreSQL 中修改现有列的数据类型? 5. 如何在 PostgreSQL 中使用 JSON 和 XML 数据类型
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值