在 jsonb 列和相同结构的复合类型列之间进行选择需要考虑哪些因素?
例如,考虑 Postgres 文档中使用的类似列:
CREATE TYPE inventory_item AS (
name text,
supplier_id integer,
price numeric
);
Run Code Online (Sandbox Code Playgroud)
这种方法与镜像这种结构的 jsonb 列之间的权衡是什么?
例如,我怀疑复合类型不需要存储每条记录的键名,而 jsonb 类型需要这样做。
postgresql database-design datatypes composite-types postgresql-10
在我的本地机器上,我刚刚升级到最新的 postgres.app 以获得版本 10。在此之前,我在 9.6 数据库上运行 pg_dumpall,然后在安装版本 10 后,我执行脚本以重新创建数据库、用户、等等...我还在从 dumpall 运行脚本并更新了一些日志记录设置后将 wal_level 更改为逻辑级别。
我首先在dot数据库中创建了一个订阅(作为超级用户)
bill=# \connect dot;
You are now connected to database "dot" as user "bill".
dot=# create publication foo for table dot.item;
CREATE PUBLICATION
Run Code Online (Sandbox Code Playgroud)
item 表中大约有 39k 行,所以同步数据应该不会花那么长时间。
接下来,我创建了一个新数据库dot2,该dot数据库由与该数据库相同的用户拥有,并在与dot数据库中存在的架构相同的模式中创建了一个空项目表,然后我尝试订阅另一个数据库中的发布(也作为超级用户)。
bill=# \connect dot2;
You are now connected to database "dot2" as user "bill".
dot2=# create subscription bar connection 'host=localhost port=5432 dbname=dot connect_timeout=10' PUBLICATION foo;
Run Code Online (Sandbox Code Playgroud)
然而,这只是挂起。它不会返回。
在我的日志中,我看到的只是这个......
2017-11-26 21:36:52.828 EST bill@dot2 54567 …Run Code Online (Sandbox Code Playgroud) 我正在阅读有关新的Postgres 10 标识列的信息,并了解了如何使用它SERIAL在CREATE TABLE.
是否也可以向现有表添加标识列?
例如,使用旧SERIAL列,我可以执行以下操作:
ALTER TABLE sourceTable ADD COLUMN ogc_fid SERIAL;
Run Code Online (Sandbox Code Playgroud)
对于标识列,是否有与上述相同的内容?我试过:
ALTER TABLE sourceTable ADD COLUMN ogc_fid GENERATED BY DEFAULT AS IDENTITY;
Run Code Online (Sandbox Code Playgroud)
但是得到了一个错误:
错误:“BY”第 1 行或附近的语法错误:...R TABLE sourceTable ADD COLUMN ogc_fid GENERATED BY DEFAULT
我正在考虑用我的脚本中的SERIAL列替换列IDENTITY,只是想检查这是否可行。
我使用 pg_upgrade(就地)升级了 Postgres DB 9.3.2-->10.5。我根据文档和 pg_upgrade 给出的说明做了一切。一切顺利,但后来我意识到索引没有在其中一个表中使用(也许其他表也受到影响)。
所以我ANALYZE昨天在那个桌子上开始了一个仍在运行的桌子上(超过 22 小时)......!
问题:ANALYZE执行时间这么长正常吗?
该表包含大约 30M 条记录。结构是:
CREATE TABLE public.chs_contact_history_events (
event_id bigint NOT NULL
DEFAULT nextval('chs_contact_history_events_event_id_seq'::regclass),
chs_id integer NOT NULL,
event_timestamp bigint NOT NULL,
party_id integer NOT NULL,
event integer NOT NULL,
cause integer NOT NULL,
text text COLLATE pg_catalog."default",
timestamp_offset integer,
CONSTRAINT pk_contact_history_events PRIMARY KEY (event_id)
);
ALTER TABLE public.chs_contact_history_events OWNER to c_chs;
CREATE INDEX ix_chs_contact_history_events_chsid
ON public.chs_contact_history_events USING hash (chs_id)
TABLESPACE pg_default;
CREATE INDEX ix_chs_contact_history_events_id
ON …Run Code Online (Sandbox Code Playgroud) postgresql performance index disaster-recovery postgresql-10
我在 Postgres 表中有一个jsonb列。它包含以下数据:datamy_table
[
{"id":"1","status":"test status1","updatedAt":"1571145003"},
{"id":"2","status":"test status2","updatedAt":"1571145323"}
]
Run Code Online (Sandbox Code Playgroud)
我想updatedAt使用一个查询更新该数组中所有对象的键。我试过:
update my_table set data = data || '{"updatedAt": "1571150000"}';
Run Code Online (Sandbox Code Playgroud)
上面的查询在数组中添加了一个新对象,如下所示:
[
{"id":"1","status":"test status1","updatedAt":"1571145003"},
{"id":"2","status":"test status2","updatedAt":"1571145323"},
{"updatedAt":"1571150000"}
]
Run Code Online (Sandbox Code Playgroud)
我想要的输出如下:
[
{"id":"1","status":"test status1","updatedAt":"1571150000"},
{"id":"2","status":"test status2","updatedAt":"1571150000"}
]
Run Code Online (Sandbox Code Playgroud)
我也尝试过jsonb_set(),但这需要第二个参数是数组索引。我无法确定数组中 JSON 对象的数量。
如果可以通过自定义函数解决这个问题,也很好。
我最近从 PostgreSQL 9.5 升级到 PostgreSQL 10。PostgreSQL 10 中的一个漂亮特性是新的标识列类型,它是 PostgreSQL串行伪类型的替代品。身份栏的官方文档可以在CREATE TABLE一页中找到。
但是,当将多行插入到带有GENERATED BY DEFAULT AS IDENTITY列的表中并使用关键字DEFAULT获取下一个 ID 值时,默认值返回为null.
例如,假设我有一张桌子
CREATE TABLE test (
id int GENERATED BY DEFAULT AS IDENTITY,
t text
);
CREATE TABLE
Run Code Online (Sandbox Code Playgroud)
使用DEFAULT关键字插入单行似乎工作正常。
INSERT INTO test (id, t) VALUES (DEFAULT, 'a');
INSERT 0 1
Run Code Online (Sandbox Code Playgroud)
插入多行不会。
INSERT INTO test (id, t) VALUES (DEFAULT, 'b'), (DEFAULT, 'c');
ERROR: null value in column "id" violates …Run Code Online (Sandbox Code Playgroud) 上下文正在从其余服务器连接到 Postgres 数据库。
考虑一个假设的代表性示例:我希望能够获取帐户创建日期比任意值早/新的名称列表。
在下面的示例查询中,表结构很简单 -name是 type text,并且creation_date是 type timestamp。所以当我做类似的事情时
server_pg_module:query("select name from new_table where
current_timestamp - creation_date < '6 days'")
Run Code Online (Sandbox Code Playgroud)
它工作得很好。但我真正想做的是6 days从服务器获取该值。所以我尝试像
server_pg_module:query("select name from new_table where
current_timestamp - timestamp < $1", ["6 days"]
Run Code Online (Sandbox Code Playgroud)
它抛出一个错误。我试过'6 days',"'6 days'"以及其他一些混合物,都抛出错误。所以为了检查我添加了一个新interval的类型列interval并尝试了一个查询
server_pg_module:query("insert into new_table (name, interval) values ($1, '3 day')", ["fooo"]).
Run Code Online (Sandbox Code Playgroud)
哪个有效,但是
server_pg_module:query("insert into new_table (name, interval) values ($1, $2)", ["fooo", "3 days"]).
Run Code Online (Sandbox Code Playgroud)
休息。为了更好的衡量,除了"'3 days'"上面提到的混合物之外,我还尝试过 …
我无法让我的第一个存储过程工作,所以我从手册中复制了这个例子:
CREATE PROCEDURE insert_data(a integer, b integer)
LANGUAGE SQL
AS $$
INSERT INTO tbl VALUES (a);
INSERT INTO tbl VALUES (b);
$$;
CALL insert_data(1, 2);
Run Code Online (Sandbox Code Playgroud)
我收到以下错误消息:
Run Code Online (Sandbox Code Playgroud)ERROR: syntax error at or near "PROCEDURE" LINE 1: CREATE PROCEDURE insert_data(a integer, b integer) ^ SQL state: 42601 Character: 8
我究竟做错了什么?
我在本地主机上运行数据库,以管理员用户身份运行。我自己安装的。安装过程无错误完成,我能够创建表、函数、触发器等。
PostgreSQL 版本:我的本地安装是 11.3,下面的小提琴是 10.0。两者的行为相同。
我有一个页面架构,每个页面都有部分,每个部分可以有不同类型的内容。当我查询某个页面时,我希望在 JSON 文档中输出有关该页面的所有信息。
我将 CTE 用于json_agg()每个部分的各种内容。最后,我将各个部分连接起来json_object_agg(),将部分标题映射到部分内容。
问题: json_object_agg()当页面没有任何部分时抛出错误。我已经通过使用没有章节标题的常规来验证有罪json_agg()。确切的错误:
error: field name must not be null
Run Code Online (Sandbox Code Playgroud)
我想要的:无论如何都不是错误。我不想在接收方进行自定义错误处理。如果查询可以返回 JSONNull来代替json_object_agg()没有部分的情况,那就更好了,但这是可选的。(欢迎其他优雅的解决方案)
文档
可能文档不完整或者我遗漏了一些东西。仅供参考。
在聚合表达式上它说(强调我的):
大多数聚合函数都会忽略 null 输入,因此一个或多个表达式产生null 的行将被丢弃。除非另有说明,对于所有内置聚合,这可以 假定为 true 。
在聚合函数中,json_object_agg()没有评论不处理null:
将名称/值对聚合为 JSON 对象
摆弄错误的域参数。将域更改为其他选项可以使其正常工作。使用不存在的域也可以正常工作并返回 0 行。
询问
with secs as (
select p.page_id, p.domain, s.section_id as sid, s.title as title
from pages p
left …Run Code Online (Sandbox Code Playgroud) 为什么我可以使用 UUID 对行进行排序:
SELECT uuid_nil()
ORDER BY 1;
Run Code Online (Sandbox Code Playgroud)
但我无法计算最大值:
SELECT max(uuid_nil());
Run Code Online (Sandbox Code Playgroud)
[42883] 错误:函数 max(uuid) 不存在
提示:没有函数与给定名称和参数类型匹配。您可能需要添加显式类型转换。
我知道我可以转换为字符类型 orORDER BY和LIMIT 1。我只是好奇为什么我必须使用解决方法。
postgresql ×10
postgresql-10 ×10
datatypes ×2
identity ×2
json ×2
aggregate ×1
alter-table ×1
errors ×1
index ×1
interval ×1
json-path ×1
max ×1
parameter ×1
performance ×1
replication ×1
update ×1
uuid ×1