Limit number of records using trigger and constraints in MySQL

最后都变了- 提交于 2019-12-13 04:03:20

问题


I have a table called BFFs, that stores userID, and best friend's userID and I would like to restrict that table to have exactly 3 number of best friends for each different user.

I mean if the table structre is:

BFFs(userID, userID)

and records are:

(3286, 1212)
(3286, 4545)
(3286, 7878)

And in that case, if user with ID 3286 should not be allowed to have a new record such as (3286, xyzt).

I wrote this trigger but I'm not sure:

CREATE TRIGGER BFFControl
BEFORE INSERT ON BFFs
FOR EACH ROW
DECLARE
    numberOfBFFs INTEGER;
    max_BFFs INTEGER := 3;
BEGIN
    SELECT COUNT(*) INTO numberOfBFFs
    FROM BFFs
    WHERE sender =: NEW.sender

    IF :OLD.sender =: NEW.sender THEN
        RETURN;
    ELSE
        IF numberOfBFFs >= max_BFFs THEN
            RAISE_APPLICATION_ERROR(-20000, 'Users are allowed to have at most thre friends.');
        END IF;
    END IF;
END;
/

How should I restrich this on relational tables through assertions or triggers ?

Thanks


回答1:


Add another column, FriendNumber and a Foreign Key constraint to a reference table with exactly 3 rows:

CREATE TABLE Three
( friendNumber TINYINT NOT NULL 
, PRIMARY KEY (friendNumber)
) ;

INSERT INTO Three(friendNumber) 
  VALUES
    (1), (2), (3) ;

CREATE TABLE BFFs
( userID       INT NOT NULL 
, friendID     INT NOT NULL
, friendNumber TINYINT NOT NULL
, PRIMARY KEY (userID, friendID)
, UNIQUE (userID, friendNumber)
, FOREIGN KEY userID
    REFERENCES Person(userID)
, FOREIGN KEY friendID
    REFERENCES Person(userID) 

, FOREIGN KEY friendNumber           --- this ensures that a user can have
    REFERENCES Three(friendNumber)   --- max of 3 friends
) ;

Then you can add:

INSERT INTO BFFs 
  (userID, friendID, friendNumber)
VALUES
  (3286, 1212, 1) ,
  (3286, 4545, 2) ,
  (3286, 7878, 3) ;

or as suggested by @gbn, to something like this (so the column is auto-filled):

INSERT INTO BFFs 
    (userID, friendID, friendNumber)
  SELECT 
       3286 AS userID
     , 8989 AS friendID
     , COALESCE(
         ( SELECT MIN(Three.friendNumber)
           FROM Three 
             LEFT JOIN BFFs AS b  
               ON  b.friendNumber = Three.friendNumber
               AND b.userID = 3286
           WHERE b.friendNumber IS NULL
         ), 4
       ) AS friendNumber
  FROM dual



回答2:


In addition to ypercubes' answer (whcih leverages DRI to enforce your rule), you can also LEFT JOIN with MIN to get the next of 1, 2 or 3 from the Three table per userID



来源:https://stackoverflow.com/questions/9621509/limit-number-of-records-using-trigger-and-constraints-in-mysql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!