2012-03-08 5 views
0

У меня есть таблица с именем BFF, которая хранит идентификатор пользователя и идентификатор пользователя лучшего друга, и я бы хотел ограничить эту таблицу, имея ровно 3 числа лучших друзей для каждого другого пользователя.Ограничить количество записей с помощью триггера и ограничений в MySQL

Я имею в виду, если таблица structre является:

BFFs(userID, userID) 

и записи:

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

И в этом случае, если пользователь с ID 3286 не должно быть позволено иметь новый рекорд такого как (3286, xyzt).

Я написал этот триггер, но я не уверен:

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; 
/

Как я должен restrich это реляционных таблиц с помощью утверждений или триггеров?

Благодаря

ответ

2

Добавить еще один столбец, FriendNumber и ограничение внешнего ключа в справочной таблице именно с 3 рядами:

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 
) ; 

Затем вы можете добавить:

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

или, как было предложено @gbn, для чего-то вроде этого (так что столбец автозаполняется):

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 
+0

могут вы видите редактирование моего вопроса, каковы различия между вашим ответом и моим триггером? – CanCeylan

+0

Триггеры трудно отлаживать. Обычно я избегаю их, когда существует решение ограничения. –

+0

Хотя они не являются чистым злом, читайте об этом: [База данных запускает зло?] (Http://stackoverflow.com/questions/460316/are-database-triggers-evil) –

1

В дополнении к ответу ypercubes' (whcih рычагов DRI для обеспечения вашего правила), вы можете также LEFT JOIN с MIN, чтобы получить следующий 1, 2 или 3 из три таблицы за идентификатор пользователя

Смежные вопросы