Postgres 中的不变性

Has*_*sef 6 postgresql database-permissions

我想创建一个不可变的 Postgres 数据库,用户可以在其中插入和选择(写入和读取)数据,但无法更新或删除数据。

我知道FOR UPDATE锁,但不知道如何使用它。

举例来说,我有下表,如何使其不可变(或者,如果我理解正确,如何FOR UPDATE永久使用锁)

CREATE TABLE account(
 user_id serial PRIMARY KEY,
 username VARCHAR (50) UNIQUE NOT NULL,
 password VARCHAR (50) NOT NULL,
 email VARCHAR (355) UNIQUE NOT NULL,
 created_on TIMESTAMP NOT NULL,
 last_login TIMESTAMP
);
Run Code Online (Sandbox Code Playgroud)

Lau*_*lbe 9

解决方案是仅向访问数据库的用户授予所INSERT涉及SELECT表的权限。

锁不是拒绝某人访问的工具,而是防止同时发生冲突的数据修改的短期屏障。

这是一个例子:

CREATE TABLE sensitive (
   id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
   available text,
   restricted text
);
Run Code Online (Sandbox Code Playgroud)

现在我想允许someuser插入数据并读取和更新除 之外的所有列restricted,并且我想阻止自己删除该表中的数据:

/* the CREATE TABLE above was run by user "laurenz" */
REVOKE DELETE ON sensitive FROM laurenz;

GRANT INSERT ON sensitive TO someuser;
GRANT SELECT (id, available), UPDATE (id, available) ON sensitive TO someuser;
Run Code Online (Sandbox Code Playgroud)


dan*_*imo 0

不,该解决方案不起作用。我找到了这个。我在每行更新时在表上创建一个before触发器:

create or replace function table_update_guard() returns trigger
language plpgsql immutable parallel safe cost 1 as $body$
begin
  raise exception
    'trigger %: updating is prohibited for %.%',
    tg_name, tg_table_schema, tg_table_name
    using errcode = 'restrict_violation';
  return null;
end;
$body$;

create or replace trigger account_update_guard
before update on account for each row
execute function table_update_guard();
Run Code Online (Sandbox Code Playgroud)

请参阅我的原始研究