diff --git a/lab-4/music-store-app/sql/schema.sql b/lab-4/music-store-app/sql/schema.sql new file mode 100644 index 0000000000000000000000000000000000000000..2a0b651f48cdbc0fa45f55a3260c23818ed51cea --- /dev/null +++ b/lab-4/music-store-app/sql/schema.sql @@ -0,0 +1,115 @@ +/* Delete existing tables in reverse order of creation +so as not to violate any foreign key constraints */ +DROP TABLE IF EXISTS LineItem, Transaction, Customer, Track, Album, Artist, Band, Genre; + +/* Define table for genres */ +CREATE TABLE Genre ( + id INT AUTO_INCREMENT, + name VARCHAR(25) UNIQUE NOT NULL, + PRIMARY KEY (id) +); + +/* Define table for storing act (i.e. a group or solo artist) +ON DELETE CASCADE not used in this case as we don't want bands +being deleted if their genre is deleted. We'd rather an error +was raised. */ +CREATE TABLE Band ( + id INT AUTO_INCREMENT, + name VARCHAR(50) NOT NULL, + genre_id INT, + PRIMARY KEY (id), + FOREIGN KEY (genre_id) + REFERENCES Genre (id) +); + +/* Define table for storing artists */ +CREATE TABLE Artist ( + id INT AUTO_INCREMENT, + first_name VARCHAR(25) NOT NULL, + last_name VARCHAR(25), + band_id INT, + PRIMARY KEY (id), + FOREIGN KEY (band_id) + REFERENCES Band (id) +); + +/* Define table for storing albums */ +CREATE TABLE Album ( + upc CHAR(12), + title VARCHAR(50) NOT NULL, + release_year YEAR(4), + artist_id INT, + compilation BOOLEAN NOT NULL DEFAULT 0, + price_pounds DECIMAL(5, 2) unsigned NOT NULL, /* MODIFIED! */ + price_euros DECIMAL(5, 2) unsigned NOT NULL, /* NEW! */ + genre_id INT, + num_ratings INT unsigned DEFAULT 0, /* NEW! column for storing number of times users rated album */ + total_rating INT unsigned DEFAULT 0, /* NEW! columm for storing sum of all ratings */ + avg_user_rating DECIMAL(2,1) unsigned DEFAULT NULL, /* NEW! column for average rating */ + PRIMARY KEY (upc), + FOREIGN KEY (artist_id) + REFERENCES Artist (id), + FOREIGN KEY (genre_id) + REFERENCES Genre (id) +); + + +/* Define table for storing single tracks +ON DELETE CASCADE will ensure no track +is left that isn't linked to an album. +ON UPDATE CASCADE will inherit any changes +to the Album UPC (Universal Product Code). +A composite PRIMARY KEY is used here to +ensure the track_number is unique +on any given album */ +CREATE TABLE Track ( + name VARCHAR(50) NOT NULL, + album_upc CHAR(12) NOT NULL, + track_number INT, + PRIMARY KEY (album_upc, track_number), + FOREIGN KEY (album_upc) + REFERENCES Album (upc) + ON UPDATE CASCADE + ON DELETE CASCADE +); + +/* Define table for storing customers */ +CREATE TABLE Customer ( + id INT AUTO_INCREMENT, + username VARCHAR(25) UNIQUE NOT NULL, + email_address VARCHAR(50) UNIQUE NOT NULL, + password VARCHAR(64), /* will store a hashed password */ + first_name VARCHAR(50) NOT NULL, + last_name VARCHAR(50) NOT NULL, + address_1 VARCHAR(50) NOT NULL, + address_2 VARCHAR(50), + postcode VARCHAR(10) NOT NULL, + wishlist VARCHAR(255), /* NEW! will store a list of album UPCs */ + PRIMARY KEY (id) +); + +/* Define table for storing orders */ +CREATE TABLE Transaction ( + id INT AUTO_INCREMENT, + customer_id INT NOT NULL, + delivery ENUM('first class','second class','next working day'), + PRIMARY KEY (id), + FOREIGN KEY (customer_id) + REFERENCES Customer(id) + ON DELETE CASCADE +); + +/* Define table for storing items in an order */ +CREATE TABLE LineItem ( + id INT AUTO_INCREMENT, + trans_id INT NOT NULL, + album_upc CHAR(12) NOT NULL, + quantity INT NOT NULL DEFAULT 1, + PRIMARY KEY (id), + FOREIGN KEY (trans_id) + REFERENCES Transaction (id) + ON DELETE CASCADE, + FOREIGN KEY (album_upc) + REFERENCES Album (upc) + ON DELETE CASCADE +); diff --git a/lab-4/music-store-app/sql/schema_norm.sql b/lab-4/music-store-app/sql/schema_norm.sql new file mode 100644 index 0000000000000000000000000000000000000000..a50644a8821871a62497e0f47d7bc74a6b4b4935 --- /dev/null +++ b/lab-4/music-store-app/sql/schema_norm.sql @@ -0,0 +1,132 @@ +/* Delete existing tables in reverse order of creation +so as not to violate any foreign key constraints */ +DROP TABLE IF EXISTS LineItem, Transaction, Customer, Track, Album, Artist, Band, Genre; + +/* Define table for genres */ +CREATE TABLE Genre ( + id INT AUTO_INCREMENT, + name VARCHAR(25) UNIQUE NOT NULL, + PRIMARY KEY (id) +); + +/* Define table for storing act (i.e. a group or solo artist) +ON DELETE CASCADE not used in this case as we don't want bands +being deleted if their genre is deleted. We'd rather an error +was raised. */ +CREATE TABLE Band ( + id INT AUTO_INCREMENT, + name VARCHAR(50) NOT NULL, + genre_id INT, + PRIMARY KEY (id), + FOREIGN KEY (genre_id) + REFERENCES Genre (id) +); + +/* Define table for storing artists */ +CREATE TABLE Artist ( + id INT AUTO_INCREMENT, + first_name VARCHAR(25) NOT NULL, + last_name VARCHAR(25), + PRIMARY KEY (id) +); + +/* Define table for storing albums */ +CREATE TABLE Album ( + upc CHAR(12), + title VARCHAR(50) NOT NULL, + release_year YEAR(4), + compilation BOOLEAN NOT NULL DEFAULT 0, + price DECIMAL(5, 2) unsigned NOT NULL, + genre_id INT, + PRIMARY KEY (upc), + FOREIGN KEY (genre_id) + REFERENCES Genre (id) +); + + +/* Define table for storing single tracks +ON DELETE CASCADE will ensure no track +is left that isn't linked to an album. +ON UPDATE CASCADE will inherit any changes +to the Album UPC (Universal Product Code). +A composite PRIMARY KEY is used here to +ensure the track_number is unique +on any given album */ +CREATE TABLE Track ( + name VARCHAR(50) NOT NULL, + album_upc CHAR(12) NOT NULL, + track_number INT, + PRIMARY KEY (album_upc, track_number), + FOREIGN KEY (album_upc) + REFERENCES Album (upc) + ON UPDATE CASCADE + ON DELETE CASCADE +); + +/* Define table for storing customers */ +CREATE TABLE Customer ( + id INT AUTO_INCREMENT, + username VARCHAR(25) UNIQUE NOT NULL, + email_address VARCHAR(50) UNIQUE NOT NULL, + password VARCHAR(64), /* will store a hashed password */ + first_name VARCHAR(50) NOT NULL, + last_name VARCHAR(50) NOT NULL, + address_1 VARCHAR(50) NOT NULL, + address_2 VARCHAR(50), + postcode VARCHAR(10) NOT NULL, + PRIMARY KEY (id) +); + +/* Define table for storing orders */ +CREATE TABLE Transaction ( + id INT AUTO_INCREMENT, + customer_id INT NOT NULL, + delivery ENUM('first class','second class','next working day'), + PRIMARY KEY (id), + FOREIGN KEY (customer_id) + REFERENCES Customer(id) + ON DELETE CASCADE +); + +/* Define table for storing line items */ +CREATE TABLE LineItem ( + id INT AUTO_INCREMENT, + trans_id INT NOT NULL, + album_upc CHAR(12) NOT NULL, + quantity INT NOT NULL DEFAULT 1, + PRIMARY KEY (id), + FOREIGN KEY (trans_id) + REFERENCES Transaction (id) + ON DELETE CASCADE, + FOREIGN KEY (album_upc) + REFERENCES Album (upc) + ON DELETE CASCADE +); + +/* Define table to store customer 'wishes'. +Compile wishlists from this data. */ +CREATE TABLE Wish ( + customer_id INT, + album_upc INT, + PRIMARY KEY (customer_id, album_id), + FOREIGN KEY (customer_id) + REFERENCES Customer(id) + ON DELETE CASCADE, + FOREIGN KEY (album_upc) + REFERENCES Album (upc) + ON DELETE CASCADE +); + +/* Define table for storing customer ratingsfor albums */ +CREATE TABLE Rating ( + customer_id INT NOT NULL, + album_upc CHAR(12) NOT NULL, + score TINYINT unsigned NOT NULL, + PRIMARY KEY (customer_id, album_id), + FOREIGN KEY (customer_id) + REFERENCES Customer(id) + ON DELETE CASCADE, + FOREIGN KEY (album_upc) + REFERENCES Album (upc) + ON DELETE CASCADE +);