L’écriture de pipelines ETL clairs, logiques, faciles à lire et performants en SQL est une partie importante du travail quotidien d’un Data Scientist. Récemment, après avoir examiné plusieurs guides de style SQL (voir les références), j’ai réfléchi à mes pratiques et j’ai identifié les 10 meilleures pratiques SQL suivantes, plus précisément les erreurs courantes que j’ai commises. J’espère que cela te sera utile !
Les avantages de ces meilleures pratiques en matière de style SQL sont les suivants :
- Amélioration de la lisibilité du code
- Réduction des ambiguïtés
- Amélioration de l’efficacité du débogage
- Optimisation des performances du code
1. En minuscule
Les mots-clés et les noms de fonctions doivent tous être en minuscules. Les minuscules sont beaucoup plus faciles à lire pour l’être humain.
/* Bon */ select count(*) as customers_count from customers /* Mauvais */ SELECT * FROM customers
2. Utiliser la sélection distincte
Utilise select distinct au lieu de regrouper toutes les colonnes. L’intention est ainsi plus claire.
/* Bon */ select distinct customer_id , date_trunc('day', created_at) as purchase_date from orders /* Mauvais */ select customer_id , date_trunc('day', created_at) as purchase_date from orders group by 1, 2
3. Utiliser « union all »
Utilise union all au lieu de union, sauf si les lignes dupliquées doivent vraiment être supprimées. union all est plus performant car il n’a pas besoin de trier et de dédupliquer les lignes.
4. CTEs
Lorsque les performances le permettent, les CTes doivent effectuer une seule unité logique de travail. Les noms des CTEs doivent être aussi verbeux que nécessaire pour indiquer ce qu’ils font. Les noms des CTEs ne doivent pas être préfixés ou suffixés par cte. Les CTEs dont la logique prête à confusion ou est remarquable doivent être commentés.
5. Utiliser des CTEs plutôt que des sous-requêtes
Les CTEs rendent nos requêtes plus simples à lire et à raisonner. Ils peuvent être référencés plusieurs fois et sont plus faciles à adapter/refactoriser par la suite.
6. Nom des clés primaires à colonne unique id.
Cela nous permet de savoir d’un coup d’œil si une colonne est une clé primaire, nous aide à discerner si les jointures sont de type one-to-many ou many-to-one, et est plus succinct que d’autres conventions de dénomination des clés primaires (en particulier dans les conditions de jointure).
/* Bon */ select ... from orders left join customers on orders.customer_id = customers.id /* Il est plus facile de dire qu'il s'agit d'une jonction multiple et qu'il n'y aura donc pas d'effet de dispersion. */ /* Mauvais */ select ... from orders left join customers on orders.customer_id = customers.customer_id
7. Utilisation de virgules en tête
Si le code contenant des virgules doit être réparti sur plusieurs lignes, place les virgules au début des lignes suivantes, suivies d’un espace.
Pendant le débogage, tu peux commenter la ligne entière sans provoquer d’erreur telle que « rien n’a suivi la virgule, ce n’est pas nécessaire ».
Il est ainsi plus facile de repérer les virgules manquantes. Les différences de contrôle de version seront plus propres lorsqu’elles sont ajoutées à la fin d’une liste, car il n’est pas nécessaire d’ajouter une virgule à la ligne précédente.
/* Bon */ select id , email , date_trunc('month', created_at) as signup_month from paying_customers /* Mauvais */ select id, email, date_trunc('month', created_at) as signup_month from paying_customers
8. Utiliser des guillemets simples pour les chaînes de caractères
Certains dialectes SQL comme BigQuery permettent d’utiliser des guillemets doubles ou même triples pour les chaînes de caractères, mais pour la plupart des dialectes, les guillemets doubles représentent les identifiants : Les chaînes entre guillemets doubles représentent des identifiants. Les chaînes entre guillemets triples seront interprétées comme si la valeur elle-même contenait des guillemets simples au début et à la fin.
/* Bon */ select * from customers where email like '%@domain.com' /* Mauvais */ select * from customers where email like "%@domain.com" /* Il en résultera probablement une erreur du type `column "%@domain.com" does not exist`. */
9. Ne pas utiliser de « using » dans les jointures
L’utilisation de on pour toutes les jointures est plus cohérente. Si des conditions de jointure supplémentaires doivent être ajoutées ultérieurement, on est plus facile à adapter. L’utilisation de on peut produire des résultats incohérents avec les jointures externes dans certaines bases de données.
10. Conditions de join
Dans les conditions de jointure, place la table qui a été référencée en premier immédiatement après on.
Il est ainsi plus facile de déterminer si la jointure va entraîner une dispersion des résultats.
/* Bon */ select * from orders left join customers on orders.customer_id = customers.id /* foreign key = primary key --> many-to-one --> pas de dispersion */ /* Mauvais */ select * from customers left join orders on orders.customer_id = customers.id