Fix spelling mistakes

This commit is contained in:
Paul Copplestone committed 2021-02-27 18:30:06 +08:00
1 parent 72e944a00e
commit 2dcd78a79b
2 files changed
+18 -106

No files matched your search

-88
View File
@@ -1,88 +0,0 @@
---
title: A half-hour to learn SQL
description: Build a to do app with Postgres
author: Paul Copplestone
author_title: Supabase
author_url: https://github.com/kiwicopple
author_image_url: https://github.com/kiwicopple.png
authorURL: https://github.com/kiwicopple
image: /img/roboflow-og.png
tags:
- SQL
- Postgres
---
Imagine there was a messenger app which changed its policies to infringe on privacy. As a result you decided to build your own messenger application, one where you owned all the data. Where would you store that data? Perhaps a database? Perhaps a Relational Database? Perhaps PostgreSQL?
In this article, instead of focusing on one or two concepts, I'll try to go through as many Postgres snippets as I can. Along the way we will be building a Chat Application, very similar to Slack.
### Tables
Relational databases are made of `tables`. Tables are like "groups" of data. In our messenger app, we need to store messages. So let's create a table for it:
```sql
create table messages (
message text
);
```
This table has a `column` named `message`, for storing `text`. Sometimes we want to add some rules to our columns. For example I might want to ensure that the `message` column is never empty.
```sql
alter table messages
alter column message set not null;
```
We may also want to put some restrictions on our columns. For example we may want to reject any messages that are longer than 1000 characters.
```sql
alter table messages
add contraint message_less_than_1000
check( len(message) < 1000 );
```
There are a variety of different column types we can use. Perhaps we want to store a timestamp every time a message is created?
```sql
alter table messages
add column inserted_at
timestamp with time zone -- data type
default timezone('utc', now()) -- default value
not null;
```
Wow I went crazy with that one. I added a timestamp with the timezone included. I also made it default to the current time (UTC), and put a constraint to make sure it is never empty (`not null`).
How can we differentiate two messages that are the same?
text |
------ |
"Hello World" |
"Hello World" |
We can differentiate them with a unique key. This is called a `Primary Key`.
```sql
alter table messages
add column id serial primary key;
```
We made it a `serial`. That's a built-in "number" type, which will increment up every time. Now our data would look like:
id | text |
---- | -----
1 | "Hello World" |
2 | "Hello World" |
### Data
Adding data to our tables is as easy
@@ -13,32 +13,32 @@ tags:
---
There are plenty of resources out there for preparing for technical interviews with a focus on PostgreSQL, however many just cover the basics, and the more advanced offerings often conflate transactional SQL with analytical SQL (WINDOW/RANK functions, aggregates etc.).
There are plenty of resources out there for preparing for technical interviews with a focus on PostgreSQL, however many just cover the basics and the advanced resources often conflate transactional SQL with analytical SQL (WINDOW/RANK functions, aggregates etc.).
Here, we're going to focus more on the transactional side of PostgreSQL, and offer some areas that you may want to go a little deeper on, in order to really impress your interviewer (and more importantly; become a kick-ass software engineer).
Here, we're going to focus on the transactional side of PostgreSQL, and offer some areas that you may want to go a little deeper on in order to really impress your interviewer (and more importantly, become a kick-ass software engineer).
## 1. Modeling
### Knows how to model 1-M, M-M, 1-1 relationships. Knows how to use foreign keys.
### Know how to model 1-M, M-M, 1-1 relationships. And know how to use foreign keys.
A review of [database normalization](https://ocw.mit.edu/courses/civil-and-environmental-engineering/1-264j-database-internet-and-systems-integration-technologies-fall-2013/lecture-notes-exercises/MIT1_264JF13_lect_10.pdf) is always a great place to start when thinking about how to correctly model relationships. However if you don't have the time to read through lecture notes, head over to [DBDesigner](https://app.dbdesigner.net/designer/schema/guest_template) and inspect their example schema. The table StudentCourses is a great example of how to model a Many-to-Many relationship, by using a joining table. (side note: you can export these visual schemas to SQL using Ctrl+E). Modelling your data correctly is arguably the most important part of any software project, writing applications becomes a breeze if you can get the data layer right.
A review of [database normalization](https://ocw.mit.edu/courses/civil-and-environmental-engineering/1-264j-database-internet-and-systems-integration-technologies-fall-2013/lecture-notes-exercises/MIT1_264JF13_lect_10.pdf) is a great place to start when thinking about how to correctly model relationships. However if you don't have the time to read through lecture notes, head over to [DBDesigner](https://app.dbdesigner.net/designer/schema/guest_template) and inspect their example schema. The table StudentCourses is a great example of how to model a Many-to-Many relationship, by using a joining table. (side note: you can export these visual schemas to SQL using Ctrl+E). Modelling your data correctly is arguably the most important part of any software project, writing applications becomes a breeze if you can get the data layer right.
### Knows how to use pg rich type system: [arrays](https://www.postgresql.org/docs/current/arrays.html), [domains](https://www.postgresql.org/docs/current/domains.html), [JSONB](https://www.postgresql.org/docs/13/datatype-json.html), [timestamptz](https://www.postgresql.org/docs/current/functions-datetime.html), [enums](https://www.postgresql.org/docs/13/datatype-enum.html)
### Know how to use pg rich type system: [arrays](https://www.postgresql.org/docs/current/arrays.html), [domains](https://www.postgresql.org/docs/current/domains.html), [JSONB](https://www.postgresql.org/docs/13/datatype-json.html), [timestamptz](https://www.postgresql.org/docs/current/functions-datetime.html), [enums](https://www.postgresql.org/docs/13/datatype-enum.html)
Postgres has tons of useful types beyond the basics, knowing how to use them will show you can leverage the true power of Postres. JSONB for example can be incredibly useful for storing non-structured data, which you can query using syntax like:
Postgres has tons of useful types beyond the basics, knowing how to use them will show you can leverage the true power of Postgres. JSONB for example can be incredibly useful for storing non-structured data, which you can query using syntax like:
```sql
-- grades = {'geography': 'A', 'history': 'B', 'postgres': 'A++'}
SELECT * FROM students WHERE grades->>'geography' = 'A';
```
### Knows about namespacing with SCHEMAs
### Know about namespacing with SCHEMAs
In Supabase for example we keep system schemas such as 'extensions' and 'auth' in their own separate schemas so as to not pollute the default 'public' schema.
In Supabase for example we keep system schemas such as `extensions` and `auth` in separate schemas so that we don't pollute the default `public` schema.
## 2. INDEX
## 2. INDEXes
### Knows how speed up queries with indexes.
### Know how speed up queries with indexes.
If your students table is most frequently queried on surname, you may want to create an index:
@@ -47,7 +47,7 @@ CREATE INDEX idx_students_surname
ON students(surname);
```
### Knows how to analyze with EXPLAIN ANALYZE
### Know how to analyze with EXPLAIN ANALYZE
Running
@@ -61,11 +61,11 @@ Before and after adding your index will show you the difference in approach Post
## 3. VIEWs
### Knows how to create different representations of data with [VIEWs](https://supabase.io/blog/2020/11/18/postgresql-views).
### Know how to create different representations of data with [VIEWs](https://supabase.io/blog/2020/11/18/postgresql-views).
We might create a VIEW `transcripts` which pulls out data from `students`, `courses`, and `grades`. It's useful for security, and logical abstractions. Check out our longer post on VIEWs here: [https://supabase.io/blog/2020/11/18/postgresql-views](https://supabase.io/blog/2020/11/18/postgresql-views)
### Knows about Autoupdatable views.
### Know about Autoupdatable views.
If a VIEW is named as the target relation in an INSERT, UPDATE, or DELETE and only SELECTs from a single base relation, then the underlying subquery is automatically rewritten to update the underlying base relation instead.
@@ -75,11 +75,11 @@ One example of a limitation is when a VIEW is not Autoupdatable. This happens wh
## 4. ROLEs
### Knows how to secure their database. Permissions at the table, column, row level.
### Know how to secure their database. Permissions at the table, column, row level.
All databases have different user types, your client for example doesn't usually need the ability to create and drop schemas, but your DB admin does. You should play around with [creating roles](https://www.postgresql.org/docs/current/database-roles.html), and [granting](https://www.postgresql.org/docs/current/role-membership.html) various permissions.
### Knows about [ROLEs](https://www.postgresql.org/docs/13/sql-createrole.html), application ROLEs, the PUBLIC role, and [GRANTs](https://www.postgresql.org/docs/current/sql-grant.html)
### Know about [ROLEs](https://www.postgresql.org/docs/13/sql-createrole.html), application ROLEs, the PUBLIC role, and [GRANTs](https://www.postgresql.org/docs/current/sql-grant.html)
In Postgres, the special “role” name PUBLIC can be used to grant a privilege to every role on the system. For example, if you want to grant insert access to all users on table students:
@@ -87,7 +87,7 @@ In Postgres, the special “role” name PUBLIC can be used to grant a privilege
GRANT INSERT ON students TO PUBLIC;
```
### Knows how to do RLS - Policies
### Know how to do RLS - Policies
We use Row Level Security in Supabase as a way to grant/restrict access on a row level basis. For example if you're writing a Discord clone, perhaps only a given user should be able to write their own messages:
@@ -102,7 +102,7 @@ CREATE POLICY "Individuals can only write their own messages." ON messages FOR
## 5. FUNCTIONs
### Knows how to do business logic on SQL/[PLPGSQL](https://www.postgresql.org/docs/current/plpgsql-overview.html#PLPGSQL-ADVANTAGES)
### Know how to do business logic on SQL/[PLPGSQL](https://www.postgresql.org/docs/current/plpgsql-overview.html#PLPGSQL-ADVANTAGES)
PL/pgSQL is a procedural programming language that can be used to write functions inside of your database. It can be useful for making [remote procedure calls](https://supabase.io/docs/client/rpc) from an API. You can go as deep as you want here, since it's an entire programming language, but understanding the basics will really go a long way, and give you super powers when working with your data.
@@ -129,7 +129,7 @@ CREATE TRIGGER handle_updated_at
Whilst PL/pgSQL does have [loops](https://www.postgresql.org/docs/current/plpgsql-control-structures.html#PLPGSQL-CONTROL-STRUCTURES-LOOPS) and [cursors](https://www.postgresql.org/docs/current/plpgsql-cursors.html), there is usually a faster and more legible pure SQL based solution available using JOIN/UNION etc. So it's important to become well acquainted with thinking in these terms.
### Knows how to use [CTEs](https://www.postgresqltutorial.com/postgresql-cte/)
### Know how to use [CTEs](https://www.postgresqltutorial.com/postgresql-cte/)
Common table expressions are temporary or intermediate result sets. They can make your queries more readable and even enable recursion. The typical form is: