我正在构建一个应用程序,其中用户(已在另一个表中)可以拥有一组他们可以邀请到该位置的访问者。限制每个用户的行数(在访问者表中)的最佳方法是什么?
感谢您的建议。
答案 0 :(得分:0)
我建议 不 在数据库架构中处理此问题。相反,请在data model。
中处理它经验法则是 不 将业务规则强制执行到架构中;他们经常变化。相反,架构应该强制数据的完整性。例如,架构应确保每个邀请都与邀请用户,受邀用户和事件相关联。如果其中任何一个消失,邀请就会消失。这正在保护数据完整性。业务规则类似于“名称长度只能为20个字符”,鼓励过度使用name varchar(20)
之类的内容。
相反,请在数据模型中强制执行规则,例如User.add_invitation
。随着业务规则的变化,这将更容易修改,它将为尝试添加邀请失败的原因提供更好的错误消息,并且它将允许具有不同规则的不同应用程序使用相同的模式。
这假设更改数据库将通过一个模型。如果您有代码对数据库进行无可置疑的更改,那么在一个地方对业务规则进行编码可能是务实的:架构。
你没有说你正在使用什么数据库,所以我会为你做出一个很好的决定并假设它是Postgres。它具有很好的触发和约束功能。 (我看到你在MS SQL Server上,代码应该非常相似。)
如果您决定在架构中执行此操作,那么如果邀请太多,您可能需要before insert
trigger raises an exception。
假设您有一个包含用户,事件和邀请的架构。
create table users (
id bigserial primary key,
name text not null,
...whatever...
);
create table events (
id bigserial primary key,
...whatever...
);
create table event_invitations (
host bigint references user(id),
guest bigint references user(id),
event bigint references events(id)
);
每个用户一次只能邀请10个人参加活动。为此,如果已有10个邀请,您将使用before insert
触发器来阻止插入。我的pl/pgsql有点生疏,但它是这样的:
create function limit_event_invitations_to()
returns trigger as $$
declare
invitations_count integer;
begin
select count(*) into invitations_count
from event_invitations
where host = NEW.host and event = NEW.event;
if invitations_count > TG_ARGV[0] then
raise 'User %d has too many invitations to event %d', NEW.host, NEW.event
using errcode = 'check_violation';
end if;
return NEW;
end;
$$ language plpgsql;
create trigger limit_event_invitations
before insert on event_invitations
for each row execute procedure limit_event_invitations_to(10);
基本上计算一个用户已经为一个事件发出了多少个邀请,如果它超过了限制,则会引发异常。这应该非常快,因为它只是索引外键查找。
我选择使用the check_violation
error code因为它与你正在做的最接近。这使您可以检测特定类型的异常,而无需解析错误消息。