Mysql Movie Database - mysql

I'm creating a movie database and I think I have finished designing it, but my results are not coming back as I would like them too. I only have 2 movies details in the database right now. I'm trying to get it to stop displaying duplicate information.
Can you take a look and give feedback?
Thanks for the help in advance.
/*
Navicat MySQL Data Transfer
Source Server : localhost
Source Server Version : 50525
Source Host : localhost
Source Database : MovieDB
Target Server Version : 50525
File Encoding : utf-8
Date: 09/12/2013 22:06:21 PM
*/
SET NAMES utf8;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for `FORMAT`
-- ----------------------------
DROP TABLE IF EXISTS `FORMAT`;
CREATE TABLE `FORMAT` (
`ID` int(10) NOT NULL AUTO_INCREMENT,
`Formats` varchar(10) NOT NULL DEFAULT '',
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for `FORMAT_ID`
-- ----------------------------
DROP TABLE IF EXISTS `FORMAT_ID`;
CREATE TABLE `FORMAT_ID` (
`MovieID` int(11) NOT NULL DEFAULT '0',
`FormatID` int(11) NOT NULL DEFAULT '0',
`Num_Discs` int(128) DEFAULT NULL,
`Locations` varchar(128) DEFAULT NULL,
PRIMARY KEY (`MovieID`,`FormatID`),
KEY `FormatID` (`FormatID`),
CONSTRAINT `FORMAT_ID_ibfk_1` FOREIGN KEY (`MovieID`) REFERENCES `MOVIE` (`ID`),
CONSTRAINT `FORMAT_ID_ibfk_2` FOREIGN KEY (`FormatID`) REFERENCES `FORMAT` (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for `GENRE`
-- ----------------------------
DROP TABLE IF EXISTS `GENRE`;
CREATE TABLE `GENRE` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`Genres` varchar(50) NOT NULL DEFAULT '',
`Descriptions` varchar(128) DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=39 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for `GENRE_ID`
-- ----------------------------
DROP TABLE IF EXISTS `GENRE_ID`;
CREATE TABLE `GENRE_ID` (
`MovieID` int(11) NOT NULL DEFAULT '0',
`GenreID` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`MovieID`,`GenreID`),
KEY `GenreID` (`GenreID`),
CONSTRAINT `GENRE_ID_ibfk_2` FOREIGN KEY (`GenreID`) REFERENCES `GENRE` (`ID`),
CONSTRAINT `GENRE_ID_ibfk_1` FOREIGN KEY (`MovieID`) REFERENCES `MOVIE` (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for `MOVIE`
-- ----------------------------
DROP TABLE IF EXISTS `MOVIE`;
CREATE TABLE `MOVIE` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`Titles` varchar(128) NOT NULL DEFAULT '',
`Alt_Titles` varchar(128) DEFAULT NULL,
`Types` varchar(10) NOT NULL DEFAULT '',
`Synopsis` varchar(128) DEFAULT NULL,
`Images` varchar(128) DEFAULT NULL,
`Num_Eps` int(10) DEFAULT '0',
`Catagories` varchar(50) NOT NULL DEFAULT '',
`Duration` time DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for `RENT`
-- ----------------------------
DROP TABLE IF EXISTS `RENT`;
CREATE TABLE `RENT` (
`MovieID` int(11) NOT NULL DEFAULT '0',
`Rents` varchar(3) NOT NULL DEFAULT '',
`Who` varchar(128) NOT NULL DEFAULT '',
`Note` varchar(128) DEFAULT NULL,
PRIMARY KEY (`MovieID`,`Rents`,`Who`),
CONSTRAINT `RENT_ibfk_1` FOREIGN KEY (`MovieID`) REFERENCES `MOVIE` (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
SET FOREIGN_KEY_CHECKS = 1;
sql:
select distinct Titles, Types, Num_Eps, Catagories, Duration, Formats, Num_Discs, Genres
from MOVIE, FORMAT, FORMAT_ID, GENRE, GENRE_ID
where MOVIE.ID=GENRE_ID.MovieID
AND GENRE_ID.GenreID=GENRE.ID
and MOVIE.ID=FORMAT_ID.MovieID
AND FORMAT_ID.FormatID=FORMAT.ID
order by Titles;
this is my results:
Titles,Types,Num_Eps,Catagories,Duration,Formats,Num_Discs,Genres
Ghost in the Shell,Movie,1,Anime,01:23:00,DVD,1,Mecha
Ghost in the Shell,Movie,1,Anime,01:23:00,DVD,1,Police
Ghost in the Shell,Movie,1,Anime,01:23:00,DVD,1,Psychological
Ghost in the Shell,Movie,1,Anime,01:23:00,DVD,1,Sci-Fi
Ghost in the Shell,Movie,1,Anime,01:23:00,DVD,1,Cyberpunk
Ghost in the Shell,Movie,1,Anime,01:23:00,Bluray,1,Mecha
Ghost in the Shell,Movie,1,Anime,01:23:00,Bluray,1,Police
Ghost in the Shell,Movie,1,Anime,01:23:00,Bluray,1,Psychological
Ghost in the Shell,Movie,1,Anime,01:23:00,Bluray,1,Sci-Fi
Ghost in the Shell,Movie,1,Anime,01:23:00,Bluray,1,Cyberpunk
Summer Wars,Movie,1,Anime,01:54:00,DVD,1,Comedy
Summer Wars,Movie,1,Anime,01:54:00,DVD,1,Sci-Fi
Summer Wars,Movie,1,Anime,01:54:00,HD,,Comedy
Summer Wars,Movie,1,Anime,01:54:00,HD,,Sci-Fi

A few points. I would use full join syntax,
FROM MOVIE JOIN GENRE ON MOVIE.ID=GENRE_ID.MovieID
instead of the where clauses you have now.
Then you might want to try GROUP_CONCAT(expr) to concatenate your Genres into one line, ex. Mecha, Police, Psychological, etc...

Update: Thanks to Vulcronos I got genres and formats to list out right if I do them separate by using
Genre:
select distinct Titles, Types, Num_Eps, Catagories, Duration, Genres
FROM MOVIE JOIN GENRE_ID ON MOVIE.ID=GENRE_ID.MovieID, GENRE
where GENRE_ID.GENREID=GENRE.ID
order by Titles;
format:
select distinct Titles, Types, Num_Eps, Catagories, Duration, Formats, Num_Discs, Locations
FROM MOVIE JOIN FORMAT_ID ON MOVIE.ID=FORMAT_ID.MovieID, FORMAT
where FORMAT_ID.FORMATID=FORMAT.ID
order by Titles;
Is there any way to combine the two?
So I would get something like this:
Ghost in the Shell,Movie,1,Anime,01:23:00,DVD,1,Mecha
Ghost in the Shell,Movie,1,Anime,01:23:00,DVD,1,Police
Ghost in the Shell,Movie,1,Anime,01:23:00,DVD,1,Psychological
Ghost in the Shell,Movie,1,Anime,01:23:00,DVD,1,Sci-Fi
Ghost in the Shell,Movie,1,Anime,01:23:00,Bluray,1,Cyberpunk
Summer Wars,Movie,1,Anime,01:54:00,DVD,1,Comedy
Summer Wars,Movie,1,Anime,01:54:00,HD,,Sci-Fi
Where it would list the genres once and the formats once. Of course with multiple genres the format will be repeated unless there is a way to fix that, but where it will at least show all the formats once along with genres once.
Thanks for the help.

Nobody is probably looking at this thread any more, but I wanted to let future views and the people who helped me that I found what I was looking for in the question.
select DISTINCT m.Title,
group_concat(DISTINCT g.Genre) as Genres,
group_concat(DISTINCT f.Format) as Formats
from MOVIES m
left join MOVIEGENRES mg on m.Code=mg.MovieCode
left join GENRES g on mg.GenCode=g.Code
left join MOVIEFORMATS mf on m.Code=mf.MovieCode
left join FORMATS f on mf.FormCode=f.Code
group by m.Code;

Related

MySQL - how to lock a single row?

My aim is to create a system to book trips. My system is built in MySQL + PHP. I'm using InnoDB as engine in MySQL.
When an user choose which trip he wants to book, I want the ipothetic page "*.php" to lock one of those trip for some times (ex. 10 minutes) and after this time release it.
Which is the best way to lock the trip in the DB?
Notice that I didn't talk about rows or table because I'm asking for the easiest way to implement this kind of feature and I'm not sure if mines is that one. So I've tried to design a table to contain the trips, and look like this:
CREATE TABLE IF NOT EXISTS Trip (
id INT(1) NOT NULL AUTO_INCREMENT,
descr VARCHAR(50) NOT NULL,
quantity INT(2) NOT NULL DEFAULT 10,
PRIMARY KEY (id)
) Engine=InnoDB
This is your Ticket table
CREATE TABLE IF NOT EXISTS Trip (
id INT(1) NOT NULL AUTO_INCREMENT,
descr VARCHAR(50) NOT NULL,
quantity INT(2) NOT NULL DEFAULT 10,
PRIMARY KEY (id)
) Engine=InnoDB
Let me visualize your user table as this ( just for testing )
CREATE TABLE IF NOT EXISTS `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` text COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci AUTO_INCREMENT=1 ;
Now You need add an extra table where you can track your users booking order ( Example like this )
CREATE TABLE IF NOT EXISTS `trip_track` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`trip_id` int(11) NOT NULL,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci AUTO_INCREMENT=1 ;
Now Every time you insert a booking query you need to insert user_id,ticket_id and timestamp ( You can use date or Mysql's default time stamp )
Then whenever user tries to book any ticket use a Query to check the time difference between current time and the timestamp from the database
That's it! .. see? that's simple :)

Mysql : I want to create a trigger which will insert data into user access permission table based on employee table and categories table

I have three tables :- category ,employee and user_access_permission . I want to create a trigger that will fire when new category is added , insert values in user_access_permission for each employee id .default value for user_access is 0.
Category table :-
CREATE TABLE IF NOT EXISTS `categories` (
`category_id` int(11) NOT NULL AUTO_INCREMENT,
`category_name` varchar(100) NOT NULL,
`section_id` int(11) NOT NULL,
UNIQUE KEY `category_id` (`category_id`),
UNIQUE KEY `category_name` (`category_name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
Employee table :-
CREATE TABLE IF NOT EXISTS `employee` (
`employee_id` int(11) NOT NULL AUTO_INCREMENT,
`emp_pass` varchar(50) NOT NULL,
`email` varchar(100) NOT NULL,
PRIMARY KEY (`employee_id`),
UNIQUE KEY `email_UNIQUE` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=' ' AUTO_INCREMENT=1;
User Access Permission Table :-
CREATE TABLE IF NOT EXISTS `user_access_permission` (
`uap_id` int(10) NOT NULL AUTO_INCREMENT,
`section_id` int(10) NOT NULL,
`category_id` int(10) NOT NULL,
`employee_id` int(10) NOT NULL,
`access_level` int(10) NOT NULL DEFAULT '0',
PRIMARY KEY (`uap_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;
I am writing trigger like this :-
CREATE TRIGGER update_permssion_on_add_category
AFTER INSERT
ON categories FOR EACH ROW
insert into user_access_permission(section_id,category_id,employee_id,access_level) select(new.section_id,new.category_id,employee_id,0) from employee
But I don't get things right. Please Help
You have
select(new.section_id,new.category_id,employee_id,0) from employee
but section_id and category_id come from the category table.
I would suggest changing it to be 'from category' but the problem then is where do you get the employee_id number from? It's not anywhere in the original insert statement for the category table. Unless you decide to have it be some default value every time the trigger is fired.

How do I join three fields from three tables in MySQL?

I have three fields from three different tables that I would like to join together.
company FROM company,
title FROM jobs,
Description FROM jobcategory
I would like to have these three fields join together and listed sequentially to the right of the prvious field as follows:
Company | Title | Description
This is the best I can do as for providing information regarding the databases Keys...
CREATE TABLE `company` (
`companyID` int(11) NOT NULL AUTO_INCREMENT,
`company` varchar(255) NOT NULL,
PRIMARY KEY (`companyID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=117 ;
CREATE TABLE `jobcategory` (
`JobCategoryID` int(11) NOT NULL AUTO_INCREMENT,
`CategoryName` text,
`Description` text,
PRIMARY KEY (`JobCategoryID`),
UNIQUE KEY `unique_JobCategoryID` (`JobCategoryID`),
KEY `index_JobCategoryID` (`JobCategoryID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ;
CREATE TABLE `jobs` (
`title` varchar(255) NOT NULL,
`company` varchar(255) NOT NULL,
`date` date NOT NULL,
`companyID` int(11) NOT NULL,
`jobCategoryID` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
I tried running a query commented below, I received the following error.
"Error 1054 (42S22) : Unknown column 'Company.ID' in "on clause'
What is the proper syntax to execute this query?
Depends on how your keys are set up, but assuming JOBS has foreign keys referencing the COMPANY and JOBCATEGORY tables:
SELECT COMPANY.COMPANY, JOBS.TITLE, JOBCATEGORY.DESCRIPTION<br>
FROM COMPANY
INNER JOIN JOBS ON COMPANY.ID=JOBS.COMPANY_ID
INNER JOIN JOBCATEGORY ON JOBCATEGORY.ID=JOBS.JOBCATEGORY_ID

Setting up my picture gallery tables

I am going to create a web application for picture gallery.
So this is how I have created my database tables. (I have excluded the rest of unnecessary tables.)
Gallery
Gid -> Primary key.
Rid -> Foreign key from register table.
Name -> Name of the image.
Url -> Location of image.
Status -> Enabled or disabled.
Album
Aid -> Primary key.
Name -> Name of the album.
Imagelist
Iid -> Primary key.
Aid -> Foreign key from Album table.
Gid -> Foreign key from Gallery table.
But for some reason I feel the structure of these tables are wrong. My requirement is user should be able to create different albums from the gallery table.
For example if there are pictures named A, B, C, D. then user should be able to create album named a1 which contains pictures A,B,C; album a2 which contains pictures A, B, D.
I have created this three tables, but I feel that there is something wrong in the table structure. Can someone point me in a right direction?
I would not call table with images a gallery as it can mean album to. From my point of view database schema is correct only thing I would change is ImageList table as Iid is not required there, Aid and Gid suppose to be unique index, I would also add field to store image order in album, and also set all tables to InnoDB mode.
Here is example of database schema:
-- ----------------------------
-- Table structure for `gallery_album`
-- ----------------------------
DROP TABLE IF EXISTS `gallery_album`;
CREATE TABLE `gallery_album` (
`album_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL COMMENT 'name of the album',
`description` text COMMENT 'description of the album',
`visible` enum('0','1') NOT NULL DEFAULT '1' COMMENT 'is album visible',
`position` int(11) unsigned NOT NULL,
`date_created` datetime NOT NULL,
`date_updated` datetime NOT NULL,
PRIMARY KEY (`album_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for `gallery_image`
-- ----------------------------
DROP TABLE IF EXISTS `gallery_image`;
CREATE TABLE `gallery_image` (
`image_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(30) DEFAULT NULL COMMENT 'name of the image used as image ALT attribute',
`description` varchar(100) DEFAULT NULL COMMENT 'description of the image used as image TITLE attribute',
`visible` enum('0','1') NOT NULL DEFAULT '1',
`date_created` datetime NOT NULL,
`date_updated` datetime NOT NULL,
PRIMARY KEY (`image_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for `gallery_relation`
-- ----------------------------
DROP TABLE IF EXISTS `gallery_relation`;
CREATE TABLE `gallery_relation` (
`album_id` int(11) unsigned NOT NULL,
`image_id` int(11) unsigned NOT NULL,
`position` int(11) unsigned NOT NULL,
PRIMARY KEY (`album_id`,`image_id`),
KEY `image_id` (`image_id`),
CONSTRAINT `gallery_relation_ibfk_1` FOREIGN KEY (`album_id`) REFERENCES `gallery_album` (`album_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `gallery_relation_ibfk_2` FOREIGN KEY (`image_id`) REFERENCES `gallery_image` (`image_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Optimize Join sentence with foreign keys, and show records with nulls

I have the following structure
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
CREATE TABLE IF NOT EXISTS `sis_param_tax` (
`id` int(5) NOT NULL auto_increment,
`description` varchar(50) NOT NULL,
`code` varchar(5) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=7;
CREATE TABLE IF NOT EXISTS `sis_param_city` (
`id` int(4) NOT NULL auto_increment,
`name` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
CREATE TABLE IF NOT EXISTS `sis_supplier` (
`id` int(15) NOT NULL auto_increment,
`name` varchar(200) NOT NULL,
`address` varchar(200) default NULL,
`phone` varchar(30) NOT NULL,
`fk_city` int(11) default NULL,
`fk_tax` int(11) default NULL,
PRIMARY KEY (`id`),
KEY `fk_city` (`fk_city`),
KEY `fk_tax` (`fk_tax`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
ALTER TABLE `sis_supplier`
ADD CONSTRAINT `sis_supplier_ibfk_4` FOREIGN KEY (`fk_tax`) REFERENCES `sis_param_tax` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
ADD CONSTRAINT `sis_supplier_ibfk_3` FOREIGN KEY (`fk_city`) REFERENCES `sis_param_city` (`id`) ON DELETE SET NULL ON UPDATE CASCADE;
My questions are
1. This structure allows me to have a supplier with city and tax fields = null (in case user didn't set these values). Right?
2. If I delete "X" city, supplier's fk_city with city="X" are set to null, same with fk_tax. Right?
3. I want to optimize (IF POSSIBLE) the following join sentence, so I can show suppliers whom have fk_city and/or fk_tax = NULL
SELECT DISTINCT
sis_supplier.id,
sis_supplier.name,
sis_supplier.telefono,
sis_supplier.address,
sis_supplier.phone,
sis_supplier.cuit,
sis_param_city.name AS city,
sis_param_tax.description AS tax,
sis_supplier.fk_city,
sis_supplier.fk_tax
FROM
sis_supplier
LEFT OUTER JOIN sis_param_city
ON
sis_supplier.`fk_city` = sis_param_city.id
LEFT OUTER JOIN `sis_param_tax`
ON
sis_supplier.`fk_tax` = `sis_param_tax`.`id`
Thanks a lot in advance,
Yes.
Yes.
Yes, it's good to optimize. The query you showed looks fine. How is it not working for you?
Have you analyzed the query with EXPLAIN? This can help you tell when you have a query that isn't using indexes effectively. In fact, all of Chapter 7 Optimization would be recommended reading.
if you want to show records with nulls than use RIGHT or LEFT JOIN
depend on your needs