可以在 PostgreSQL 中创建原子事务吗?
考虑我有这些行的表类别:
id|name
--|---------
1 |'tablets'
2 |'phones'
Run Code Online (Sandbox Code Playgroud)
并且列名具有唯一约束。
如果我尝试:
BEGIN;
update "category" set name = 'phones' where id = 1;
update "category" set name = 'tablets' where id = 2;
COMMIT;
Run Code Online (Sandbox Code Playgroud)
我越来越:
ERROR: duplicate key value violates unique constraint "category_name_key"
DETAIL: Key (name)=(tablets) already exists.
Run Code Online (Sandbox Code Playgroud) 我有一个以这种方式创建的表:
--
-- Table: #__content
--
CREATE TABLE "jos_content" (
"id" serial NOT NULL,
"asset_id" bigint DEFAULT 0 NOT NULL,
...
"xreference" varchar(50) DEFAULT '' NOT NULL,
PRIMARY KEY ("id")
);
Run Code Online (Sandbox Code Playgroud)
稍后插入一些行并指定 id:
INSERT INTO "jos_content" VALUES (1,36,'About',...)
稍后,一些记录被插入而没有 id 并且它们因错误而失败:
Error: duplicate key value violates unique constraint。
显然,id 被定义为一个序列:

每个失败的插入都会增加序列中的指针,直到它增加到一个不再存在的值并且查询成功。
SELECT nextval('jos_content_id_seq'::regclass)
表定义有什么问题?解决这个问题的聪明方法是什么?
我最近想与服务器的一个用户共享定期访问权限和我认识到,一个简单的CREATE USER和GRANT ALL ON DATABASE命令没有让他运行一个简单SELECT的数据。
我想将给定数据库中所有表的权限授予指定用户,但我不确定授予他对整个架构的访问权限是否是最好的主意,public因为我不知道这是否允许某种特权升级。有没有其他办法?
我知道如何检查 Postgres 中索引和表的大小(我使用的是 9.4 版):
SELECT
relname AS objectname,
relkind AS objecttype,
reltuples AS "#entries", pg_size_pretty(relpages::bigint*8*1024) AS size
FROM pg_class
WHERE relpages >= 8
ORDER BY relpages DESC;
Run Code Online (Sandbox Code Playgroud)
但这并没有显示物化视图。如何查看它们占用了多少磁盘空间?
我在列a和b. 我需要这样的东西:
insert into my_table (a, b) values (1, 2), (1, 2)
on conflict (a) do update set c = 'a_violation'
on conflict (b) do update set c = 'b_violation'
Run Code Online (Sandbox Code Playgroud)
所以一般我想根据冲突目标进行不同的更新 - 不支持上面的语法(只支持一个on conflict语句)。有没有其他方法可以做到这一点?
我有一个包含大量插入内容的表,将其中一个字段 ( uploaded_at) 设置为NULL. 然后周期性任务选择所有元组WHERE uploaded_at IS NULL,处理它们并更新,设置uploaded_at为当前日期。
我应该如何索引表?
我知道我应该使用部分索引,例如:
CREATE INDEX foo ON table (uploaded_at) WHERE uploaded_at IS NULL
Run Code Online (Sandbox Code Playgroud)
或者像那样。我有点困惑,但如果在始终为NULL. 或者如果使用 b 树索引是正确的。Hash 看起来是一个更好的主意,但它已经过时并且不能通过流式热备复制进行复制。任何建议将不胜感激。
我对以下索引进行了一些试验:
"foo_part" btree (uploaded_at) WHERE uploaded_at IS NULL
"foo_part_id" btree (id) WHERE uploaded_at IS NULL
Run Code Online (Sandbox Code Playgroud)
并且查询平面似乎总是选择foo_part索引。索引的explain analyse结果也稍好一些foo_part:
Index Scan using foo_part on t1 (cost=0.28..297.25 rows=4433 width=16) (actual time=0.025..3.649 rows=4351 loops=1)
Index Cond: (uploaded_at IS NULL)
Total runtime: 4.060 ms
Run Code Online (Sandbox Code Playgroud)
对比 …
考虑一个prices包含这些列的表:
id integer primary key
product_id integer -- foreign key
start_date date not null
end_date date not null
quantity integer
price numeric
Run Code Online (Sandbox Code Playgroud)
我希望数据库强制执行这样的规则,即产品在日期范围内(通过where <date> BETWEEN start_date AND end_date)的特定数量只能有一个价格。
这种基于范围的约束可行吗?
postgresql database-design exclusion-constraint postgresql-9.4
我一直在我的一个 PostgreSQL 数据库中使用数组。
我创建了一个包含至少一个元素的几何数组的表:
CREATE TABLE test_arrays (
polygons geometry(Polygon,4326)[],
CONSTRAINT non_empty_polygons_chk
CHECK ((COALESCE(array_length(polygons, 1), 0) <> 0))
);
Run Code Online (Sandbox Code Playgroud)
我添加了几行,并在表中查询每个几何数组中的第一个元素:
SELECT polygons[0] FROM test_arrays;
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,我得到了一个空行列表!
经过一些研究,事实证明PostgreSQL 数组是基于一个的:
数组下标数字写在方括号内。默认情况下,PostgreSQL 使用基于 1 的数组编号约定,即 n 个元素的数组以 array[1] 开头,以 array[n] 结尾。
所以SELECT polygons[0] FROM test_arrays;工作并返回polygon每一行的第一行。
如果 PostgreSQL 使用基于 1 的编号约定,为什么允许查询第 0 个元素,结果是否有任何意义?
可以CURRENT_TIMESTAMP用作PRIMARY KEY?
是否有可能两个或多个不同的 INSERT 得到相同的结果CURRENT_TIMESTAMP?
我在PostgreSQL 教程上读到了这篇文章:
如果您想从存储过程返回值,可以使用输出参数。输出参数的最终值将返回给调用者。
然后我发现DZone的函数和存储过程之间存在差异:
存储过程不返回值,但存储函数返回单个值
谁能帮我解决这个问题。
如果我们可以从存储过程中返回任何内容,也请让我知道如何从SELECT主体内的语句中执行此操作。
如果我有错的地方请告知。
postgresql ×10
array ×1
disk-space ×1
duplication ×1
functions ×1
index ×1
index-tuning ×1
insert ×1
null ×1
permissions ×1
primary-key ×1
sequence ×1
timestamp ×1
transaction ×1
upsert ×1