SQL movie database diagram - sql

Im working on a small school project where im creating a movie database in SQL. I've created the tables and was wondering if I will encounter any problems with the model i created.
Thanks in advance.
Current diagram
Edit:
Here is the new diagram

MovieDetails is bad design. You need one row in MovieDetails per actor, while the director will be the same, which is data duplication. Instead, the Movie table should have a foreign key referencing director, then a MovieActor table should represent the many to many relationship between movies and actors.
Technically, there's also no reason to have different tables for Directors and Actors since you have the same data in the tables. You could just as well have a Person table with both.

How about (I am only showing the relevant columns)
movie table
-----------
id
title
person
------
id
name
cast table
----------
movie_id
person_id
movie_role_id (actor, director, ...)
role_type table
----------------
id
name (actor, director, ...)
genres table
------------
id
name
movie_genres table
------------------
movie_id
genre_id

I would consider the following structure:
movie(id, title, year, rating, plot, length)
actor(id, first name, last name, nationality, birth_date)
director(id, first name, last name, nationality, birth_date)
movie_x_actor(movie_id, actor_id)
movie_x_director(movie_id, director_id)
This is, of course, just the simplest example.
You can, for instance add a movie_series table like:
movie_series(id, title)
movie_x_movie_series(movie_id, series_id, plot_order_number)
and, like #Juergen described, a movie usually belongs to more than one genre so:
genres(id, genre_name, genre_description)
movie_x_genres(movie_id, genre_id)
You should definitely take a look at one-to-many and many-to-many relationships between rows in tables.
Cheers

Related

SQL Query to return a table of specific matching values based on a criteria

I have 3 tables in PostgreSQL database:
person (id, first_name, last_name, age)
interest (id, title, person_id REFERENCES person)
location (id, city, state text NOT NULL, country, person_id REFERENCES person)
city can be null, but state and country cannot.
A person can have many interests but only one location. My challenge is to return a table of people who share the same interest and location.
All ID's are serialized and thus created automatically.
Let's say I have 4 people living in "TX", they each have two interests a piece, BUT only person 1 and 3 share a similar interest, lets say "Guns" (cause its Texas after all). I need to select all people from person table where the person's interest title (because the id is auto generated, two Guns interest would result in two different ID keys) equals that of another persons interest title AND the city or state is also equal.
I was looking at the answer to this question here Select Rows with matching columns from SQL Server and I feel like the logic is sort of similar to my question, the difference is he has two tables, to join together where I have three.
return a table of people who share the same interest and location.
I'll interpret this as "all rows from table person where another rows exists that shares at least one matching row in interest and a matching row in location. No particular order."
A simple solution with a window function in a subquery:
SELECT p.*
FROM (
SELECT person_id AS id, i.title, l.city, l.state, l.country
, count(*) OVER (PARTITION BY i.title, l.city, l.state, l.country) AS ct
FROM interest i
JOIN location l USING (person_id)
) x
JOIN person p USING (id)
WHERE x.ct > 1;
This treats NULL values as "equal". (You did not specify clearly.)
Depending on undisclosed cardinalities, there may be faster query styles. (Like reducing to duplicative interests and / or locations first.)
Asides 1:
It's almost always better to have a column birthday (or year_of_birth) than age, which starts to bit-rot immediately.
Asides 2:
A person can have [...] only one location.
You might at least add a UNIQUE constraint on location.person_id to enforce that. (If you cannot make it the PK or just append location columns to the person table.)

How to combine two databases?

I am asking myself how to best define a new database given two databases.
I have the following two databases
Author where I save information about authors i.e. Name, Birthyear, Country, Genre etc.
Book where I save information about the book i.e. AuthorName, ReleaseYear, Pages etc
How do I create a new database with the full information about all books and the author? I.e. a Book_Complete Database which includes Author.Name, ReleaseYear,Pages, Genre,ReleaseYear and Author.Birthyear, Author.Country?
Better to go for a single database and having 2 tables in it like
Author Table
AuthorId (PK)
Name
Birthyear
Country
Genre
Book Table
BookId (PK)
AuthorId (FK)
ReleaseYear
Pages
If you have two tables in a database you can combine them using JOIN. Here is SQLite tutorial on how to use JOIN.
https://www.sqlitetutorial.net/sqlite-join/
On the information you provided I assume you can you columns Name in table Author, and AuthorName in table Book. You can try something like this
SELECT
A.Name,
B.ReleaseYear,
B.Pages,
B.Genre,
B.ReleaseYear,
A.Birthyear,
A.Country
FROM
Author A
LEFT JOIN Book B
ON A.Name = B.AuthorName
Basically, I have these create these two tables on my app and want to store the combined version on a server. Or would you suggest another approach?
Yes we would. You should have one table per entity, i.e. one for the authors and one for the books. Thus you don't store data redundantly (e.g. the author's name or the book's title), which could otherwise lead to inconsistencies later. You can read up on database normalization here: https://en.wikipedia.org/wiki/Database_normalization or google it.
Now you must decide how to link the tables. One author can write multiple books. Can one book be written by multiple authors? Give both tables IDs you can work with (or find some natural unique key, like the ISBN for the book and maybe name + birth year for the author - the name only will probably not suffice and maybe it won't even when combined with the year).
If one book can only be written by one author, you have a 1:n relation (one book written by one author, one author writing multiple books).
author (author_id, name, birth_year, country, ...)
book (book_id, title, author_id, release_year, pages, ...)
If one book can have several authors, you have an m:n relation (one book written by multiple authors, one author writing multiple books).
author (author_id, name, birth_year, country, ...)
book (book_id, title, release_year, pages, ...)
book_author (book_id, author_id)
You can always join the tables, so as to get a combined result.

How can i get values from under type table to parent type table

Im not sure if i formulated this correctly but i came upon a problem, Basically i made a type of object in SQL Developer HUMAN which contains ID, Name and Surname. I needed a type TEACHER so i made it as an under type of HUMAN with extra attribute. Later on i made a table containing teacher, so i thought all info inserted into teacher, that is the same for human would automatically go into table "all humans" but that didnt work. Is there a way to make some code, where parent object would recieve all information from its under objects?
It sounds like you're looking for something like this:
table Humans
____________
id
name
surname
table Teachers
____________
human_id -- foreign key to Humans table
grade_level
subject -- math, history, etc.
table Students
____________
human_id -- foreign key to Humans table
student_info
Teachers.human_id and Students.human_id are foreign keys that reference Humans.id. To get all teachers, you might do something like this
select *
from Humans inner join Teachers
on Teachers.human_id = Humans.id;
That'll give you a result set with all of the columns from both tables, like
id | name | surname | human_id | grade_level | subject
And you'd do the same to get all the students, replacing Teachers with Students in the above query.

Varray compare item in the collections

The a table of movies with attribute of directors and actors. The actor is a varray type of actor_type contain 5 actor. i want to retrieve the movie that actor is both director and actor.
i tried
select actors, title, director
from movie
where actors = director
it telling me inconsistent datatype
You didn’t provide the sample data so my understanding from your description is:
The director and actor attribute are in the movie table and the actor is displayed as Varray, which being called actor_type. Also, the actor Varray contains 5 actors in each movie.
The way to query Varray is different, you can use TABLE expression in FROM clause.
This website might help you
Database Object-Relational Developer's Guide:
https://docs.oracle.com/database/121/ADOBJ/adobjcol.htm#ADOBJ00204
Then, you have to loop through the actor list and use the EXISTS or IN operator to check if the director is inside the actor list instead of using actors=director
You didn't specify what datatype the director column is. You can do a convert on the join actor = convert(director).
But I highly recommend you don't do this.
The problem with joining on strings is it is very inconsistent and if this is your only option to join actor to director, you need to restructure your tables.
I advise you have a Person table which contains both actors and directors.
You then need a table for movies and have the director and actor as foreign keys.
If the movie can have more than one actor, for instance, you then need a link table between person and movie tables (Same with the director if you have more than one director)
Hope this helps.

SQL Multiple MANY_TO_MANY relationships

I have a three objects: City, Channel, Genre. Relations: City has many Channels and Genres, and Channel and Genres may are in several Cities. Channels has many Genres, and but Genre may has many Channels.
I designed next database:
tblChannel:
id,
name
tblGenre:
id,
name
tblCity:
id,
name
// City and Channel MANY_MANY
tblCityChannel:
id,
cityId,
channelId
// City and Genre MANY_MANY
tblCityGenre:
id,
cityId,
genreId
// Channel and Genre MANY_MANY
tblChannelGenre:
id,
channelId,
genreId
I am not sure that this correctly, who can specify my mistakes?
RESOLVE:
I redesigned my database by next:
tblChannel:
id,
name
tblGenre:
id,
name
tblCity:
id,
name
tblCityChannelGenre:
id,
cityId, // NOT NULL
channelId,
genreId
That layout solves next problems:
I may create entites separately (channel may not have genre, genre
may not have channels)
City may have list of channels,
which are not be defined by genre, and with genres conversely.
your model is correct if it is a real m:m relationship between all 3 entities. however in the real world it is unlikely. most likely you have a hierarchy (like a tree) where you only have 2 m:m relationships and the third one is implied or you have a relationship between 3 tables so you need a table with 3 col key (not 3 tables with 2 col keys). try to understand you data better and you'll see what the correct model is. again, it could be just fine...