feature: adds pg interview blog

This commit is contained in:
awalias committed 2021-02-27 17:52:30 +08:00
1 parent 87eebc2352
commit 978f88b8e4
2 files changed
+152 -1

No files matched your search

@@ -0,0 +1,151 @@
---
title: Cracking the PostgreSQL Interview
description: Transactional SQL to Show Off Your Data Skills
author: Ant Wilson
author_title: Supabase
author_url: https://github.com/awalias
author_image_url: https://github.com/awalias.png
authorURL: https://github.com/awalias
image: /img/roboflow-og.png
tags:
- SQL
- Postgres
---
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.).
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).
## 1. Modeling
### Knows how to model 1-M, M-M, 1-1 relationships. Knows 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.
### 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)
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:
```sql
-- grades = {'geography': 'A', 'history': 'B', 'postgres': 'A++'}
SELECT * FROM students WHERE grades->>'geography' = 'A';
```
### Knows 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.
## 2. INDEX
### Knows how speed up queries with indexes.
If your students table is most frequently queried on surname, you may want to create an index:
```sql
CREATE INDEX idx_students_surname
ON students(surname);
```
### Knows how to analyze with EXPLAIN ANALYZE
Running
```sql
EXPLAIN SELECT *
FROM students
WHERE surname = 'Krobb';
```
Before and after adding your index will show you the difference in approach Postgres took to finding your data.
## 3. VIEWs
### Knows 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.
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.
### Limitations on VIEWs
One example of a limitation is when a VIEW is not Autoupdatable. This happens when the VIEW does not SELECT from a single base relation. If the user does not specify an INSTEAD OF trigger that upgrades the underlying query, then an error will be thrown, since the executor cannot update a view as such.
## 4. ROLEs
### Knows 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)
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:
```sql
GRANT INSERT ON students TO PUBLIC;
```
### Knows 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:
```sql
CREATE POLICY "Individuals can only write their own messages." ON messages FOR
INSERT WITH CHECK (auth.uid() = user_id);
-- auth.uid() is a function provided by Supabase which plucks the uid out
-- of the JWT sent along with an API request more on this here:
-- https://www.youtube.com/watch?v=0LvCOlELs5U
```
## 5. FUNCTIONs
### Knows 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.
You can use FUNCTIONs in combination with TRIGGERs to do cool stuff like have auto-updating `updated_at` columns on your data:
```sql
-- a function that sets the updated_at value to now()
CREATE FUNCTION set_updated_at()
RETURNS TRIGGER AS $$
BEGIN
new.updated_at = now();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- a trigger that fires when students table is updated
CREATE TRIGGER handle_updated_at
BEFORE UPDATE ON students
FOR EACH ROW
EXECUTE PROCEDURE set_updated_at();
```
### Thinks in SETs when doing logic
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/)
Common table expressions are temporary or intermediate result sets. They can make your queries more readable and even enable recursion. The typical form is:
```sql
WITH ten_strumpers AS (
SELECT id, first_name
FROM students
WHERE surname = 'Strumper'
ORDER BY first_name
LIMIT 10
)
SELECT id
FROM ten_strumpers
WHERE first_name LIKE "S%";
```
Thanks Steve Chavez for providing all the good bits of this post :)
[Get started on Supabase for free](https://app.supabase.io)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "supabase",
"version": "0.0.2",
"version": "0.0.3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {