Andmebaas MOVIES

Выполняю работу в Microsoft SQL Server, согласно своему варианту 2.

Для начала работы создаю базу данных, в графической среде, под названием MOVIES:

Далее, создаю 10 таблиц в графической среде, согласно заданию:

📍Таблица person:

Разрешила «самозаполнение» Identity Specication = Yes (делаю для каждого id)⤵️

Пишу название для таблиц, согласно схеме в задании:

📍Таблица person_in_movie:

📍Таблица movie:

📍Таблица movie_by_production_company:

📍Таблица picture:

📍Таблица position:

📍Таблица quote:

📍Таблица movie_genre:

📍Таблица genre:

📍Таблица production_company:

Проверяю, что все таблицы созданы и отображаются в БД MOVIES ➜ Tables:

Перед тем, как сделать связи между таблицами, я их заполнила (по 5 записей) через графическую среду. Вот так заходим на каждую таблицу и заполняем их данными:

🧩 Связи между таблицами

Создаём New Database Diagram для построения связей и присвоение первичных PK и вторичных ключей FK.

Делаем связи для всех таблиц нажимая на таблицу, где вторичный ключ FK и выбирая Relationships:

Связь person_in_movie(person_id) c person(id):

Связь person_in_movie(movie_id) c movie(id):

Связь picture(person_id) c person(id):

Связь quote(person_in_movie_id) c person_in_movie(id):

Связь person_in_movie(position_id) c position(id):

Связь movie_genre(genre_id) c genre(id):

Связь movie_by_production_company(movie_id) c movie(id):

Связь movie_by_production_company(production_company_id) c production_company(id):

🔑 Проверяю связи. Все связи выполнены верно:

✏️ Выполнение задания

1️⃣ Процедура getActorsAndMovies выбирает информацию об актёрах и фильмах, в которых они снимались:

USE MOVIES;
GO

CREATE PROCEDURE getActorsAndMovies
AS
BEGIN
    SELECT 
        p.first_name + ' ' + p.last_name AS actor_name,
        m.title AS movie_title,
        pim.role,
        pos.position_name
    FROM person p
    JOIN person_in_movie pim ON p.id = pim.person_id
    JOIN movie m ON m.id = pim.movie_id
    JOIN position pos ON pos.id = pim.position_id
    WHERE pos.position_name = 'Актёр'
END;

Добавляю в таблицы новые данные для проверки работы процедур:

➖ Добавим актёра

INSERT INTO person (first_name, last_name, birth_date)
VALUES ('Эмма', 'Уотсон', '1990-04-15');

SELECT * FROM person;

➖ Добавим фильм

INSERT INTO movie (title, production_year, duration, description)
VALUES ('Гарри Потер', 2001, 152, 'Начинается волшебный мир.');

SELECT * FROM movie;

➖ Добавим позицию «Актёр»

INSERT INTO position (position_name, description)
VALUES ('Актёр', 'Играет роль в фильме');

SELECT * FROM position;

➖ Добавим связь между актёром и фильмом, запускаем процедуру и проверяем:

INSERT INTO person_in_movie (person_id, movie_id, position_id, role)
VALUES (10, 14, 10, 'Гермиона Грейнджер');

EXEC getActorsAndMovies;

SELECT * FROM person_in_movie;

Результат показывает, кто и в каком фильме снимался, и в какой роли.

2️⃣ Процедура getQuotesWithActors отображает цитаты персонажей из фильмов:

CREATE PROCEDURE getQuotesWithActors
AS
BEGIN
    SELECT 
        q.quote_text,
        p.first_name + ' ' + p.last_name AS actor_name,
        m.title AS movie_title
    FROM quote q
    JOIN person_in_movie pim ON q.person_in_movie_id = pim.id
    JOIN person p ON pim.person_id = p.id
    JOIN movie m ON pim.movie_id = m.id
END;

Добавляю цитату:

INSERT INTO quote (quote_text, person_in_movie_id)
VALUES ('Это не просто магия — это Хогвартс!', 5);

Запускаю:

EXEC getQuotesWithActors;

Проверяю:

Результат показывает, какой актер и из какого фильма, сказал цитату.

3️⃣ Процедура getMoviesWithGenres показывает, каким жанрам принадлежат фильмы:

CREATE PROCEDURE getMoviesWithGenres
AS
BEGIN
    SELECT 
        m.title AS movie_title,
        g.genre_name
    FROM movie m
    JOIN movie_genre mg ON m.id = mg.movie_id
    JOIN genre g ON mg.genre_id = g.id
END;

➖ Ищу подходящий жанр в своей таблице, он у меня под id 3 Фэнтези:

SELECT * FROM genre;

Связываю фильм Гарри Поттер id = 14 с жанром id = 3 и запускаю:

INSERT INTO movie_genre (movie_id, genre_id)
VALUES (14, 3);

EXEC getMoviesWithGenres;

Результат: таблица отображает название фильма и его жанр.

🧚🏼‍♀️Создаю пользователей для БД MOVIES:

Создаю admin_kino с правами owner

-- Создание админа, привязка к бд MOVIES + роли owner

CREATE LOGIN admin_kino WITH PASSWORD = '12345';
CREATE USER admin_kino FOR LOGIN admin_kino;
ALTER ROLE db_owner ADD MEMBER admin_kino;

Создаю kasutaja_kino с правами только к таблицам person и picture:

-- Создание kasutaja, привязка к бд MOVIES + права только к таблицам person и picture

CREATE LOGIN kasutaja_kino WITH PASSWORD = '12345';
CREATE USER kasutaja_kino FOR LOGIN kasutaja_kino;
GRANT SELECT, INSERT ON person TO kasutaja_kino;
GRANT SELECT, INSERT ON picture TO kasutaja_kino;

✔️ Через графическую сферу проверяю, что данные пользователи существуют

admin_kino имеет полный контроль.

kasutaja_kino может смотреть и добавлять данные только в указанные таблицы, не имеет доступа к другим.

Создаю таблицу logi, чтобы заполнялась триггерами:

CREATE TABLE logi (
    id INT IDENTITY(1,1) PRIMARY KEY,
    tegevus NVARCHAR(50),          -- Действие
    tabel NVARCHAR(50),            -- Название таблицы
    kasutaja NVARCHAR(100),        -- Кто выполнил
    aeg DATETIME DEFAULT GETDATE() -- Время 
);

1️⃣ Триггер personLisamine (Добавление в таблицу picture):

CREATE TRIGGER personLisamine
ON person_in_movie
FOR INSERT
AS
INSERT INTO logi(aeg, tegevus, tabel, kasutaja)
SELECT 
    GETDATE(),                         
    'on tehtud INSERT person_in_movie',
    'person_in_movie',               
    SYSTEM_USER                       
FROM inserted;

2️⃣ Триггер pildiKustutamine (Удаление из picture):

CREATE TRIGGER pildiKustutamine
ON picture
FOR DELETE
AS
INSERT INTO logi(aeg, tegevus, tabel, kasutaja)
SELECT 
    GETDATE(),
    'on tehtud DELETE picture',
    'picture',
    SYSTEM_USER
FROM deleted;

3️⃣ Триггер quoteUuendamine (срабатывает, когда кто-то обновляет запись в таблице quote)

CREATE TRIGGER quoteUuendamine
ON quote
FOR UPDATE
AS
INSERT INTO logi(aeg, tegevus, tabel, kasutaja)
SELECT 
    GETDATE(),
    'on tehtud UPDATE quote',
    'quote',
    SYSTEM_USER
FROM inserted;

➖ Проверяю работу триггеров:

INSERT INTO person_in_movie (person_id, movie_id, position_id, role)
VALUES (10, 14, 10, 'Гермиона');

UPDATE quote
SET quote_text = 'Это обновлённая цитата про Хогвартс!'
WHERE id = 10;

DELETE FROM picture
WHERE id = 1; 

-- проверка логов
SELECT * FROM logi;

Вывод

Во время выполнения этого задания я создала базу данных MOVIES, в которую входят фильмы, актёры, роли, жанры, цитаты и другие связанные таблицы.

Я сделала три процедуры, чтобы можно было получать информацию об актёрах, фильмах и цитатах. Также создала двух пользователей: один — администратор, второй — обычный, у которого доступ только к нужным таблицам.

Для контроля действий были добавлены триггера, которые срабатывают при добавлении, обновлении и удалении данных. Все действия записываются в журнал logi, где видно, что произошло, когда и какой пользователь это сделал.

Я всё проверила с помощью реальных данных — добавляла, меняла и удаляла записи. Все триггеры сработали, а информация отобразилась в журнале. Работа соответствует заданию и требованиям.