我有一个 PostgreSQL 9.5 服务器,上面有自动为用户创建角色和数据库的脚本。在这些数据库中启用特定扩展(例如 pgcrypto)会很有帮助,但据我所知,必须是超级用户才能运行CREATE EXTENSION
. 有没有办法在不使用超级用户帐户手动登录的情况下启用此类扩展?
我有一个 PostgreSQL (9.4) 数据库,它根据当前用户限制对记录的访问,并跟踪用户所做的更改。这是通过视图和触发器实现的,并且在大多数情况下效果很好,但是我在需要INSTEAD OF
触发器的视图上遇到了问题。我试图减少问题,但我提前道歉,这仍然很长。
到数据库的所有连接都是通过单个帐户从 Web 前端建立的dbweb
。连接后,角色将通过SET ROLE
Web 界面更改为对应的人,所有此类角色都属于组角色dbuser
。(有关详细信息,请参阅此答案)。让我们假设用户是alice
。
我的大部分表都放置在一个架构中,在这里我将调用该架构private
并属于dbowner
. 这些表不能直接dbuser
被其他角色访问,但可以被其他角色访问dbview
。例如:
SET SESSION AUTHORIZATION dbowner;
CREATE TABLE private.incident
(
incident_id serial PRIMARY KEY,
incident_name character varying NOT NULL,
incident_owner character varying NOT NULL
);
GRANT ALL ON TABLE private.incident TO dbview;
Run Code Online (Sandbox Code Playgroud)
特定行对当前用户的可用性alice
由其他视图确定。一个简化的例子(可以减少,但需要以这种方式来支持更一般的情况)是:
-- Simplified case, but in principle could join multiple tables to determine allowed ids …
Run Code Online (Sandbox Code Playgroud) 我希望将大型 (100Mb -- 1 GB) 多通道时间序列数据导入 PostgreSQL 数据库。数据来自EDF 格式的文件,这些文件将数据分块成“记录”或“时期”,每个“记录”或“时期”通常为几秒钟。每个时期的记录将每个数据通道的信号保存为短整数的顺序数组。
我被要求将文件存储在数据库中,在最坏的情况下存储为 BLOB。鉴于此,我想研究可以让我对数据库中的数据做更多事情的选项,例如促进基于信号数据的查询。
我最初的计划是将数据存储为每个纪元记录一行。我想要权衡的是是否将实际信号数据存储为 bytea 或 smallint[](甚至 smallint[][])类型。有人可以推荐一个吗?我对存储和访问成本感兴趣。用法很可能是插入一次,偶尔读取,从不更新。如果一个更容易包装为自定义类型,以便我可以添加用于分析比较记录的函数,那就更好了。
毫无疑问,我缺乏细节,所以请随时对您希望我澄清的内容添加评论。
我无法让 INSTEAD OF 触发器正常工作,而且我想我误解了如何使用 NEW。考虑以下简化场景:
CREATE TABLE Product (
product_id SERIAL PRIMARY KEY,
product_name VARCHAR
);
CREATE TABLE Purchase (
purchase_id SERIAL PRIMARY KEY,
product_id INT REFERENCES Product,
when_bought DATE
);
CREATE VIEW PurchaseView AS
SELECT purchase_id, product_name, when_bought
FROM Purchase LEFT JOIN Product USING (product_id);
Run Code Online (Sandbox Code Playgroud)
我希望能够创建INSTEAD OF
触发器以允许我直接插入到 中PurchaseView
,例如:
INSERT INTO Product(product_name) VALUES ('foo');
INSERT INTO PurchaseView(product_name, when_bought) VALUES ('foo', NOW());
Run Code Online (Sandbox Code Playgroud)
我的想法是这样的:
CREATE OR REPLACE FUNCTION insert_purchaseview_func()
RETURNS trigger AS
$BODY$
BEGIN
INSERT INTO Purchase(product_id, when_bought) …
Run Code Online (Sandbox Code Playgroud) 这个问题已经出现过几次了,例如在postgresql 新闻组和wiki中。一般来说,不同interval
s 之间的关系可能没有明确定义 - 一个月可能有不同的天数,具体取决于所考虑的月份(和年份)。但有时需要计算两个时间点之间发生了多少个间隔,例如(简化示例):
CREATE TABLE recordings(tstart timestamp, tend timestamp, interval ticklength);
SELECT (tend - tstart) / ticklength AS numticks
FROM recordings;
Run Code Online (Sandbox Code Playgroud)
这在 PostgreSQL 中是不允许的,因为它是两个间隔之间的划分,由于上述原因,这不会有明确定义的一般行为。当间隔可以转换为秒时,存在一种解决方法,但如果不是这种情况,例如当间隔为毫秒量级时,最好的方法是什么?
在下面的示例中,我有一个表foo
,我想从中随机选择每组的一行。
CREATE TABLE foo (
line INT
);
INSERT INTO foo (line)
SELECT generate_series(0, 999, 1);
Run Code Online (Sandbox Code Playgroud)
假设我想按 分组line % 10
。我可以这样做:
SELECT DISTINCT ON (bin) bin, line
FROM (
SELECT line, line % 10 AS bin, random() x
FROM foo
ORDER BY x
) X
Run Code Online (Sandbox Code Playgroud)
我想做的是多次从每个垃圾箱中随机选择。我原以为我能和做到这一点generate_series()
,并LATERAL
SELECT i, line, bin
FROM
(
SELECT generate_series(1,3) i
) m,
LATERAL
(SELECT DISTINCT ON (bin) bin, line
FROM (
SELECT line, line % 10 bin, random() x …
Run Code Online (Sandbox Code Playgroud) 我的数据库中的许多表共享一个公共布局,特别是它们有一个serial
以关系名称命名的主键。从 Web 应用程序中更新这些表通常涉及以下形式的查询:
UPDATE table SET attribute = x WHERE table_id = y
Run Code Online (Sandbox Code Playgroud)
这很常见,以至于我有一个执行此任务的存储过程:
CREATE OR REPLACE FUNCTION setvalue(
relname text,
row_id integer,
colname text,
newvalue text)
RETURNS void AS
$BODY$
BEGIN
EXECUTE format('UPDATE %I SET %I = $1 WHERE %I = $2', relname, colname, relname || '_id', colname) USING row_id;
END;
$BODY$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不适用于非文本类型。例如,更新一date
列给出ERROR: column ... is of type date but expression is of type text
. 假设文本是预期类型的有效文字表示,是否有一种安全的方法让 DBMS 找出正确的类型并做正确的事情?
以下似乎可能是一种相当普遍的情况,但我还没有看到任何解决方案。
我有一个 PostgreSQL 数据库,其中包含特定于 的视图,$user
以便根据某些特定于数据库的 ACL 逻辑来限制数据。数据库通常通过 JDBC 访问,特别是在 Web 界面的 JSP 中。用户通过 LDAP 密码认证登录网站。
我想要的是利用从 JDBC 连接到数据库的视图。但通常这个中间层连接是使用通用用户创建的,而不是特定于登录网站的人。我相信在 Oracle 中“正确”的方法是Proxy Authentication,但 AFAIAA 没有与 PostgreSQL 等效的方法。那么该怎么做呢?
想到了一些想法:
还有其他(希望更好)的建议吗?
当人们希望用一个新的大对象替换一个大对象时应该怎么做。一个示例是使用新版本更新上传的文件。
一种方法大概是创建一个新的大对象,更新到新 oid 的链接,然后取消旧对象的链接。但是替换现有数据是否合理,例如,通过覆盖原始数据(可能首先截断内容)?
FWIW 我会在 JDBC 和 PostgreSQL 9.4 中这样做。
我有三个表,代表两个实体和一个连接关系。每个实体关系都有一个人工代理键,用于代替自然键的外键约束。
CREATE TABLE Person (
person_id SERIAL PRIMARY KEY,
username VARCHAR NOT NULL UNIQUE
);
CREATE TABLE Group (
group_id SERIAL PRIMARY KEY,
group_name VARCHAR NOT NULL UNIQUE
);
CREATE TABLE GroupMember (
person_id INTEGER REFERENCES Person,
group_id INTEGER REFERENCES Group,
PRIMARY KEY (person_id, group_id)
);
Run Code Online (Sandbox Code Playgroud)
我想在关系中插入多个条目GroupMember
,但使用关联实体的自然键。类似的东西:
INSERT INTO GroupMember (person_id,group_id)
SELECT person_id,group_id
FROM Person P, Group G, (
('alice','girls'),
('bob','boys'),
('alice','coolkids'),
('bob','coolkids')
) AS X
WHERE P.username = X.1 AND G.group_name = X.2;
Run Code Online (Sandbox Code Playgroud)
显然,上述语法无效,但希望能传达这个想法。有没有办法在 PostgreSQL 中做到这一点?
我有一个 Java/JDBC 程序,它获取一个示例文件并将数据导入数据库,将其分解为多个关系。该程序针对几种不同的表示多次执行此操作,其中一种使用大对象。我可以分享这些表示的更多细节,但它们很长并且与这个问题无关,因为我正在寻找一些通用的东西。
我想通过在每次导入后检查数据库的大小来比较这些不同表示的大小。该数据库位于 PostgreSQL 9.4 本地 Windows 服务器实例上,没有其他用户和默认配置。它的唯一目的是进行这个测试。
我最初的计划是这样的:
for each representation {
call VACUUM ANALYZE
record old DB size with SELECT pg_tablespace_size('pg_default');
import data into database
call VACUUM ANALYZE
record new DB size with SELECT pg_tablespace_size('pg_default');
store storage cost as new DB size - old DB size
}
Run Code Online (Sandbox Code Playgroud)
显然这种方法有局限性,但我的期望是对于大文件(~100MB),报告的存储成本应该是合理的近似值。请注意,我使用pg_tablespace_size
是为了包含主架构之外的数据的贡献,例如大对象(inpg_catalog.pg_largeobject
和pg_catalog.pg_largeobject_metadata
)。
我想知道这是否是一种正确的方法,以及是否有更好的方法。我不确定是否VACUUM ANALYZE
正确更新了 使用的统计信息pg_tablespace_size
,即使它是在同一会话中调用的。如果我可以避免调用VACUUM ANALYZE
,也会更好,因为这需要以超级用户身份连接才能运行pg_catalog
关系。
有什么想法吗?
postgresql ×11
jdbc ×3
blob ×2
plpgsql ×2
trigger ×2
bytea ×1
connections ×1
datatypes ×1
dynamic-sql ×1
insert ×1
join ×1
performance ×1
permissions ×1
random ×1
subquery ×1
syntax ×1
time ×1
view ×1