From 978f88b8e4b7b1c6a25775d11ab944119c55fa7d Mon Sep 17 00:00:00 2001 From: awalias Date: Sat, 27 Feb 2021 17:52:30 +0800 Subject: [PATCH] feature: adds pg interview blog --- .../2021-02-27-cracking-postgres-interview.md | 151 ++++++++++++++++++ web/package-lock.json | 2 +- 2 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 web/blog/2021-02-27-cracking-postgres-interview.md diff --git a/web/blog/2021-02-27-cracking-postgres-interview.md b/web/blog/2021-02-27-cracking-postgres-interview.md new file mode 100644 index 00000000000..f37d8894559 --- /dev/null +++ b/web/blog/2021-02-27-cracking-postgres-interview.md @@ -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) \ No newline at end of file diff --git a/web/package-lock.json b/web/package-lock.json index 92b6f576f01..a01f6f7a5bd 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -1,6 +1,6 @@ { "name": "supabase", - "version": "0.0.2", + "version": "0.0.3", "lockfileVersion": 1, "requires": true, "dependencies": {