- MySQL Master Bootcamp
- Section 2: Overview
- Section 4: Inserting Data (And More)
- Section 7: String Functions
- Section 8: Refining Our Selections
- Section 9: Aggregate Functions
- Section 10: Data Types
- Section 11: Logical Operators
- Section 12: Relationships - One to Many
- Section 14: Many-To-Many
- Section 14: Instagram Database Clone
- Section 16: Introducing Node
- Section 17: Building The Web App
- Section 18: Database Triggers
- Further Learning
- Wildcards in SQL:
%
(Any character)_
(Any character, but only results where there are the same amount of characters as there are underscores)- Escape the character if you need to use either
- To comment in SQL, use
--
,/* */
, or#
- Some of the most common DBMS's (Database Management Systems):
- PostgreSQL
- MySQL
- Oracle Database
- SQLite
- Types cannot be mixed and are specified upon creation. (Statically Typed)
- A collection of data
- I.e. a phone book
- A method of accessing and manipulating that data
- A structured set of computerized data with an accessible interface
- DMS or Relational Database Management System refers to an interface
for the data.
- The database is the data itself and all of it. The DBMS is the UI for it.
- They're often referred to as the same thing
- The language we use to "talk" to our databases
- SQL is used to write inside of DBMS's such as MySQL
- There is a standard for how SQL should work, and all DBMS's are tasked with implementing that standard and making them work.
- It's very easy to switch after learning SQL
- What makes databases (DBMS) unique are the features they offer, not the language.
mysql-ctrl {command}
start
(will start mysql)stop
(will stop mysql)cli
(Will stop and then start mysql)- Stands for Command Line Interface
use {database_name}
(Changes the database being used)source {database_filename}
(Run code from a query file)desc {table}
(Shows the contents of a table)- Shorthand for
SHOW COLUMNS FROM {tablename}
- Shorthand for
create {database_name}
(Creates a database)drop {database_name}
(permanently destroys a database)SELECT database()
(Tells you the current database being used)show {tables | databases}
(Shows all tables or databases)
A table is a collection of related data held in a structured format within a database.
- Columns (Headers)
Numeric | String | Date |
---|---|---|
INT | CHAR | DATE |
SMALLINT | VARCHAR | DATETIME |
TINYINT | BINARY | TIMESTAMP |
MEDIUMINT | VARBINARY | TIME |
BIGINT | BLOB | YEAR |
DECIMAL | TINYBLOB | |
NUMERIC | MEDIUMBLOB | |
FLOAT | LONGBLOB | |
DOUBLE | TEXT | |
BIT | TINYTEXT | |
MEDIUMTEXT | ||
LONGTEXT | ||
ENUM |
- INT (whole number)
- varchar (variable-length string between 1-255 characters)
- Table names should be pluralized. It's because a table describes multiple of the thing, not just one.
CREATE TABLE tablename
(
column_name data_type,
column_name data_type,
);
/* Example: */
CREATE TABLE cats
(
name VARCHAR(100),
age INT
);
SHOW WARNINGS
(Shows all warnings)size
is a reserved word. Don't use it for a column name.
Incorrect syntax:
INSERT INTO <tablename>(column, column)
VALUES (value, value);
The preferred way of writing:
INSERT INTO <tablename>
(column,
column)
VALUES (value,
value);
- The order which the columns are used matters, as the order for the values being inserted must be in the same order.
INSERT INTO <tablename>
(column type, column type)
VALUES (value, value),
(value, value),
(value, value);
- When a value is not given for a column,
NULL
is put in its place. - To require a value for a field:
CREATE TABLE <tablename>(column type NOT NULL);
- The
NOT NULL
part throws awarning
if the value is empty when being inserted.
CREATE TABLE <tablename>
(
column type DEFAULT <default_value>
)
- It's important to specify
NOT NULL
as a value can still manually be set toNULL
.
- If you have multiple entries, you need to be able to tell them apart. That's when you use a Primary Key (A unique identifier).
CREATE TABLE unique_cats (cat_id INT AUTO_INCREMENT NOT NULL
,name VARCHAR(100)
,age INT
,PRIMARY KEY(cat_id) /* Give the name of the field */
);
/* The second way to write it is to put PRIMARY KEY at the end */
CREATE TABLE unique_cats (cat_id INT AUTO_INCREMENT NOT NULL PRIMARY KEY
,name VARCHAR(100)
,age INT
);
AUTO_INCREMENT
will automatically increase the value for each entry.- It will appear under
EXTRA
whenDESC
is used.
- It will appear under
It's possible to use two primary keys to make sure there's no duplicates of the pair of those columns:
-- Likes Table.
-- Ensures one photo will not have the same user liking multiple times
-- as both the photo_id and user_id pair must be unique in an entry
CREATE TABLE likes (
photo_id INT NOT NULL,
user_id INT NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
FOREIGN KEY(photo_id) REFERENCES photos(id),
FOREIGN KEY(user_id) REFERENCES users(id),
PRIMARY KEY(user_id, photo_id)
);
- C reate
-
INSERT INTO
-
- R ead
-
SELECT
- Can use
*
or the name of acolumn
or multiplecolumns
-
SELECT column, column from <table>;
- Can use
-
- U pdate
-
UPDATE <table> SET <column>=<value> WHERE <column>=<value>
-
- D elete
-
DELETE FROM <table> WHERE column=<value>;
Common in many areas of web development, not just databases.
Used to find specific information, not just check in on the table
- I.e. Finding someone by their username and checking that their password matches
- Used almost everywhere
- Case-insensitive
SELECT * FROM <table> WHERE <column>=<value>;
/* Example */
SELECT * FROM cats WHERE age=4;
Specify how our data should be displayed back to us. Changes the name of the column temporarily to what's specified when it's displayed in a table.
SELECT column AS <temporary name>, column FROM <table>
/* Example */
SELECT cat_id AS id, name FROM cats;
- In this example
cat_id
has been changed toid
. It's useful for when there are two databases with the same column. This way, you can tell them apart.
Good rule of thumb before updating is to run the equivalent SELECT
to make sure
you're updating the correct data.
UPDATE table SET column=<value>
WHERE column=<value>;
/* Example */
UPDATE cats SET breed='Shorthair'
WHERE breed='Tabby';
Same syntax as SELECT
, except without a column
after DELETE
.
DELETE FROM <table> WHERE column=<value>;
- The IDs will not shift when an item is deleted, as they're generated at
creation.
- This can be problematic if they were changed, as the IDs are often stored in multiple tables.
CONCAT
Combine data for cleaner output
SELECT CONCAT(column, column, 'text', ...) FROM <table>;
/* Example s*/
SELECT CONCAT(author_fname, ' ', author_lname) AS 'Full Name' FROM books;
SELECT author_fname AS first, author_lname AS last,
CONCAT(author_fname, ' ', author_lname) AS 'Full Name'
FROM books;
When dealing with multiple values that will all need a separator, using CONCAT_WS
will save time:
SELECT CONCAT_WS(<separator>, column, column, ...) FROM <table>
Work with parts of a string. SUBSTR()
is the shorthand.
SELECT SUBSTRING(column, start, end) FROM <table>;
SELECT SUBSTRING('Hello World', 1, 4);
SELECT SUBSTR('Hello World', 1, 4);
- Unlike other programming languages like Python, the index does not start at 0.
- Only giving one number will produce all letters from there to the end.
- i.e.
SELECT SUBSTRING('Hello World', 7)
will giveWorld
- Negative numbers are also applicable
- i.e.
SELECT CONCAT
(
SUBSTRING(column, start, end),
column/text,
column/text
) AS 'My Concat'
FROM <table>;
Replace parts of a string
SELECT REPLACE(text, text_to_replace, replacement_text)
FROM <table>;
- Replaces all occurrences of
text_to_replace
withreplacement_text
in the string - It is case-sensitive
Reverses a string
SELECT REVERSE(column) FROM <table>;
Counts characters in a string. The long-form is CHARACTER_LENGTH
.
SELECT CHAR_LENGTH(column) FROM <table>;
Converts the string to either upper or lower-case.
SELECT UPPER(column) FROM <table>;
SELECT LOWER(column) FROM table;
- Using Parenthesis
()
can create a sub-query that will execute first.- This is slow though as
SELECT
is slow and two queries are being run
- This is slow though as
Used in conjunction with SELECT
. If there's duplicates, it will only give the
unique ones.
- Comes right after
SELECT
SELECT DISTINCT column FROM <table>;
-- Example
SELECT DISTINCT author_lname FROM books;
- To get a
DISTINCT
of multiple columns, you can either:- Use
CONCAT
- Use multiple columns:
-
SELECT DISTINCT column, column FROM <table>
- Will only select unique columns where both values are unique. Applies it to the entire row.
-
- Use
Sorting our results
SELECT column FROM <table> ORDER BY column;
-- Example
SELECT DISTINCT author_lname, author_fname
FROM books
ORDER BY author_lname;
- Ascending by default. Can be changed by assing
DESC
after the columns to sort by:-
SELECT DISTINCT author_lname, author_fname FROM books ORDER BY author_lname DESC;
-
- Each selected column is given an index number starting from 1 that can be used
as a shortcut, rather than typing the column:
-
SELECT DISTINCT author_lname, author_fname FROM books ORDER BY 2; -- This is ordering by author_fname
-
- It's possible to
ORDER BY
multiple columns. They will be ordered from left to right, prioritizing the column before it.-
SELECT DISTINCT title, author_lname, author_fname FROM books ORDER BY title, author_lname;
-
Specify a number for how many results to select.
- Used in conjunction with
ORDER BY
SELECT column FROM <table> LIMIT <int>;
-- Examples
SELECT * FROM books LIMIT 3;
SELECT title, released_year FROM books
ORDER BY released_year DESC LIMIT 5;
- A range
<int>, <int>
can be given instead of a single number. The first number is the offset, and the second number is how many rows to fetch starting there (including that row)- An example of when to use this is a blog site for pagination.
- To retrieve all rows from a certain offset, a number larger than the amount of rows can be given (i.e. 99999999999999)
Better searching. Allows the use of wildcards and partial matches using patterns.
SELECT * FROM <table> WHERE column LIKE '%<value>%';
-- Examples
-- Find all rows where author_fname contains 'da'
SELECT title, author_fname FROM books WHERE author_fname LIKE '%da%';
-- Find all rows where author_fname starts with 'da'
SELECT title, author_fname FROM books WHERE author_fname LIKE 'da%';
-- Find all rows where author_fname ends with 'da'
SELECT title, author_fname FROM books WHERE author_fname LIKE 'da%';
SELECT "(235)234-0987" LIKE '(___)___-____' ;
- This is not case-sensitive
Count how many of something are in a specific column, or all columns.
SELECT COUNT(*) FROM <table>;
SELECT COUNT(column) FROM <table>;
SELECT COUNT(DISTINCT column) FROM <table>;
SELECT COUNT(DISTINCT column, column) FROM <table>;
- Using
*
says to count all rows intable
. DISTINCT
needs to be used inside the parenthesis when usingCOUNT
.- Multiple rows can only be used when
DISTINCT
is being used. - Using multiple columns when using
DISTINCT
will only return rows where both columns are unique.
- Multiple rows can only be used when
- A super row is created and displayed
Summarizes or aggregates identical data into single rows
SELECT column, column FROM <table>
GROUP BY column;
-- COUNT here is counting how many sub-rows are in each row.
SELECT column, COUNT(*) FROM <table>
GROUP BY column;
-- Grouping by multiple columns will make sure both values are unique
SELECT column, column, COUNT(*) FROM <table>
GROUP BY column, column;
-- Example
SELECT title, author_lname FROM books
GROUP BY author_lname;
- Creates a super row containing all entries that meet the criteria, even though it may not be visually seen when displayed.
- Meant to be used with another aggregate function like
COUNT()
, and not by itself.- Newer versions will throw an error if it's used by itself.
- The
GROUP BY
is run first, and theSELECT
applies to the groups created.
Identify minimum and maximum values in a table.
SELECT MIN(column) FROM <table>;
SELECT MAX(column) FROM <table>;
- If used on a string, it will find the shortest or longest string
Using MIN
or MAX
with another column will retrieve the first value in the
other column, independent of the max or minimum value.
SELECT * FROM books
WHERE pages = (SELECT MIN(pages)
FROM books);
- The sub-query will execute first.
- Slow method
SELECT * FROM books
ORDER BY pages LIMIT 1;
SELECT author_fname,
author_lname,
MIN(released_year)
FROM books
GROUP BY author_lname,
author_fname;
Adds all values in a column.
SELECT SUM(column) FROM <table>;
- Does not work for strings. Will return
0
.
SELECT AVG(column) FROM <table>;
- Does not work for strings. Will return
0
. - Gives 4 decimal points, but does not round up the result.
- Even if it's an even number, it will still give four
0
's.
- Even if it's an even number, it will still give four
Rounds a number up to a given digit count
SELECT ROUND(1.234565, 2);
-> 1.23
CHAR
has a fixed length that's specified upon table creation.- If it's fewer, it will add spaces to make it the specified number.
- If it's longer, the rest will be chopped off.
- Faster for fixed length text
- Examples can be:
- State abbreviations: CA, NY
- Yes/No flags: Y/N
- Sex: M/F
- Examples can be:
VARCHAR
has a length that is specified, but does not have to be met with each value.
Value | Char(4) | Storage | Varchar(4) | Storage |
---|---|---|---|---|
'' | ' ' | 4 bytes | '' | 1 bytes |
'ab' | 'ab ' | 4 bytes | 'ab' | 3 bytes |
'abcd' | 'abcd' | 4 bytes | 'abcd' | 5 bytes |
'abcdefg' | 'abcdefg' | 4 bytes | 'abcdefg' | 5 bytes |
Whole numbers
Fixed point type, and calculations are exact.
DECIMAL(<total num of digits>, <digits after decimal>);
-- Example
DECIMAL(5, 2); -- 5 digits long, 2 decimal points after the number
DECIMAL
has a 0-30 range for decimal places.- The decimal places count towards the total amount of digits.
- If a larger number is given than the amount of digits allowed, it will default to 9's equal to the amount of allowed digits.
- Always use
DECIMAL
, unless precision doesn't matter.
Floating-point types and calculations are approximate.
Data Type | Memory Needed | Precision Issues |
---|---|---|
FLOAT | 4 Bytes | ~7 digits |
DOUBLE | 8 Bytes | ~15 digits |
- After the above amount of digits under precision, each type will begin having precision issues.
More info can be found at DateTime Fucntions Documentation and DateTime Documentation
DATE
-YYYY-MM-DD
(Value with a date, but no time)TIME
-HH:MM:SS
(Stores value with a time, but no date)DATETIME
-YYYY-MM-DD HH:MM:SS
(Values with a Date and Time)- Use case: Storing when a row in a column is created
CURDATE()
(Gives current date as aDATE
)- Same thing as
CURRENT_DATE
- Same thing as
CURTIME()
(Gives current time as aTIME
)- Same thing as
CURRENT_TIME
- Same thing as
NOW()
(Gives current datetime as aDATETIME
)- Same thing as
CURRENT_TIMESTAMP
- Same thing as
DAY()
(Extracts day fromDATE
orDATETIME
)DAYNAME()
(Extracts & returns the name of the weekday)DAYOFWEEK()
(Extracts & returns the number of that day within a week)DAYOFYEAR()
(Extracts & returns the day of the year)MINUTE()
(Extracts the minute)MONTH()
(Extracts the month of the year)MONTHNAME()
(Extracts & returns the name of the month)
SELECT DATE_FORMAT('2019-10-04 22:23:00', '%W %M %Y')
-> Sunday October 2009
-- Datediff
SELECT DATEDIFF(<datetime/date>, <datetime/date>);
-> <Resulting datetime/date>
-- Example
mysql> SELECT DATEDIFF('2007-12-31 23:59:59','2007-12-30');
-> 1
-- DATE_ADD
SELECT DATE_ADD(<datetime/date, INTERVAL <int> <Unit of time>);
-> <Resulting datetime/date>
-- Example
SELECT DATE_ADD('2018-05-01',INTERVAL 1 DAY);
-> '2018-05-02'
- It's not possible to chain together additions and subtractions this way.
It's also possible to just use +/-
instead of a function.
SELECT <datetime/date> + INTERVAL <int> <Unit of time> FROM <table>;
SELECT <datetime/date>
+ INTERVAL <int> <Unit of time>
+ INTERVAL <int> <Unit of time>
FROM <table>;
- It's possible to chain together additions and subtractions this way.
When used in tables, it's great to set DEFAULT
to NOW()
.
TIMESTAMP
supports1970-01-01 00:00:01.000000
to2038-01-19 03:14:07.999999
DATETIME
supports1000-01-01 00:00:00.000000
to9999-12-31 23:59:59.999999
TIMESTAMP
takes up half as many bytes asDATETIME
Used in table creation. Says that whenever the table is updated, do that thing.
CREATE TABLE <table> (
column <type> DEFAULT <value> ON UPDATE <function>
)
-- Example
CREATE TABLE comments (
content_id INT NOT NULL AUTO_INCREMENT,
content VARCHAR(100),
modified_at TIMESTAMP DEFAULT NOW() ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY(content_id)
)
CREATE <table> (
column YEAR(4) -- amount of numbers in the year
)
YEAR(2)
is deprecated
- When comparing
CHAR
's, it goes off ASCII values.
Not equal to
SELECT column FROM <table> WHERE column != <value>;
SELECT column FROM <table> WHERE column NOT LIKE <value>;
Check that a value is greater than another value.
SELECT column FROM <table> WHERE <value> > <value>;
Check that a value is greater than or equal to another value.
SELECT column FROM <table> WHERE <value> >= <value>;
Check that a value is less than another value.
SELECT column FROM <table> WHERE <value> < <value>;
Check that a value is less than or equal to another value.
SELECT column FROM <table> WHERE <value> <= <value>;
SELECT column FROM <table> WHERE <value>=<value> AND <value>=<value>;
SELECT column FROM <table> WHERE <value>=<value> && <value>=<value>;
SELECT column FROM <table> WHERE <value>=<value> OR <value>=<value>;
SELECT column FROM <table> WHERE <value>=<value> || <value>=<value>;
Converts a value to a different type for use in an expression.
CAST('2017-05-02' AS DATETIME);
-- Example
SELECT birthdate FROM people
WHERE birthdate BETWEEN CAST('2017-05-02') AND CAST('2017-06-02');
Find a value between two values. Quicker than writing
<value> >= <value> && <value> <= <value>
SELECT column FROM <table> WHERE column BETWEEN <value> AND <value>;
- The
AND
here is not the same as the&&
operator, and must always be paired withBETWEEN
.
Find a value between two values. Quicker than writing
<value> >= <value> && <value> <= <value>
SELECT column FROM <table> WHERE column NOT BETWEEN <value> AND <value>;
- The
AND
here is not the same as the&&
operator, and must always be paired withNOT BETWEEN
.
Search that a value is in or not in a value.
-- In
SELECT column FROM <table>
WHERE column IN (<value to find>, <value to find>, <value to find>);
-- Not In
SELECT column FROM <table>
WHERE column NOT IN (<value to find>, <value to find>, <value to find>);
column
must be in or not in the values in order to meet criteria. It's basically creating a list and checking that the column entry is in that list.- Can be slow when given a long list, as it iterates through each value, checking against them.
Modulo operator. Divides by a given value, and returns the remainder.
SELECT column FROM <table>
WHERE value % <value> = <value>;
If a certain case is met, then perform a function.
- Control flow statement and the sql version of
if else then
statements.
SELECT column,
CASE
WHEN <condition> THEN <function or value>
ELSE <function or value>
END AS <name of created column>
FROM <table>;
-- Example
SELECT title, released_year,
CASE
WHEN released_year >= 2000 THEN 'Modern Lit'
WHEN released_year >= 2015 THEN 'Super Modern Lit'
ELSE '20th Century Lit'
END AS GENRE
FROM books;
column
is not necessary to select, and just the case can be selected.AS
is not necessary and is anALIAS
.
Checks a condition, and outputs a result based on it.
SELECT
IF(<condition>, <result if true>, <result if false>)
FROM <table>;
- Great when you don't need multiple outputs or conditional checks.
SELECT
first_name,
last_name,
order_date,
amount IS NULL '0' -- Shorthand
FROM customers
LEFT JOIN orders
ON customers.id = orders.customer_id;
GROUP BY customers.id
ORDER BY total_spent;
IFNULL(<value1>, <value to sub if value1 is null)
SELECT
first_name,
last_name,
order_date,
IFNULL(SUM(amount), 0) AS total_spent -- Checks if null, and provides second argument if so
FROM customers
LEFT JOIN orders
ON customers.id = orders.customer_id;
GROUP BY customers.id
ORDER BY total_spent;
- When working with multiple tables, be explicit with which column belongs to
which table.
- Use
customers.id
instead ofid
.
- Use
- Animated visual of joins
- One to One Relationship
- Example: A customer has a customer detail table. Each customer has their own customer detail entry.
- One to Many Relationship
- Example: A book has many reviews. All of those reviews belong to one book.
- The most common
- Refers to how many values in a separate table each can have a relationship to, not how many tables.
- Many to Many Relationship
- Example: A two-way relationship. Books can have many authors, and those authors can have many books.
- Refers to how many values in a separate table each can have a relationship to, not how many tables.
The most common relationship.
- The problem with having all the data in one table is duplicated info, and
NULL
entries where the data was not used for that row.
Customers | Orders |
---|---|
customer_id | order_id |
first_name | order_date |
last_name | amount |
customer_id |
- The
customer_id
is what connects the two tables.
The unique identifier for that table. There's only one of each value for that column.
Reference to another table, within a table.
- Refers to the
PRIMARY KEY
of a different table, creating the relationship. - Creates a constraint
- Throws an error when trying to add a non-existent key from the other table
- Throws an error when trying to delete some data that other data is dependent upon.
-- Used at the end of table creation, as the last value
FOREIGN KEY(<key_from_current_table>) REFERENCES <table>(<PRIMARY KEY from that table>)
-- Example
CREATE TABLE customers (
id INT NOT NULL AUTO_INCREMENT,
first_name,
last_name,
email UNIQUE,
PRIMARY KEY(id)
);
CREATE TABLE orders (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
order_date DATE,
amount DECIMAL(8, 2),
customer_id INT,
FOREIGN KEY(customer_id)
REFERENCES customers(id)
);
- It's conventional when using a
FOREIGN KEY
to have the column be named the of the table it's referencing, followed by an underscore _, and then the name of the column.customer_id
- Known as an implicit join
When a value is deleted that has a corresponding value from the foreign table, delete that value as well.
CREATE TABLE orders (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
order_date DATE,
amount DECIMAL(8, 2),
customer_id INT,
FOREIGN KEY(customer_id)
REFERENCES customers(id)
ON DELETE CASCADE
Almost never used and is an Implicit Inner-Join
SELECT * FROM table, table;
SELECT * FROM customers, orders WHERE customers.id = customer_id;
Explicit Inner-Join
SELECT * FROM table
JOIN <table to join>
ON <key from table 1> = <key from table 2>;
-- You can leave off INNER as it's implied
SELECT * FROM table
INNER JOIN <table to join>
ON <key from table 1> = <key from table 2>;
-- Examples
SELECT * FROM customers
JOIN orders
ON customers.id = orders.customer_id;
SELECT first_name, last_name, order_date, SUM(amount) AS total_spent FROM customers
JOIN orders
ON customers.id = orders.customer_id
GROUP BY orders.customer_id
ORDER BY total_spent DESC;
JOIN
says the table to joinON
will only add the value to the column being created if the two keys provided match.- The foreign key and primary key are typically provided.
Say there's table A and B. Selects everything from A, along with any matching records in B.
- Takes all from table A, and the union of table B.
- Common convention
SELECT * FROM table
LEFT JOIN <table to join>
ON <key from table 1> = <key from table 2>;
- An example of when to use this is if you're looking to see who's purchased with the business to email them.
Say there's table A and B. Selects everything from B, along with any matching records in A.
- Takes all from table B, and the union of table A.
- Not common convention
- Some IDE's and work environments don't even support it
SELECT * FROM table
RIGHT JOIN <table to join>
ON <key from table 1> = <key from table 2>;
An example of when to use this is if someone accidentally deleted some customers
from your database, and you need to know who. By doing a RIGHT JOIN
on your
orders, instead of a LEFT JOIN
, it will be NULL
for all customers that were
deleted.
SELECT
IFNULL(first_name, 'MISSING') as first,
IFNULL(last_name, 'USER') as last,
order_date,
amount,
SUM(amount)
FROM customers
RIGHT JOIN orders
ON customers.id = orders.customer_id
GROUP BY first_name, last_name
ORDER BY amount DESC;
CREATE TABLE reviewers (
id INT AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(100),
last_name VARCHAR(100)
);
CREATE TABLE series (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(100),
released_year YEAR(4),
genre VARCHAR(100)
);
CREATE TABLE reviews (
id INT AUTO_INCREMENT PRIMARY KEY,
rating DECIMAL(2, 1),
series_id INT,
reviewer_id INT,
FOREIGN KEY(series_id) REFERENCES series(id),
FOREIGN KEY(reviewer_id) REFERENCES reviewers(id)
);
DESC reviewers;
DESC series;
DESC reviews;
INSERT INTO series (title, released_year, genre) VALUES
('Archer', 2009, 'Animation'),
('Arrested Development', 2003, 'Comedy'),
("Bob's Burgers", 2011, 'Animation'),
('Bojack Horseman', 2014, 'Animation'),
("Breaking Bad", 2008, 'Drama'),
('Curb Your Enthusiasm', 2000, 'Comedy'),
("Fargo", 2014, 'Drama'),
('Freaks and Geeks', 1999, 'Comedy'),
('General Hospital', 1963, 'Drama'),
('Halt and Catch Fire', 2014, 'Drama'),
('Malcolm In The Middle', 2000, 'Comedy'),
('Pushing Daisies', 2007, 'Comedy'),
('Seinfeld', 1989, 'Comedy'),
('Stranger Things', 2016, 'Drama');
INSERT INTO reviewers (first_name, last_name) VALUES
('Thomas', 'Stoneman'),
('Wyatt', 'Skaggs'),
('Kimbra', 'Masters'),
('Domingo', 'Cortes'),
('Colt', 'Steele'),
('Pinkie', 'Petit'),
('Marlon', 'Crafford');
INSERT INTO reviews(series_id, reviewer_id, rating) VALUES
(1,1,8.0),(1,2,7.5),(1,3,8.5),(1,4,7.7),(1,5,8.9),
(2,1,8.1),(2,4,6.0),(2,3,8.0),(2,6,8.4),(2,5,9.9),
(3,1,7.0),(3,6,7.5),(3,4,8.0),(3,3,7.1),(3,5,8.0),
(4,1,7.5),(4,3,7.8),(4,4,8.3),(4,2,7.6),(4,5,8.5),
(5,1,9.5),(5,3,9.0),(5,4,9.1),(5,2,9.3),(5,5,9.9),
(6,2,6.5),(6,3,7.8),(6,4,8.8),(6,2,8.4),(6,5,9.1),
(7,2,9.1),(7,5,9.7),
(8,4,8.5),(8,2,7.8),(8,6,8.8),(8,5,9.3),
(9,2,5.5),(9,3,6.8),(9,4,5.8),(9,6,4.3),(9,5,4.5),
(10,5,9.9),
(13,3,8.0),(13,4,7.2),
(14,2,8.5),(14,3,8.9),(14,4,8.9);
SELECT * FROM series;
SELECT * FROM reviewers;
SELECT * FROM reviews;
SELECT
CONCAT_WS(" ", first_name, last_name) AS full_name,
title,
rating
FROM reviews
INNER JOIN reviewers
ON reviews.reviewer_id = reviewers.id
INNER JOIN series
ON reviews.series_id = series.id
ORDER BY rating DESC;
SELECT
first_name,
last_name,
COUNT(rating) AS "COUNT",
IFNULL(MIN(rating), 0.0) AS "MIN",
IFNULL(MAX(rating), 0.0) AS "MAX",
IFNULL(
ROUND(
AVG(rating),
2
),
"0.00"
) AS "AVG",
CASE
WHEN COUNT(rating) >= 1 THEN 'ACTIVE'
ELSE 'INACTIVE'
END AS STATUS
FROM reviewers
LEFT JOIN reviews
ON reviews.reviewer_id = reviewers.id
GROUP BY reviewers.id
ORDER BY STATUS;
- If you will not be referencing a table, you don't always need to store an
id
. - Ask questions before you start working with the data.
A few things we need to store:
- Users
- Photos
- Comments
- Likes
- Hashtags
- Followers / followees
The best solution is a combination of 1 and 2.
- Faster with uncommon tags.
- Fastest if working with common tags that are used often.
- Not as fast with uncommon tags
CREATE DATABASE ig_clone;
USE ig_clone;
-- Users Table
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) UNIQUE,
created_at TIMESTAMP DEFAULT NOW()
);
-- Photos Table
CREATE TABLE photos (
id INT AUTO_INCREMENT PRIMARY KEY,
image_url VARCHAR(255) NOT NULL,
user_id INT NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
FOREIGN KEY(user_id) REFERENCES users(id)
);
-- Comments Table
CREATE TABLE comments (
id INT AUTO_INCREMENT PRIMARY KEY,
comment_text VARCHAR(255) NOT NULL,
user_id INT NOT NULL,
photo_id INT NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
FOREIGN KEY(user_id) REFERENCES users(id),
FOREIGN KEY(photo_id) REFERENCES photos(id)
);
-- Likes Table
CREATE TABLE likes (
photo_id INT NOT NULL,
user_id INT NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
FOREIGN KEY(photo_id) REFERENCES photos(id),
FOREIGN KEY(user_id) REFERENCES users(id),
PRIMARY KEY(user_id, photo_id)
);
-- Followers Table
-- Who follows who
CREATE TABLE follows (
follower_id INT NOT NULL,
followee_id INT NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
FOREIGN KEY (follower_id) REFERENCES users(id),
FOREIGN KEY (followee_id) REFERENCES users(id),
PRIMARY KEY(follower_id, followee_id)
);
-- Tags Table
CREATE TABLE tags (
id INT AUTO_INCREMENT PRIMARY KEY,
tag_name VARCHAR(255) UNIQUE,
created_at TIMESTAMP DEFAULT NOW()
);
-- Photo Tags Table
-- Associate a tag with a photo
CREATE TABLE photo_tags (
photo_id INT NOT NULL,
tag_id INT NOT NULL,
FOREIGN KEY (photo_id) REFERENCES photos(id),
FOREIGN KEY (tag_id) REFERENCES tags(id),
PRIMARY KEY(photo_id, tag_id)
);
Acts like WHERE
, but takes grouped data and allows for filtering based off a
clause.
- This is necessary, because
WHERE
comes beforeGROUP BY
, which means it's impossible to filter the data usingWHERE
when trying to also group.
- Javascript for backend
- An implementation of javascript so that it can be used on the backend.
- Allows servers to be created so that another language like PHP or Ruby don't need to be used.
- With Express, you add the tools you need as you need them.
A better practice than using npm install <package>
is to use npm init
.
- This creates a package.json file and states what packages and their versions that have been installed.
- Run
npm install --save <package>
after creating the package, so that a record is saved of each package installed.
To install multiple packages:
npm install --save <package> <package> <package>
Templating language. An alternative to writing HTML that allows variables and code logic to be included.
SQL statements that are automatically run when a specified table is changed.
DELIMITER $$
CREATE TRIGGER trigger_name
trigger_time trigger_event ON table_name FOR EACH ROW
BEGIN
...
END;
$$
DELIMITER ;
trigger_time | trigger_event | ON | table_name |
---|---|---|---|
BEFORE | INSERT | photos | |
AFTER | UPDATE | users | |
DELETE |
- Options for creating the trigger.
- Whatever code is between
BEGIN
andEND
will run whenever the trigger is activated. - Examples of time to use this:
- Validating data.
- Enforce specific things on your data, such as not letting them sign up for your application unless they're 18. Prevent the insert.
- Not the best use as you can enforce this in the web app code.
- Manipulating tables
- An initial table triggering data in another.
- If you want to know when someone unfollowed someone else.
- An initial table triggering data in another.
- Validating data.
SHOW TRIGGERS
(Shows all triggers in a very unorganized mess)DROP TRIGGER <triggername>
(Drops a trigger)- Triggers make debugging hard, as you have no way of identifying that something
is happening because of it (It's all behind the scenes).
- Some people have a tendency to chain triggers together.
- Shopping carts where the total needs to be updates as things are put into a shopping cart
DELIMITER $$
CREATE TRIGGER must_be_adult
BEFORE INSERT ON people FOR EACH ROW
BEGIN
IF NEW.age < 18
THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Must be an adult!';
END IF;
END;
$$
DELIMITER ;
FOR EACH ROW
is default syntax.NEW
refers to new data about to be inserted.OLD
refers to data that was deleted.
- MySQL Errors (There are 3 parts):
- A numeric code (1146)> This number is MySQL-specific
- A five-character
SQLSTATE
value (42S02
).- The values are taken from ANSI SQL and ODBC and are more standardized.
- A message string (
MESSAGE_TEXT
) - textual description of the error
SIGNAL SQLSTATE '45000'
is anIF
condition. If error45000
appears, then do the following code.45000
is a wildcard generic state representing "unhandled user-defined exception".
DELIMITER $$
Changes the delimiter so that MySQL doesn't see each semicolon as a SQL expression. To create the trigger, the entire piece of code needs to be treated as one chunk.DELIMITER ;
changes the delimiter back to a semicolon.
DELIMITER $$
CREATE TRIGGER ig_trigger
BEFORE INSERT ON follows FOR EACH ROW
BEGIN
IF NEW.follower_id = NEW.followee_id
THEN
SIGNAL SQLSTATE "45000"
SET MESSAGE_TEXT = 'You cannot follow yourself!';
END IF;
END;
$$
DELIMITER ;
DELIMITER $$
CREATE TRIGGER unfollow_trigger
AFTER DELETE ON unfollows FOR EACH ROW
BEGIN
-- Syntax 1
INSERT INTO unfollows(follower_id, followee_id)
VALUES(OLD.follower_id, OLD.followee_id);
-- Syntax 2
INSERT INTO unfollows
SET follower_id = OLD.follower_id,
followee_id = OLD.followee_id;
END;
$$
DELIMITER ;
- https://www.educba.com/data-science/data-science-tutorials/mysql-tutorial/
- https://www.w3resource.com/mysql/mysql-tutorials.php
- https://www.geeksforgeeks.org/sql-tutorial/?ref=gcse
- https://www.mysqltutorial.org/
- https://www.w3schools.com/sql/
- https://www.geeksengine.com/database/sample/
- https://www.khanacademy.org/computing/computer-programming/sql/