You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
401 lines
9.2 KiB
Markdown
401 lines
9.2 KiB
Markdown
---
|
|
marp: true
|
|
paginate: true
|
|
math: mathjax
|
|
theme: buutti
|
|
title: SQL Databases
|
|
---
|
|
|
|
# SQL Databases
|
|
|
|
<!-- headingDivider: 5 -->
|
|
<!-- class: invert -->
|
|
|
|
## What is SQL?
|
|
|
|
* SQL, Structured Query Language is a language used to organize and manipulate data in a database
|
|
* Originally developed by IBM in the 70's
|
|
* Quickly became the most popular database language
|
|
```sql
|
|
SELECT id, email
|
|
FROM users
|
|
WHERE first_name = 'Teppo';
|
|
```
|
|
|
|
## Relational Database Management Systems
|
|
|
|
* In relational databases, values are stored in *__tables__*
|
|
* Each table has *__rows__* and *__columns__*
|
|
* Data is displayed in a two-dimensional matrix
|
|
* Values in a table are related to each other
|
|
* Values can also be related to values in other tables
|
|
* A relational database management system (RDBMS) is a program that executes queries to relational databases
|
|
|
|
---
|
|
|
|

|
|
|
|
[https://db-engines.com/en/ranking](https://db-engines.com/en/ranking)
|
|
|
|
## PostgreSQL
|
|
|
|
* Free and open-source, cross-platform relational database management system
|
|
* Emphasizes extensibility and SQL compliance
|
|
* Fully ACID-compliant (atomicity, consistency, isolation and durability)
|
|
* Used in conjunction with ***pgAdmin***
|
|
* Administration and development platform for PostgreSQL
|
|
* Cross-platform, features a web interface
|
|
* Basically a control panel application for your PostgreSQL database
|
|
|
|
### PostgreSQL: Creating a Database
|
|
|
|
<div class='columns' markdown='1'>
|
|
<div markdown='1'>
|
|
|
|
With pgAdmin:
|
|
1) Right-click *Servers > my-postgres > Databases*
|
|
2) Select _Create > Database..._
|
|
3) Insert a name for the database and hit _Save_
|
|
|
|
</div>
|
|
<div markdown='1'>
|
|
|
|
With psql:
|
|
1) Enter command
|
|
```sql
|
|
CREATE DATABASE <database-name>;
|
|
```
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<div class='centered'>
|
|
|
|

|
|
|
|
</div>
|
|
|
|
### PostgreSQL: Querying
|
|
|
|
With pgAdmin:
|
|
|
|
1) Right-click _sqlpractice > Query tool..._
|
|
2) Insert a query into the _Query Editor_ and hit _Execute_ (F5)
|
|
|
|
<div class='columns23' markdown='1'>
|
|
<div markdown='1'>
|
|
|
|

|
|
|
|
</div>
|
|
<div markdown='1'>
|
|
|
|

|
|
|
|
</div>
|
|
</div>
|
|
|
|
---
|
|
|
|
With psql:
|
|
|
|
1) List all available databases with `\l`
|
|
2) Connect to the created database with `\c <database-name>`
|
|
3) List all tables in the database with `\dt`
|
|
4) Type a query and press enter
|
|
* Here's an [example query](code-examples/example-query.sql)
|
|
|
|
## Editing Data with pgAdmin
|
|
|
|
<div class='columns' markdown='1'>
|
|
<div markdown='1'>
|
|
|
|
* Inspect and edit data in pgAdmin by right-clicking a table and selecting _View/Edit Data_
|
|
|
|
</div>
|
|
<div markdown='1'>
|
|
|
|

|
|
|
|
</div>
|
|
</div>
|
|
|
|
---
|
|
|
|
<div class='columns' markdown='1'>
|
|
<div markdown='1'>
|
|
|
|
* Individual values in the table can be directly modified by double clicking the value and then editing the value in the visual user interface
|
|
* Save the changes by pressing the _Save Data Changes_ button
|
|
|
|
</div>
|
|
<div markdown='1' class='centered'>
|
|
|
|

|
|

|
|
|
|
</div>
|
|
</div>
|
|
|
|
## Exercise 1: Preparing the database
|
|
<!--_class: "exercise invert" -->
|
|
|
|
Using either PgAdmin or PSQL,
|
|
|
|
1) Create a new database called `sqlpractice`
|
|
2) Insert the provided [example query](code-examples/example-query.sql) to the new database
|
|
3) Verify that the query has created new tables to your database
|
|
|
|
## Basic SQL queries
|
|
|
|
* `SELECT`
|
|
* `INSERT`
|
|
* `DELETE`
|
|
* `UPDATE`
|
|
* `CREATE` & `DROP`
|
|
|
|
### Querying data with `SELECT`
|
|
|
|
* Syntax:
|
|
```sql
|
|
SELECT column1, column2, column3 FROM table_name;
|
|
```
|
|
* Examples:
|
|
```sql
|
|
SELECT full_name, email FROM users;
|
|
SELECT full_name AS name, email FROM users;
|
|
SELECT * FROM users;
|
|
```
|
|
|
|
### Filtering data with `WHERE`
|
|
|
|
* Syntax:
|
|
```sql
|
|
SELECT column1, column2 FROM table_name WHERE condition;
|
|
```
|
|
<div class='columns12' markdown='1'>
|
|
<div markdown='1'>
|
|
|
|
* Text is captured in **_single quotes_**.
|
|
* `LIKE` condition uses the `%` sign as a wildcard.
|
|
* `IS` and `IS NOT` are also valid operators.
|
|
|
|
</div>
|
|
<div markdown='1'>
|
|
|
|
* Example:
|
|
```sql
|
|
SELECT full_name FROM users
|
|
WHERE full_name = 'Teppo Testaaja';
|
|
|
|
SELECT * FROM books WHERE name LIKE '%rr%';
|
|
SELECT * FROM books WHERE author IS NOT null;
|
|
```
|
|
|
|
</div>
|
|
</div>
|
|
|
|
### Ordering data with `ORDER BY`
|
|
|
|
* Syntax:
|
|
```sql
|
|
SELECT column1 FROM table_name ORDER BY column1 ASC;
|
|
```
|
|
* Examples:
|
|
```sql
|
|
SELECT full_name FROM users
|
|
ORDER BY full_name ASC;
|
|
|
|
SELECT full_name FROM users
|
|
ORDER BY full_name DESC;
|
|
```
|
|
|
|
### Combining data with `JOIN`
|
|
|
|
* Also known as `INNER JOIN`
|
|
* Corresponds to ***intersection*** from [set theory](https://en.wikipedia.org/wiki/Set_theory)
|
|
|
|
<div class='centered'>
|
|
|
|

|
|
|
|
</div>
|
|
|
|
#### JOIN examples
|
|
|
|
```sql
|
|
SELECT
|
|
users.id, users.full_name, borrows.id,
|
|
borrows.user_id, borrows.due_date, borrows.returned_at
|
|
FROM users
|
|
JOIN borrows ON
|
|
users.id = borrows.user_id;
|
|
```
|
|
|
|
```sql
|
|
SELECT
|
|
U.full_name AS name,
|
|
B.due_date AS due_date,
|
|
B.returned_at AS returned_at
|
|
FROM users AS U
|
|
JOIN borrows AS B ON
|
|
U.id = B.user_id;
|
|
```
|
|
|
|
### Combining with `LEFT JOIN`
|
|
|
|
<div class='columns' markdown='1'>
|
|
<div markdown='1'>
|
|
|
|
* Also known as `LEFT OUTER JOIN`
|
|
* Example:
|
|
```sql
|
|
SELECT
|
|
U.full_name AS name,
|
|
B.due_date AS due_date,
|
|
B.returned_at AS returned_at
|
|
FROM users AS U
|
|
LEFT JOIN borrows AS B ON
|
|
U.id = B.user_id;
|
|
```
|
|
|
|
</div>
|
|
<div markdown='1'>
|
|
|
|

|
|
|
|
</div>
|
|
</div>
|
|
|
|
### Exercise 2: Querying the library
|
|
<!--_class: "exercise invert" -->
|
|
|
|
Using SQL queries, get
|
|
|
|
1) all columns of `borrows` that are borrowed before `2020-10-27`
|
|
2) all columns of `borrows` that are returned
|
|
3) columns `user.full_name` and `borrows.borrowed_at` of the user with an `id` of 1
|
|
4) columns `book.name`, `book.release_year` and `language.name` of all books that are released after 1960
|
|
|
|
### Inserting data with `INSERT`
|
|
|
|
* Syntax
|
|
```sql
|
|
INSERT INTO table_name (column1, column2, column3) VALUES (value1, value2, value3);
|
|
```
|
|
* Example
|
|
```sql
|
|
INSERT INTO users (full_name, email, created_at)
|
|
VALUES ('Pekka Poistuja', 'pekka.poistuja@buutti.com', NOW());
|
|
```
|
|
* Since id is not provided, it will be automatically generated.
|
|
|
|
### Updating data with `UPDATE`
|
|
|
|
* Syntax
|
|
```sql
|
|
UPDATE table_name SET column1 = value1, column2 = value2 WHERE condition;
|
|
```
|
|
* *__Notice:__* if a condition is not provided, all rows will be updated!
|
|
* If updating only one row, it is usually best to use `id`.
|
|
* Example
|
|
```sql
|
|
UPDATE users SET email = 'taija.testaaja@gmail.com' WHERE id = 2;
|
|
```
|
|
|
|
## Removing data with `REMOVE`
|
|
|
|
* Syntax
|
|
```sql
|
|
DELETE FROM table_name WHERE condition;
|
|
```
|
|
* Again, if the _condition_ is not provided, `DELETE` affects _all_ rows
|
|
* Before deleting, it is a good practice to execute an equivalent `SELECT` query to make sure that only the proper rows will be affected.
|
|
* Example:
|
|
```sql
|
|
SELECT * FROM users WHERE id = 5;
|
|
DELETE FROM users WHERE id = 5;
|
|
```
|
|
|
|
### Exercise 3: Editing data
|
|
<!--_class: "exercise invert" -->
|
|
|
|
1) Postpone the due date of the borrow with an `id` of `1` by two days in the `borrows` table
|
|
2) Add a couple of new books to the `books` table
|
|
3) Delete one of the borrows.
|
|
|
|
### Initializing data with `CREATE TABLE`
|
|
|
|
* Before data can be manipulated, a database and its tables need to be initialized.
|
|
|
|
<div class='columns' markdown='1'>
|
|
<div markdown='1'>
|
|
|
|
* Syntax
|
|
```sql
|
|
CREATE TABLE table_name (
|
|
column1 datatype,
|
|
column2 datatype,
|
|
...
|
|
);
|
|
```
|
|
|
|
</div>
|
|
<div markdown='1'>
|
|
|
|
* Example:
|
|
```sql
|
|
CREATE TABLE "users" (
|
|
"id" SERIAL PRIMARY KEY,
|
|
"full_name" varchar NOT NULL,
|
|
"email" varchar UNIQUE NOT NULL,
|
|
"created_at" timestamp NOT NULL
|
|
);
|
|
```
|
|
|
|
</div>
|
|
</div>
|
|
|
|
### Removing data with `DROP`
|
|
|
|
* In order to remove tables or databases, we use a `DROP` statement
|
|
```sql
|
|
DROP TABLE table_name;
|
|
DROP DATABASE database_name;
|
|
```
|
|
* These statements do not ask for confirmation and there is no undo feature. Take care when using a drop statement.
|
|
|
|
---
|
|
|
|
* I'm legally obliged to include this XKCD comic here.
|
|
|
|

|
|
|
|
## NoSQL
|
|
|
|
* In addition to SQL databases, there's ***NoSQL***
|
|
* There are many differing definitions, but...
|
|
* most agree that NoSQL databases store data in a format other than tables
|
|
* They can still store relational data - just _differently_
|
|
* Four different database types:
|
|
* Document databases
|
|
* Key-value databases
|
|
* Wide-column stores
|
|
* Graph databases
|
|
* Example database engines include [MongoDB](https://www.mongodb.com/), [Redis](https://redis.io/) and [Cassandra](https://cassandra.apache.org/_/index.html)
|
|
* For more info, see [MongoDB: What is NoSQL?](https://www.mongodb.com/resources/basics/databases/nosql-explained)
|
|
|
|
|
|
## Object-Relational Mappers
|
|
|
|
* Object-Relational Mappers, or ORMs allow the developer to write code instead of SQL to perform CRUD operations on their database
|
|
* An abstraction layer between code and database
|
|
* Can make database logic easier to read and write
|
|
* Prevents SQL injection by sanitizing input (see the comic before...)
|
|
* ...but sometimes you'd rather just write the SQL queries themselves
|
|
* Some popular ORMs:
|
|
* Hibernate (Java)
|
|
* EFCore (.NET)
|
|
* Sequelize (Node.js)
|
|
* TypeORM (TypeScript)
|