|
| 1 | +--- |
| 2 | +title: PostgreSQL - fondamentaux et sécurité |
| 3 | +description: Formation rapide sur PostgreSQL, RLS, fonctions, triggers et extensions. |
| 4 | +tags: [info, database, postgresql] |
| 5 | +last_update: |
| 6 | + date: 2026-02-25 |
| 7 | + author: Eliott Roussille |
| 8 | +--- |
| 9 | + |
| 10 | +Cette formation couvre les bases de PostgreSQL avec un focus sur la sécurité : RLS, fonctions, triggers et extensions utiles. |
| 11 | + |
| 12 | +## Prérequis |
| 13 | + |
| 14 | +- Un serveur PostgreSQL 13+ (local, Docker ou VPS) |
| 15 | +- Un client SQL (psql, DBeaver ou DataGrip) |
| 16 | +- Connaissances SQL de base |
| 17 | + |
| 18 | +## Installation rapide |
| 19 | + |
| 20 | +```bash |
| 21 | +# Debian/Ubuntu |
| 22 | +sudo apt update |
| 23 | +sudo apt install postgresql postgresql-contrib |
| 24 | + |
| 25 | +# Verification |
| 26 | +psql --version |
| 27 | +``` |
| 28 | + |
| 29 | +Connexion rapide: |
| 30 | + |
| 31 | +```bash |
| 32 | +sudo -u postgres psql |
| 33 | +``` |
| 34 | + |
| 35 | +## Schéma minimal de démo |
| 36 | + |
| 37 | +```sql |
| 38 | +CREATE TABLE app_user ( |
| 39 | + id uuid PRIMARY KEY, |
| 40 | + email text UNIQUE NOT NULL |
| 41 | +); |
| 42 | + |
| 43 | +CREATE TABLE todo ( |
| 44 | + id uuid PRIMARY KEY, |
| 45 | + user_id uuid NOT NULL REFERENCES app_user(id), |
| 46 | + title text NOT NULL, |
| 47 | + is_done boolean NOT NULL DEFAULT false, |
| 48 | + created_at timestamptz NOT NULL DEFAULT now() |
| 49 | +); |
| 50 | +``` |
| 51 | + |
| 52 | +## RLS (Row Level Security) |
| 53 | + |
| 54 | +Le RLS permet de filtrer les lignes accessibles selon le role ou le contexte. |
| 55 | + |
| 56 | +Activation: |
| 57 | + |
| 58 | +```sql |
| 59 | +ALTER TABLE todo ENABLE ROW LEVEL SECURITY; |
| 60 | +``` |
| 61 | + |
| 62 | +Politique simple (un utilisateur ne voit que ses lignes): |
| 63 | + |
| 64 | +```sql |
| 65 | +CREATE POLICY todo_is_owner |
| 66 | +ON todo |
| 67 | +USING (user_id = current_setting('app.user_id')::uuid) |
| 68 | +WITH CHECK (user_id = current_setting('app.user_id')::uuid); |
| 69 | +``` |
| 70 | + |
| 71 | +Notes: |
| 72 | + |
| 73 | +- `USING` filtre les lignes visibles (SELECT/UPDATE/DELETE). |
| 74 | +- `WITH CHECK` contrôle les lignes écrites (INSERT/UPDATE). |
| 75 | +- `current_setting('app.user_id')` doit etre défini par l'app. |
| 76 | + |
| 77 | +Exemple d'utilisation dans une session: |
| 78 | + |
| 79 | +```sql |
| 80 | +SET app.user_id = '00000000-0000-0000-0000-000000000001'; |
| 81 | +SELECT * FROM todo; |
| 82 | +``` |
| 83 | + |
| 84 | +## Fonctions PostgreSQL |
| 85 | + |
| 86 | +Syntaxe simplifiée: |
| 87 | + |
| 88 | +```sql |
| 89 | +CREATE FUNCTION nom_fonction ( |
| 90 | + [argmode] [argname] argtype [ = defaut ], |
| 91 | + ... |
| 92 | +) |
| 93 | +RETURNS type_retour |
| 94 | +LANGUAGE lang |
| 95 | +AS $$ corps $$; |
| 96 | +``` |
| 97 | + |
| 98 | +Paramètres des arguments: |
| 99 | + |
| 100 | +- `argmode` : `IN` (entrée), `OUT` (sortie), `INOUT` (entrée+sortie), `VARIADIC` (tableau variable en dernier argument). |
| 101 | +- `argname` : nom de paramètre, utilisable dans le corps. |
| 102 | +- `argtype` : type SQL (ex: `text`, `uuid`, `integer`). |
| 103 | +- `= defaut` : valeur par défaut si l'appelant ne fournit pas l'argument. |
| 104 | + |
| 105 | +Paramètres de la fonction: |
| 106 | + |
| 107 | +- `RETURNS` : type de retour (`integer`, `text`, `TABLE(...)`, `trigger`, `SETOF type`). |
| 108 | +- `LANGUAGE` : langage du corps (`sql`, `plpgsql`, etc.). |
| 109 | +- `AS $$ ... $$` : définition du corps (SQL ou bloc). |
| 110 | +- `IMMUTABLE` : pas d'effet de bord, même entrée -> même sortie. |
| 111 | +- `STABLE` : pas d'effet de bord, peut varier entre transactions. |
| 112 | +- `VOLATILE` : peut changer à chaque appel (par défaut). |
| 113 | +- `SECURITY DEFINER` : éxécute avec les droits du proprietaire. |
| 114 | +- `SECURITY INVOKER` : éxécute avec les droits de l'appelant (par défaut). |
| 115 | +- `SET` : définir des paramètres de session localement (ex: `SET search_path = public`). |
| 116 | +- `COST` : estimation du coût (utilisé par le planner). |
| 117 | +- `ROWS` : estimation du nombre de lignes pour `RETURNS SETOF`. |
| 118 | +- `PARALLEL` : `SAFE`, `RESTRICTED`, `UNSAFE` pour l'éxecution parallèle. |
| 119 | +- `LEAKPROOF` : indique qu'une fonction ne revèle pas d'infos via des erreurs (usage securité). |
| 120 | + |
| 121 | +Exemple simple: |
| 122 | + |
| 123 | +```sql |
| 124 | +CREATE FUNCTION public.is_done_count(p_user_id uuid) |
| 125 | +RETURNS integer |
| 126 | +LANGUAGE sql |
| 127 | +STABLE |
| 128 | +AS $$ |
| 129 | + SELECT count(*)::int |
| 130 | + FROM todo |
| 131 | + WHERE user_id = p_user_id AND is_done = true; |
| 132 | +$$; |
| 133 | +``` |
| 134 | + |
| 135 | +## Triggers |
| 136 | + |
| 137 | +Un trigger déclenche une fonction lors d'un evenement (INSERT/UPDATE/DELETE). |
| 138 | + |
| 139 | +Etapes: |
| 140 | + |
| 141 | +1. Fonction de trigger (retourne `trigger`): |
| 142 | + |
| 143 | +```sql |
| 144 | +CREATE FUNCTION public.todo_set_created_at() |
| 145 | +RETURNS trigger |
| 146 | +LANGUAGE plpgsql |
| 147 | +AS $$ |
| 148 | +BEGIN |
| 149 | + IF NEW.created_at IS NULL THEN |
| 150 | + NEW.created_at := now(); |
| 151 | + END IF; |
| 152 | + RETURN NEW; |
| 153 | +END; |
| 154 | +$$; |
| 155 | +``` |
| 156 | + |
| 157 | +2. Creation du trigger: |
| 158 | + |
| 159 | +```sql |
| 160 | +CREATE TRIGGER todo_created_at |
| 161 | +BEFORE INSERT ON todo |
| 162 | +FOR EACH ROW |
| 163 | +EXECUTE FUNCTION public.todo_set_created_at(); |
| 164 | +``` |
| 165 | + |
| 166 | +Parametres importants: |
| 167 | + |
| 168 | +- `BEFORE` / `AFTER` / `INSTEAD OF` (sur vues) pour le timing. |
| 169 | +- Évènements: `INSERT`, `UPDATE`, `DELETE`, `TRUNCATE`. |
| 170 | +- `FOR EACH ROW` (ligne) ou `FOR EACH STATEMENT` (instruction). |
| 171 | +- `WHEN (condition)` pour filtrer l'éxécution. |
| 172 | +- `REFERENCING` (optionnel) pour tables de transition sur `AFTER`. |
| 173 | + |
| 174 | +## Extensions |
| 175 | + |
| 176 | +- `pgcrypto` : hash, chiffrement, `gen_random_uuid()`. |
| 177 | +- `vault` : gestion de secrets. |
| 178 | +- `pg_cron` : planification de tâches. |
| 179 | + |
| 180 | +Activation: |
| 181 | + |
| 182 | +```sql |
| 183 | +CREATE EXTENSION IF NOT EXISTS pgcrypto; |
| 184 | +``` |
| 185 | + |
| 186 | +## Ressources |
| 187 | + |
| 188 | +- https://www.postgresql.org/docs/current/ |
| 189 | +- https://www.postgresql.org/docs/current/ddl-rowsecurity.html |
| 190 | +- https://www.postgresql.org/docs/current/sql-createfunction.html |
| 191 | +- https://www.postgresql.org/docs/current/sql-createtrigger.html |
0 commit comments