SQL,限制可以添加的次数

SQL,限制可以添加的次数,sql,postgresql,Sql,Postgresql,我已经使用Postgresql制作了一个图书馆管理系统,我想限制学生/员工能够借阅的图书数量。如果有人想添加一个新的元组,其中一个学生/员工已经借了一本书,而该特定用户已经借了例如7本书,那么该表将不接受另一个添加。一般来说,SQL并不能让这变得容易。典型的解决方案如下: 为借来的每本书和学生保留一排桌子 在学生表中记录优秀书籍的数量 使用触发器维护此计数 在计数上添加检查约束 博士后确实有更方便的方法。一种方法是将借书列表存储为数组或JSON结构。唉,这不是一种关系格式。而且,它不允许声明

我已经使用Postgresql制作了一个图书馆管理系统,我想限制学生/员工能够借阅的图书数量。如果有人想添加一个新的元组,其中一个学生/员工已经借了一本书,而该特定用户已经借了例如7本书,那么该表将不接受另一个添加。

一般来说,SQL并不能让这变得容易。典型的解决方案如下:

  • 为借来的每本书和学生保留一排桌子
  • 学生
    表中记录优秀书籍的数量
  • 使用触发器维护此计数
  • 在计数上添加检查约束
博士后确实有更方便的方法。一种方法是将借书列表存储为数组或JSON结构。唉,这不是一种关系格式。而且,它不允许声明外键约束

这就是说,它确实允许对
books\u followed
列进行简单的
检查
约束,例如使用
cardinality()
。而且,验证阵列中是否没有重复项并不容易。另外,
INSERT
s、
UPDATE
s和
DELETE
s更为复杂


对于您的特定问题,我建议使用第一种方法。

根据我的说法,您需要从业务逻辑的角度处理此问题,即在插入之前检索特定学生的数据,然后采取行动

从基于规则的角度来看

  • 不要等待应用程序插入任何额外的行,但要不断观察表中的计数,当达到计数时,db会通知应用程序
  • 您可以基于 如果count_num_books>7,则特定用户使用的图书数量 然后,应用程序将处理它
  • 请看一下他们文件中提到的冲突

    您可以使用insert on conflict创建一个存储过程,并采取相应的操作

    INSERT INTO table_name(column_list) VALUES(value_list)
    ON CONFLICT target action;
    

    如前所述,进行此操作的最佳位置是应用程序检查。但在其他情况下,最简单的方法可能是什么都不做——即不要尝试保持活动签出的总数。由于Postgres对从表中选择触发器没有问题,因此触发器只会派生出已签出的未完成书籍。以下假设存在一个签出表:

    create table checkouts    
         ( checkout_id          serial
         , student_employee_id  integer not null
         , book_id              integer not null
         , out_date             date    not null
         , return_date          date    default null
         ) ; 
    
    然后在此表上创建一个插入行触发器,并调用以下命令:

     create or replace function limit_checkouts()
       returns trigger 
       language plpgsql
     as $$
     declare
        checkout_count integer; 
     begin
        select count(*)
          into checkout_count
          from checkouts c
         where c.student_employee_id = new.student_employee_id
           and returned_date is null ;
    
        if checkout_count > 7
        then 
            raise exception 'Checkout limit exceeded';
        end if;
    
        return new;
    end; 
    $$; 
    

    你可以用插入触发器来处理。但是,我会在程序逻辑中进行这种检查,而不是在SQL中进行这种检查。这不是她/他所要求的