令我大吃一惊(而且令人担忧)的是,我刚刚意识到我的表有数百万行,只有几行,其中主键 (ID) 是重复的!我不明白这怎么会发生,以及我将来如何防止它?
保存主键的列是,并且一直受制于 CONSTRAINT fruits_pkey PRIMARY KEY(id);
我在 ubuntu 上运行 postgreql 9.3.4。
更新
@Mat:数据类型是integer
@ypercube:是的,select count(*) from (select count(*) from fruits group by id having count(*) > 1) as t1返回41。
@Craig:是的,我之前做过故障转移,我的slave实际上是9.3.3
我有一个巨大的整数数组列表(300,000,000 条记录)存储在 Postgres 9.2 DB 中。我想有效地搜索这些记录以获得完全匹配(仅相等)。我听说过 intarray 模块和相应的 gist-gin 索引。我想问以下问题:
我已经看到了使用此示例进行批量插入的好方法:
WITH p AS (
INSERT INTO parent_table (column_1)
SELECT $1
RETURNING id)
INSERT INTO child_table (parent_table_id, column_a)
SELECT p.id, a
FROM p, unnest($2::text[]) AS a
Run Code Online (Sandbox Code Playgroud)
但是,我需要从多个数组中插入多行,所以我尝试了以下语法:
WITH p AS (
INSERT INTO parent_table (column_1)
SELECT $1
RETURNING id)
INSERT INTO child_table (parent_table_id, column_a, column_b)
SELECT p.id, a, b
FROM p, unnest($2::text[]) AS a, unnest($3::bigint[]) AS b
Run Code Online (Sandbox Code Playgroud)
我在parent_table_idand上有一个主键column_a,当我尝试执行此查询时,Postgres 抱怨重复键冲突。
应该如何解开数组以便它们形成单独的行?
换句话说,如果$2和$3都有两个条目,那么第一个条目如何$2只插入第一个条目,$3并且对于各自的第二个条目都相同?
如果这是不可能的,我可以构造一个多维数组吗?如果是这样,它应该如何与多种数组类型一起传递,多维数组语法是什么?
我在 Postgres 中有多个用户。我想为不同的用户设置不同的语句超时。
例如:访客 5 分钟,管理员 10 分钟。
在 Postgres 11.11 中可以吗?
我正在尝试在 Centos 8 上设置 Postgres 12。Postgres 应安装在默认目录 ie 中/var/lib/pgsql,但是我希望数据目录位于/data/pgsql
我想使用 postgresql-setup 作为 root,因为我相信它会随之创建 systemd 服务文件,而不是使用 pg_ctl 或作为 postgres 用户运行 initdb。
但是,如果我尝试
$ postgresql-setup --initdb --pgdata=/data/pgsql/
Run Code Online (Sandbox Code Playgroud)
我将收到以下错误。
postgresql-setup: unrecognized option '--pgdata=/data/pgsql'
FATAL: can't parse arguments
Run Code Online (Sandbox Code Playgroud)
实现这一目标的最佳方法是什么?
许多 PostgreSQLALTER TABLE命令(例如添加具有默认值的新列)在最新版本的 PostgreSQL 中进行了巧妙的优化,一旦 Postgres 短暂获取了表上的锁,即使在大型表上,它们也能基本上立即执行。
不幸的是,最后的警告很重要。链接博客文章中类似这样的命令
ALTER TABLE users ADD COLUMN credits bigint NOT NULL DEFAULT 0;
Run Code Online (Sandbox Code Playgroud)
仍然需要等待表上的独占锁users才能运行,尽管一旦获取锁就会立即执行。更糟糕的是,当它等待该锁时,它会阻止涉及该表的所有写入和读取。
重现此问题的一些简单步骤(在 Postgres 13.3 中测试):
在一个psqlshell 中,创建一个表,然后启动一个事务,从表中进行读取,但不提交:
CREATE TABLE users (id SERIAL, name TEXT);
INSERT INTO users (name) VALUES ('bob'), ('fred');
START TRANSACTION;
SELECT * FROM users WHERE id = 1;
Run Code Online (Sandbox Code Playgroud)
让第一个 shell 打开,然后打开第二个 shell 并尝试更改表:
ALTER TABLE users ADD COLUMN credits bigint NOT NULL DEFAULT 0;
Run Code Online (Sandbox Code Playgroud)
请注意,此查询挂起,等待第一个 shell …
我在 PostgreSQL 13 中有下表:
field type
----- ----
Seq bigserial
code varchar
Run Code Online (Sandbox Code Playgroud)
Seq是主键(自增)
Code是唯一键索引
Insert Into newtable (Code) Values ('001') On Conflict(Code) Do Nothing --> Seq value is 1
Insert Into newtable (Code) Values ('001') On Conflict(Code) Do Nothing
Insert Into newtable (Code) Values ('001') On Conflict(Code) Do Nothing
Insert Into newtable (Code) Values ('002') On Conflict(Code) Do Nothing --> Seq value is 4
Run Code Online (Sandbox Code Playgroud)
为什么是序列4?有什么方法可以仅在成功插入时增加价值?
在 Postgres 中,如果超过 99.9% 的时间记录存在并且没有执行任何操作,则执行 \xe2\x80\x9cINSERT\xe2\x80\xa6 ON CONFLICT DO NOTHING\xe2\x80\x9d 是否效率低下?
\n例如让\xe2\x80\x99s 说我有一个节点进程,它获取映射到行的 100k 记录,其中 99,980 条已经存在。我可以:
\n第一种方法是最简单的,但我想知道它对于 Postgres 来说是否效率太低。我读到它在这样的 \xe2\x80\x9cdo Nothing\xe2\x80\x9d 情况下增加序列号,但是如果我跳过使用序列并使用我的唯一字段作为主(字符串)键,那可以吗? ?
\n在https://www.enterprisedb.com/downloads/postgres-postgresql-downloads上:
PostgreSQL 可在所有主要操作系统上运行,包括 Linux、UNIX(AIX、BSD、HP-UX、macOS、Solaris)和 Windows。它提供以下编程语言:PL/pgSQL、PL/SQL、Java、Python、Ruby、C/C+、PHP、Perl、Tcl、Scheme。Postgres 还提供以下库接口:OCI、libpq、JDBC、ODBC、.NET、Perl、Python、Ruby、C/C+、PHP、Lisp、Scheme 和 Qt。
我使用 PHP 和 PostgreSQL。我使用 PHP 扩展发送和接收数据pg_*,该扩展使用 libpq。我这样做已经有二十年了。
在列出“库接口”之前,PostgreSQL“提供”PHP 是什么意思?在“库接口”列表中,它再次令人困惑地列出了 PHP...
我错过了一些基本的东西吗?PostgreSQL 是否允许我将 PHP 语法混合到 SQL 查询或类似的疯狂的东西中?
EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS)
SELECT *
FROM contract
WHERE contract.id = 33129;
Run Code Online (Sandbox Code Playgroud)
EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS)
SELECT *
FROM contract
WHERE contract.id = 33129;
Run Code Online (Sandbox Code Playgroud)
EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS)
SELECT *
FROM contract
WHERE contract.id = 33128;
Run Code Online (Sandbox Code Playgroud)
Index Scan using contract_pkey on public.contract (cost=0.29..8.31 rows=1 width=305) (actual time=0.121..30.386 rows=1 loops=1)
Output: id, network, address, platform_id, sync_marker, props, sync_marker_alt, interface, ingested_at, data
Index Cond: (contract.id = 33129)
Buffers: shared hit=325
Planning Time: 0.098 ms
Execution Time: 30.412 ms
Run Code Online (Sandbox Code Playgroud)
请注意查询时间的巨大差异。分析输出中的唯一提示似乎是共享命中。 …
postgresql ×10
alter-table ×1
array ×1
btree ×1
bulk-insert ×1
centos ×1
gist-index ×1
locking ×1
performance ×1
php ×1
sequence ×1
upsert ×1
users ×1