1

给定以下架构:

Table "public.users"
        Column        |           Type           |                         Modifiers
----------------------+--------------------------+------------------------------------------------------------
 uuid                 | uuid                     | not null default uuid_generate_v4()
 email                | character varying(254)   | not null
 name                 | text                     | not null
 created_at           | timestamp with time zone | not null default now()

Table "public.users_projects"
     Column      |           Type           |                 Modifiers
-----------------+--------------------------+--------------------------------------------
 project_uuid    | uuid                     | not null
 user_uuid       | uuid                     | not null
 invitation_uuid | uuid                     |
 membership_type | membership_type          | not null default 'member'::membership_type
 created_at      | timestamp with time zone | not null default now()

Table "public.projects"
   Column   |           Type           |              Modifiers
------------+--------------------------+-------------------------------------
 uuid       | uuid                     | not null default uuid_generate_v4()
 name       | character varying(100)   | not null
 created_at | timestamp with time zone | not null default now()

Table "public.invitations"
     Column      |           Type           |                 Modifiers
-----------------+--------------------------+--------------------------------------------
 uuid            | uuid                     | not null default uuid_generate_v4()
 email           | character varying(254)   | not null
 target_type     | character varying(50)    | not null
 target_uuid     | uuid                     | not null
 membership_type | membership_type          | not null default 'member'::membership_type
 token           | character varying(32)    | not null default md5((random())::text)
 creator_uuid    | uuid                     | not null

还有一个枚举类型CREATE TYPE membership_type AS ENUM ('guest', 'member', 'manager', 'owner');

我想知道是否可以使用触发器来验证用户不能创建对资源的邀请,而至少在manager联接表上没有成员资格类型。

我的主要问题是:

  • 我可以在插入行“之前”使用触发器吗?CREATE TRIGGER check_authorisation BEFORE INSERT OR UPDATE ON invitations FOR EACH ROW EXECUTE PROCEDURE check_authorisation();
  • 我可以在错误消息中返回多少信息,而不是因为数据库连接关闭等而失败
  • 这是一个理智的方法吗?作为一名 Web 应用程序开发人员,我习惯于在应用程序代码中检查这一点的环境,但我正在开发一个将由两个应用程序(Golang 和 Ruby)共享的数据库
  • 我可以以某种方式REFERENCES在多态字段(target_typetarget_uuid)上实现 a 吗?
4

1 回答 1

0

我可以在插入行之前使用触发器,在插入之前创建触发器 check_authorisation 或更新每个行执行过程的邀请 check_authorisation();

使其成为(之后)约束触发器,并在适当时引发异常。

更一般地,使用前触发器在需要时修改传入数据,使用后触发器传播副作用和约束触发器以验证完整性。

我可以在错误消息中返回多少信息,而不是因为数据库连接关闭等而失败

提出异常时,您想发送多少就发送多少。

这是一个理智的方法吗?作为一名 Web 应用程序开发人员,我习惯于在应用程序代码中检查这一点的环境,但我正在开发一个将由两个应用程序(Golang 和 Ruby)共享的数据库

如果做得好,它可能是理智的,但恕我直言,在授权方面,要正确管理所有奇怪的情况基本上是不可能的,所以这种类型的逻辑通常最好位于数据库之外。

举个例子:当经理的秘书的替代者(原来是休产假的)这样做时会发生什么?

我可以以某种方式在多态字段(target_type,target_uuid)上实现 REFERENCES 吗?

您可以使用后触发器。但根据您的操作,考虑使用单独的字段、外键和检查约束对其进行规范化,以确保它们是互斥的。它通常比最终手动重写外键逻辑更容易/更清洁。

于 2013-10-16T08:31:17.137 回答