Andmebaas MOVIES
Ülesanne
Kasuta SQL Server Managment Stuudio või mariaDB/XAMPP
Loo tabelid, primaarsed võtmed ja välisvõtmed. Graafilises keskkonnas! ja tee vastava konspekti.
Täida tabelid (vähemalt 5 rida igas tabelis)
——————- protseduurite, trigerite ja kasutajate loomiseks saab SQL laused ka kasutada (ei tohi Chat GPT kasutada!)
1. Koosta 3 protseduuri, mis on loodud seotud (JOIN) tabelite põhjal. Iseseisvalt määra mida protseduurid teevad. Käivita neid.
2. Loo 2 kasutajat (admin, kes saab teha kõike kõikidega tabelitega / kasutajaNimi, kes saab lisada ja kontrollida andmed tabelites: person, pictures.
3. Loo 2-3 trigerid, mis jälgivad ainult põhitabelite täitmine/muutmine (näiteks, need tabelid kus on olemas FK).
4. kasutajaNimi ei pea näha logi tabeli, kuhu triger salvestab oma andmed.
5. Kõik tegevused on vaja kontrollida nii moodi, et aru saada mis kasutaja mida teeb!
Täitmiskäik
Andmebaasi tabelite ja skeemi loomine
Loon andmebaasi skeem LucidChart-is

Ekspordime Lucichartist andmebaasi koodi.

Andmebaasi Movie loome SQL Server Management Stuudios. Tabelid lisatakse SQL-koodi abil käsitsi.
CREATE TABLE [genre] (
[id] INT IDENTITY(1,1) PRIMARY KEY, -- Lisatud IDENTITY
[genre_name] VARCHAR(50),
[description] VARCHAR(100)
);
CREATE INDEX [N] ON [genre] ([description]);
CREATE TABLE [movie] (
[id] INT IDENTITY(1,1) PRIMARY KEY, -- Lisatud IDENTITY
[title] VARCHAR(100),
[production_year] INT,
[duration] INT,
[description] VARCHAR(100)
);
CREATE INDEX [N] ON [movie] ([description]);
CREATE TABLE [movie_genre] (
[id] INT IDENTITY(1,1) PRIMARY KEY, -- Lisatud IDENTITY
[movie_id] INT,
[genre_id] INT,
CONSTRAINT [FK_movie_genre.movie_id]
FOREIGN KEY ([movie_id]) REFERENCES [movie]([id]),
CONSTRAINT [FK_movie_genre.genre_id]
FOREIGN KEY ([genre_id]) REFERENCES [genre]([id])
);
CREATE TABLE [person] (
[id] INT IDENTITY(1,1) PRIMARY KEY, -- Lisatud IDENTITY
[first_name] VARCHAR(100),
[last_name] VARCHAR(100),
[birth_date] DATE
);
CREATE TABLE [position] (
[id] INT IDENTITY(1,1) PRIMARY KEY, -- Lisatud IDENTITY
[position_name] VARCHAR(50),
[description] VARCHAR(100)
);
CREATE INDEX [N] ON [position] ([description]);
CREATE TABLE [person_in_movie] (
[id] INT IDENTITY(1,1) PRIMARY KEY, -- Lisatud IDENTITY
[person_id] INT,
[movie_id] INT,
[position_id] INT,
[role] VARCHAR(50),
CONSTRAINT [FK_person_in_movie.position_id]
FOREIGN KEY ([position_id]) REFERENCES [position]([id]),
CONSTRAINT [FK_person_in_movie.movie_id]
FOREIGN KEY ([movie_id]) REFERENCES [movie]([id]),
CONSTRAINT [FK_person_in_movie.person_id]
FOREIGN KEY ([person_id]) REFERENCES [person]([id])
);
CREATE INDEX [N] ON [person_in_movie] ([role]);
CREATE TABLE [production_company] (
[id] INT IDENTITY(1,1) PRIMARY KEY, -- Lisatud IDENTITY
[company_name] VARCHAR(100),
[company_address] VARCHAR(100)
);
CREATE TABLE [movie_by_production_company] (
[id] INT IDENTITY(1,1) PRIMARY KEY, -- Lisatud IDENTITY
[movie_id] INT,
[production_company_id] INT,
CONSTRAINT [FK_movie_by_production_company.movie_id]
FOREIGN KEY ([movie_id]) REFERENCES [movie]([id]),
CONSTRAINT [FK_movie_by_production_company.production_company_id]
FOREIGN KEY ([production_company_id]) REFERENCES [production_company]([id])
);
CREATE TABLE [picture] (
[id] INT IDENTITY(1,1) PRIMARY KEY, -- Lisatud IDENTITY
[picture_file_name] VARCHAR(100),
[person_id] INT,
CONSTRAINT [FK_picture.person_id]
FOREIGN KEY ([person_id]) REFERENCES [person]([id])
);
CREATE TABLE [quote] (
[id] INT IDENTITY(1,1) PRIMARY KEY, -- Lisatud IDENTITY
[quote_text] VARCHAR(100),
[person_in_movie_id] INT,
CONSTRAINT [FK_quote.person_in_movie_id]
FOREIGN KEY ([person_in_movie_id]) REFERENCES [person_in_movie]([id])
);
Täidame tabelid (vähemalt 5 rida igas tabelis)
📥 1. genre
INSERT INTO genre VALUES ('Action', 'Fast-paced, exciting scenes');
INSERT INTO genre VALUES ('Drama', 'Emotional and narrative-driven');
INSERT INTO genre VALUES ('Comedy', 'Humorous content');
INSERT INTO genre VALUES ('Sci-Fi', 'Science fiction themes');
INSERT INTO genre VALUES ('Horror', 'Scary and suspenseful');
🎬 2. movie
INSERT INTO movie VALUES ('Skyfall', 2012, 143, 'James Bond film');
INSERT INTO movie VALUES ('Interstellar', 2014, 169, 'Space exploration');
INSERT INTO movie VALUES ('The Hangover', 2009, 100, 'Bachelor party comedy');
INSERT INTO movie VALUES ('The Godfather', 1972, 175, 'Mafia family story');
INSERT INTO movie VALUES ('Get Out', 2017, 104, 'Social horror thriller');
🎥 3. movie_genre
INSERT INTO movie_genre VALUES (1, 1);
INSERT INTO movie_genre VALUES (2, 4);
INSERT INTO movie_genre VALUES (3, 3);
INSERT INTO movie_genre VALUES (4, 2);
INSERT INTO movie_genre VALUES (5, 5);
👤 4. person
INSERT INTO person VALUES ('Daniel', 'Craig', '1968-03-02');
INSERT INTO person VALUES ('Matthew', 'McConaughey', '1969-11-04');
INSERT INTO person VALUES ('Bradley', 'Cooper', '1975-01-05');
INSERT INTO person VALUES ('Marlon', 'Brando', '1924-04-03');
INSERT INTO person VALUES ('Daniel', 'Kaluuya', '1989-02-24');
🧑💼🎬 5. position
INSERT INTO position VALUES ('Director', 'Directs the movie');
INSERT INTO position VALUES ('Actor', 'Performs roles');
INSERT INTO position VALUES ('Writer', 'Writes script');
INSERT INTO position VALUES ('Producer', 'Oversees production');
INSERT INTO position VALUES ('Editor', 'Edits final cut');
🧑🎬 6. person_in_movie
INSERT INTO person_in_movie VALUES (1, 1, 2, 'James Bond');
INSERT INTO person_in_movie VALUES (2, 2, 2, 'Cooper');
INSERT INTO person_in_movie VALUES (3, 3, 2, 'Phil');
INSERT INTO person_in_movie VALUES (4, 4, 2, 'Vito Corleone');
INSERT INTO person_in_movie VALUES (5, 5, 2, 'Chris Washington');
🏢 7. production_company
INSERT INTO production_company VALUES ('Eon Productions', 'London, UK');
INSERT INTO production_company VALUES ('Syncopy', 'Los Angeles, USA');
INSERT INTO production_company VALUES ('Legendary Pictures', 'Burbank, USA');
INSERT INTO production_company VALUES ('Paramount Pictures', 'Hollywood, USA');
INSERT INTO production_company VALUES ('Blumhouse', 'Los Angeles, USA');
📽️ 8. movie_by_production_company
INSERT INTO movie_by_production_company VALUES (1, 1);
INSERT INTO movie_by_production_company VALUES (2, 2);
INSERT INTO movie_by_production_company VALUES (3, 3);
INSERT INTO movie_by_production_company VALUES (4, 4);
INSERT INTO movie_by_production_company VALUES (5, 5);
🖼️ 9. picture
INSERT INTO picture VALUES ('craig.jpg', 1);
INSERT INTO picture VALUES ('mcconaughey.jpg', 2);
INSERT INTO picture VALUES ('cooper.jpg', 3);
INSERT INTO picture VALUES ('brando.jpg', 4);
INSERT INTO picture VALUES ('kaluuya.jpg', 5);
🗣️ 10. quote
INSERT INTO quote VALUES ('The name’s Bond, James Bond.', 1);
INSERT INTO quote VALUES ('Do not go gentle into that good night.', 2);
INSERT INTO quote VALUES ('What happens in Vegas, stays in Vegas.', 3);
INSERT INTO quote VALUES ('I’m gonna make him an offer he can’t refuse.', 4);
INSERT INTO quote VALUES ('Get out.', 5);
1. Protseduurid seotud tabelite põhjal: loomine ja käivitamine
1.1. Protseduur, mis lisab uue filmi ja seob selle valitud žanriga:
CREATE PROCEDURE AddMovieWithGenre
@title VARCHAR(100),
@production_year INT,
@duration INT,
@description VARCHAR(100),
@genre_id INT
AS
BEGIN
-- Lisame uue filmi tabelisse movie
INSERT INTO movie (title, production_year, duration, description)
VALUES (@title, @production_year, @duration, @description);
-- Saame ID, mis lisati filmi tabelisse, kasutades SCOPE_IDENTITY
DECLARE @movie_id INT = SCOPE_IDENTITY();
-- Lisame filmi žanri
INSERT INTO movie_genre (movie_id, genre_id)
VALUES (@movie_id, @genre_id);
-- Tagastame filmi info
SELECT
m.id AS MovieID,
m.title AS MovieTitle,
m.production_year AS ProductionYear,
m.duration AS Duration,
m.description AS Description,
g.genre_name AS Genre
FROM
movie m
INNER JOIN
movie_genre mg ON m.id = mg.movie_id
INNER JOIN
genre g ON mg.genre_id = g.id
WHERE
m.id = @movie_id;
END;
EXEC AddMovieWithGenre
@title = 'The Hunger Games',
@production_year = 2012,
@duration = 142,
@description = 'Film "The Hunger Games" põhineb Suzanne Collinsi populaarsel romaanil ja kujutab düstoopilist ühiskonda, kus noored peavad ellujäämise nimel võitlema.',
@genre_id = 6;

1.2. Protseduur filmis osalevate näitlejate ja nende rollide leidmiseks:
CREATE PROCEDURE GetActorsInMovie
@movie_id INT
AS
BEGIN
-- Saame kõik filmis osalevad näitlejad koos nende rollidega
SELECT
p.first_name AS eesnimi, -- Näitleja eesnimi
p.last_name AS perenimi, -- Näitleja perenimi
pim.role AS roll, -- Näitleja roll filmis
m.title AS film_pealkiri -- Filmi nimi
FROM
person_in_movie pim
JOIN
person p ON pim.person_id = p.id -- Ühendame näitlejad filmidega
JOIN
movie m ON pim.movie_id = m.id -- Ühendame näitlejad filmidega
WHERE
m.id = @movie_id -- Filtreerime vastavalt valitud filmile
ORDER BY
p.last_name; -- Sorteerime näitlejad perenime järgi
END;
EXEC GetActorsInMovie @movie_id = 1;

1.3. Protseduur filmi lisamiseks:
CREATE PROCEDURE GetMoviesByProductionCompany
@company_name VARCHAR(100) -- Sisestame tootmisfirma nime
AS
BEGIN
-- Näitame kõik filmid, mida see firma on teinud
SELECT
p.company_name AS tootmisfirma, -- Firma nimi
m.title AS film_nimi, -- Filmi pealkiri
m.production_year AS aasta, -- Millal film tehti
m.duration AS kestus_minutites, -- Kui pikk film on
m.description AS kirjeldus -- Lühikirjeldus filmist
FROM
production_company p
INNER JOIN movie_by_production_company mbpc ON p.id = mbpc.production_company_id
INNER JOIN movie m ON mbpc.movie_id = m.id
WHERE
p.company_name = company_name; -- Otsime täpselt selle firma järgi
END;
EXEC GetMoviesByProductionCompany @company_name = 'Warner Bros';

Protseduur: Filmi lisamine koos täieliku infoga (žanr, näitleja, roll, tootmisfirma)
CREATE PROCEDURE AddMovieWithFullInfo
@title VARCHAR(100),
@production_year INT,
@duration INT,
@description VARCHAR(100),
@genre_name VARCHAR(50),
@person_first_name VARCHAR(100),
@person_last_name VARCHAR(100),
@person_role VARCHAR(50),
@company_name VARCHAR(100)
AS
BEGIN
DECLARE @movie_id INT; -- Filmi ID
DECLARE @genre_id INT; -- Žanri ID
DECLARE @person_id INT; -- Näitleja ID
DECLARE @company_id INT; -- Tootmisfirma ID
-- Lisame filmi 'movie' tabelisse
INSERT INTO movie (title, production_year, duration, description)
VALUES (@title, @production_year, @duration, @description);
-- Saame uue filmi ID
SET @movie_id = SCOPE_IDENTITY();
-- Lisame žanri (kui seda pole veel) ja saame selle ID
IF NOT EXISTS (SELECT 1 FROM genre WHERE genre_name = @genre_name)
BEGIN
INSERT INTO genre (genre_name, description)
VALUES (@genre_name, ''); -- Kirjeldus on tühi, täiendage, kui vajalik
END
SET @genre_id = (SELECT id FROM genre WHERE genre_name = @genre_name);
-- Seome filmi žanriga 'movie_genre' tabelis
INSERT INTO movie_genre (movie_id, genre_id)
VALUES (@movie_id, @genre_id);
-- Lisame näitleja (kui teda pole veel) ja saame tema ID
IF NOT EXISTS (SELECT 1 FROM person WHERE first_name = @person_first_name AND last_name = @person_last_name)
BEGIN
INSERT INTO person (first_name, last_name, birth_date)
VALUES (@person_first_name, @person_last_name, '1900-01-01'); -- Sünnikuupäev on määratud, täiendage vajadusel
END
SET @person_id = (SELECT id FROM person WHERE first_name = @person_first_name AND last_name = @person_last_name);
-- Lisame näitleja filmi 'person_in_movie' tabelis
INSERT INTO person_in_movie (person_id, movie_id, position_id, role)
VALUES (@person_id, @movie_id, 1, @person_role); -- Positsioon määratud kui 1, täiendage vajadusel
-- Lisame tootmisfirma (kui seda pole veel) ja saame firma ID
IF NOT EXISTS (SELECT 1 FROM production_company WHERE company_name = @company_name)
BEGIN
INSERT INTO production_company (company_name, company_address)
VALUES (@company_name, ''); -- Aadress on tühi, täiendage vajadusel
END
SET @company_id = (SELECT id FROM production_company WHERE company_name = @company_name);
-- Seome filmi tootmisfirmaga 'movie_by_production_company' tabelis
INSERT INTO movie_by_production_company (movie_id, production_company_id)
VALUES (@movie_id, @company_id);
-- Valime kogu filmi info INNER JOIN abil
SELECT
m.title AS film_title, -- Filmi pealkiri
m.production_year AS year, -- Filmi tootmisaasta
m.duration AS duration_minutes, -- Filmi kestus minutites
m.description AS film_description, -- Filmi kirjeldus
g.genre_name AS genre, -- Žanri nimi
p.first_name AS actor_first_name, -- Näitleja eesnimi
p.last_name AS actor_last_name, -- Näitleja perenimi
pim.role AS actor_role, -- Näitleja roll
pc.company_name AS production_company -- Tootmisfirma nimi
FROM
movie m
INNER JOIN movie_genre mg ON m.id = mg.movie_id -- Ühendame filmi ja žanri
INNER JOIN genre g ON mg.genre_id = g.id -- Ühendame filmi ja žanri
INNER JOIN person_in_movie pim ON m.id = pim.movie_id -- Ühendame filmi ja näitlejad
INNER JOIN person p ON pim.person_id = p.id -- Ühendame näitlejad filmidega
INNER JOIN movie_by_production_company mbpc ON m.id = mbpc.movie_id -- Ühendame filmi ja tootmisfirma
INNER JOIN production_company pc ON mbpc.production_company_id = pc.id -- Ühendame filmi ja tootmisfirma
WHERE
m.id = @movie_id; -- Filtreerime järgi lisatud filmi ID
END;
EXEC AddMovieWithFullInfo
@title = 'A Minecraft Movie',
@production_year = 2025,
@duration = 110,
@description = 'Film "Minecraft" põhineb populaarsel videomängul Minecraft.',
@genre_name = 'Adventure',
@person_first_name = 'Jason',
@person_last_name = 'Momoa',
@person_role = 'Garrett "The Garbage Man" Garrison',
@company_name = 'Legendary Pictures';

2. Kahe SQL-kasutajate loomine – administraator (täielikud õigused) ja tavakasutaja (õigused tabelitele person ja picture).
Administraatori (täielikud õigused) loomine.


Tavakasutaja loomine (õigused kontrollida ja lisada andmeid tabelitesse person
ja picture
).




Loome 2-3 triggerit, mis jälgivad ainult põhitabelite täitmist ja muutmist (nt tabelid, kus on olemas välisvõtmed).
Loome tabel user_activity
CREATE TABLE user_activity (
id INT IDENTITY(1,1) PRIMARY KEY, -- Unikaalne ID
user_name VARCHAR(100), -- Kasutaja nimi, kes tegi tegevuse
action VARCHAR(100), -- Tegevuse tüüp (nt "AddMovie")
table_name VARCHAR(50), -- Tabel, kuhu tegevus toimus (nt "movie")
record_id INT, -- Rekordi ID, millega tegevus on seotud
action_time DATETIME -- Aeg, millal tegevus toimus
);
Loome triggeri, mis jälgib uute kirjetuste lisamist tabelisse person_in_movie
.
CREATE TRIGGER trg_after_insert_person_in_movie
ON person_in_movie
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO user_activity (user_name, action, table_name, record_id, action_time)
SELECT
SYSTEM_USER,
'InsertPersonInMovie: PersonID=' + CAST(i.person_id AS VARCHAR) +
', MovieID=' + CAST(i.movie_id AS VARCHAR) +
', PositionID=' + CAST(i.position_id AS VARCHAR) +
', Role=' + ISNULL(i.role, 'NULL'), -- на случай если роль пустая
'person_in_movie',
i.id,
GETDATE()
FROM inserted i;
END;
Loome triggeri, mis jälgib muudatusi tabelis movie
.
CREATE TRIGGER trg_after_update_movie
ON movie
FOR UPDATE
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO user_activity (user_name, action, table_name, record_id, action_time)
SELECT
SYSTEM_USER,
'Vanad andmed - Title: ' + ISNULL(d.title, 'NULL') +
', Year: ' + CAST(ISNULL(d.production_year, 0) AS VARCHAR) +
', Duration: ' + CAST(ISNULL(d.duration, 0) AS VARCHAR) +
CHAR(13) + CHAR(10) +
'Uued andmed - Title: ' + ISNULL(i.title, 'NULL') +
', Year: ' + CAST(ISNULL(i.production_year, 0) AS VARCHAR) +
', Duration: ' + CAST(ISNULL(i.duration, 0) AS VARCHAR),
'movie',
i.id,
GETDATE()
FROM deleted d
INNER JOIN inserted i ON d.id = i.id;
END;
Loome triggeri, mis jälgib muudatusi tabelis person_in_movie
CREATE TRIGGER trg_after_update_person_in_movie
ON person_in_movie
FOR UPDATE
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO user_activity (user_name, action, table_name, record_id, action_time)
SELECT
SYSTEM_USER,
'Vanad andmed - PersonID: ' + CAST(ISNULL(d.person_id, 0) AS VARCHAR) +
', MovieID: ' + CAST(ISNULL(d.movie_id, 0) AS VARCHAR) +
', PositionID: ' + CAST(ISNULL(d.position_id, 0) AS VARCHAR) +
', Role: ' + ISNULL(d.role, 'NULL') +
CHAR(13) + CHAR(10) + -- Line break
'Uued andmed - PersonID: ' + CAST(ISNULL(i.person_id, 0) AS VARCHAR) +
', MovieID: ' + CAST(ISNULL(i.movie_id, 0) AS VARCHAR) +
', PositionID: ' + CAST(ISNULL(i.position_id, 0) AS VARCHAR) +
', Role: ' + ISNULL(i.role, 'NULL'),
'person_in_movie',
i.id,
GETDATE()
FROM deleted d
INNER JOIN inserted i ON d.id = i.id;
END;