回顾 PostgreSQL 的一些回归测试,我可以看到
SELECT x, x IS OF (text) AS is_text FROM q;
Run Code Online (Sandbox Code Playgroud)
这显然可以追溯到7.3
添加 IS OF / IS NOT OF 类型谓词 (Thomas)
是否支持这种形式。在我自己的代码中,我会写,
pg_typeof(x) = 'text'
Run Code Online (Sandbox Code Playgroud)
但我IS OF更喜欢。
架构:
CREATE TABLE traffic_hit (
id SERIAL NOT NULL PRIMARY KEY,
country VARCHAR(2) NOT NULL,
created TIMESTAMP WITH TIME ZONE NOT NULL,
unique BOOLEAN NOT NULL,
user_agent_id INTEGER NULL
);
CREATE TABLE utils_useragent (
id SERIAL NOT NULL PRIMARY KEY,
user_agent_string TEXT NOT NULL UNIQUE,
is_robot BOOLEAN NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
初始查询:
SELECT
traffic_hit.created::DATE AS group_by,
COUNT(*) FILTER(WHERE traffic_hit.unique) AS unique_visits,
COUNT(*) AS non_unique_visits
FROM
traffic_hit
LEFT JOIN utils_useragent ON traffic_hit.user_agent_id = utils_useragent.id
WHERE
traffic_hit.created >= '2016-01-01' AND
traffic_hit.created …Run Code Online (Sandbox Code Playgroud) 我安装了 postgresql 10,我想对其他用户隐藏用户/角色的名称。我搜索了其他帖子,有人建议:
REVOKE SELECT ON pg_catalog.pg_authid FROM public;
REVOKE SELECT ON pg_catalog.pg_auth_members FROM public;
Run Code Online (Sandbox Code Playgroud)
完成所有这些操作后,user1 无法深入了解用户的信息,(Error retrieving roles from the database server. ERROR: permission denied for relation pg_auth_members)但仍可以将它们全部列出,如下图所示

当然 user1 不是超级用户。
我已经测试过这个没有效果:
REVOKE SELECT ON pg_catalog.pg_roles FROM user1;
REVOKE SELECT ON pg_catalog.pg_user FROM user1;
Run Code Online (Sandbox Code Playgroud)
对此也进行了测试,但没有效果:
REVOKE SELECT ON pg_catalog.pg_authid FROM user1;
REVOKE SELECT ON pg_catalog.pg_auth_members FROM user1;
Run Code Online (Sandbox Code Playgroud)
如果我启动下一个语句,用户将无法登录并且一切都已损坏:
REVOKE SELECT ON pg_catalog.pg_roles FROM public;
REVOKE SELECT ON pg_catalog.pg_user FROM public;
Run Code Online (Sandbox Code Playgroud)
有没有办法实现这一目标?对我来说向其他用户隐藏用户的名称非常重要。
背景:我正在创建一个黑客 ctf(捕获标志)虚拟机。这是挑战之一......重点是避免用户可以看到“正确的数据库用户名”进行连接。这是他/她必须在数据库中查找提示和其他加密内容的内容。
编辑:“悲伤”的解决方法是创建数百个虚拟用户以“尝试隐藏”真实用户......但它必须是一个优雅的解决方案。有什么帮助吗?
在pg_repackRDS Postgresql 9.6.3 上运行时,其中一位编写者出现此故障:
ProgrammingError: permission denied for relation log_24034858
CONTEXT: SQL statement "INSERT INTO repack.log_24034858(pk, row)
VALUES(CASE WHEN $1 IS NULL THEN NULL ELSE (ROW($1.id)::repack.pk_24034858) END, $2)"
Run Code Online (Sandbox Code Playgroud)
但是pg_repack应该允许写入重新打包的表,为什么在这里失败?
我有一个专用架构extensions(PostgreSQL v 9.6.3),我打算在其中安装我的数据库的所有扩展。我想以某种方式禁止(或至少提醒)用户在没有指定特定架构的情况下安装扩展。
所以这应该失败
CREATE EXTENSION tablefunc;
Run Code Online (Sandbox Code Playgroud)
但这应该会成功:
CREATE EXTENSION tablefunc SCHEMA extensions;
Run Code Online (Sandbox Code Playgroud)
为此,我尝试创建事件触发器:
CREATE EVENT TRIGGER e010_verify_extension_schema_et
ON ddl_command_end
WHEN TAG IN ('CREATE EXTENSION')
EXECUTE PROCEDURE verify_extension_schema();
Run Code Online (Sandbox Code Playgroud)
在verify_extension_schema()功能上,我正在尝试使用pg_catalog.pg_event_trigger_ddl_commands(). 但是,该函数不会返回任何我可以用来检查是否已指定架构或与此相关的架构的任何内容...
有没有人有任何想法我怎么能做到这一点?
这可能是一个新手问题。但有时,我发现有必要使用诸如(SELECT * FROM A)在 SQL 中进行关系代数之类的东西(而不是使用关系A本身)。
例如,尝试在工作时,UNION两种关系A,并B具有相同的结构,下面
SELECT * FROM (A UNION B) t;
Run Code Online (Sandbox Code Playgroud)
生成语法错误(使用 PostgreSQL 9.x)。
ERROR: syntax error at or near "UNION"
Run Code Online (Sandbox Code Playgroud)
我不得不做
SELECT * FROM ((SELECT * FROM A) UNION (SELECT * FROM B)) t;
Run Code Online (Sandbox Code Playgroud)
我的问题是:
子查询的冗长性(SELECT * FROM A)在 SQL 语言中是否真的必要(或者我是否遗漏了一些更好的编写方式)?为什么这里不能直接使用A和关系B?
是(SELECT * FROM A)相当于A在关系代数?扩张(SELECT * FROM A)给我们带来了什么?什么时候需要长表格?
默认情况下,PostgreSQL 的money数据类型插入带有货币代码和分组的值。我观察到它总是用$.
尽管所有索引都已到位,但我的查询执行速度非常慢:
SELECT * FROM "entry"
INNER JOIN "entrytag" ON ("entry"."id" = "entrytag"."entry_id")
WHERE "entrytag"."tag_id" = 323456
ORDER BY "entry"."date"
DESC LIMIT 10'
Run Code Online (Sandbox Code Playgroud)
解释显示太多循环,为什么?如何解决这个问题?
Limit (cost=1241.85..1241.87 rows=10 width=666) (actual time=23576.449..23576.454 rows=10 loops=1)
-> Sort (cost=1241.85..1242.10 rows=99 width=666) (actual time=23576.446..23576.447 rows=10 loops=1)
Sort Key: entry.date DESC
Sort Method: top-N heapsort Memory: 31kB
-> Nested Loop (cost=0.87..1239.71 rows=99 width=666) (actual time=0.168..22494.187 rows=989105 loops=1)
-> Index Scan using entrytag_tag_id_row_idx on entrytag (cost=0.44..402.17 rows=99 width=4)
(actual time=0.093..535.664 **rows=989105** loops=1)
Index Cond: (tag_id = 323456)
-> …Run Code Online (Sandbox Code Playgroud) 我在 Postgres 表中有 6 列:
A1 character varying(5)[]
A2 character varying(5)[]
A3 int REFERENCES ... -- FK
B1 character varying(5)[]
B2 character varying(5)[]
B3 int REFERENCES ... -- FK
Run Code Online (Sandbox Code Playgroud)
我需要一个SELECT匹配的第一行是获胜者(限制为 1)并匹配 A 组和 B 组。
我知道 Postgres 不关心WHERE子句的顺序,我必须准备一个ORDER子句或找到不同的方法。
我想准备匹配优先级的查找,我的WHERE子句重要性如下:
highest priority: (A1 and B1) OR
. (A1 and B2 OR A2 and B1) OR
. (A1 and B3 OR A3 and B1) OR
. (A2 and B3 OR A3 and B2) OR …Run Code Online (Sandbox Code Playgroud) 我有一个类型为字段的表jsonb,我想为所有 json 键拆分字段 jsonb 的列。此列缺少架构。例如:
从
CREATE TABLE v(id,jsonb)
AS VALUES
(1,'{"a":"4", "b":"5"}'::jsonb),
(2,'{}'),
(3,'{"a":"8", "c":"9", "d":"9"}');
Run Code Online (Sandbox Code Playgroud)
到
id | a | b | c | d
1 | 4 | 5 | |
3 | 8 | | 9 | 9
Run Code Online (Sandbox Code Playgroud)
对于这种特定情况,一种解决方案是
select * from table, json_to_record(optional) as x("a" text, "b" text, "c" text, d text)
Run Code Online (Sandbox Code Playgroud)
如您所见,键可能会有所不同,并且在大型数据库中很难将所有键都放在我的实际问题中,我有 31 个键,另一方面,如果我想在其他表中重用此脚本,我必须手动填充键。
有没有办法在 jsonb 的所有键上进行选择而无需手动指定键?
postgresql ×10
performance ×2
amazon-rds ×1
datatypes ×1
ddl ×1
ddl-trigger ×1
dml ×1
index ×1
json ×1
money ×1
order-by ×1
permissions ×1
role ×1
select ×1
trigger ×1
users ×1