sql-code-review

Par github · awesome-copilot

Assistant universel de revue de code SQL qui effectue une analyse complète de la sécurité, de la maintenabilité et de la qualité du code pour tous les moteurs SQL (MySQL, PostgreSQL, SQL Server, Oracle). Se concentre sur la prévention des injections SQL, le contrôle d'accès, les standards de code et la détection des anti-patterns. Complète le prompt d'optimisation SQL pour une couverture complète du développement.

npx skills add https://github.com/github/awesome-copilot --skill sql-code-review

Examen du Code SQL

Effectuez un examen approfondi du code SQL ${selection} (ou du projet entier s'il n'y a pas de sélection) en mettant l'accent sur la sécurité, les performances, la maintenabilité et les bonnes pratiques de base de données.

🔒 Analyse de Sécurité

Prévention des Injections SQL

-- ❌ CRITIQUE : Vulnérabilité d'injection SQL
query = "SELECT * FROM users WHERE id = " + userInput;
query = f"DELETE FROM orders WHERE user_id = {user_id}";

-- ✅ SÉCURisé : Requêtes paramétrées
-- PostgreSQL/MySQL
PREPARE stmt FROM 'SELECT * FROM users WHERE id = ?';
EXECUTE stmt USING @user_id;

-- SQL Server
EXEC sp_executesql N'SELECT * FROM users WHERE id = @id', N'@id INT', @id = @user_id;

Contrôle d'Accès et Permissions

  • Principe du Moindre Privilège : Accorder les permissions minimales requises
  • Contrôle d'Accès Basé sur les Rôles : Utiliser les rôles de base de données plutôt que des permissions directes
  • Sécurité du Schéma : Propriété et contrôles d'accès appropriés du schéma
  • Sécurité des Fonctions/Procédures : Examiner les droits DEFINER vs INVOKER

Protection des Données

  • Exposition de Données Sensibles : Éviter SELECT * sur les tables contenant des colonnes sensibles
  • Journalisation d'Audit : S'assurer que les opérations sensibles sont enregistrées
  • Masquage des Données : Utiliser des vues ou des fonctions pour masquer les données sensibles
  • Chiffrement : Vérifier le chiffrage du stockage pour les données sensibles

⚡ Optimisation des Performances

Analyse de la Structure des Requêtes

-- ❌ MAUVAIS : Patterns de requête inefficaces
SELECT DISTINCT u.* 
FROM users u, orders o, products p
WHERE u.id = o.user_id 
AND o.product_id = p.id
AND YEAR(o.order_date) = 2024;

-- ✅ BON : Structure optimisée
SELECT u.id, u.name, u.email
FROM users u
INNER JOIN orders o ON u.id = o.user_id
WHERE o.order_date >= '2024-01-01' 
AND o.order_date < '2025-01-01';

Examen de la Stratégie d'Indexation

  • Index Manquants : Identifier les colonnes qui ont besoin d'indexation
  • Sur-Indexation : Trouver les index inutilisés ou redondants
  • Index Composites : Index multi-colonnes pour les requêtes complexes
  • Maintenance des Index : Vérifier la fragmentation ou les index obsolètes

Optimisation des Jointures

  • Types de Jointures : Vérifier les types de jointures appropriés (INNER vs LEFT vs EXISTS)
  • Ordre des Jointures : Optimiser pour les ensembles de résultats plus petits en premier
  • Produits Cartésiens : Identifier et corriger les conditions de jointure manquantes
  • Sous-Requête vs JOIN : Choisir l'approche la plus efficace

Fonctions d'Agrégation et de Fenêtrage

-- ❌ MAUVAIS : Agrégation inefficace
SELECT user_id, 
       (SELECT COUNT(*) FROM orders o2 WHERE o2.user_id = o1.user_id) as order_count
FROM orders o1
GROUP BY user_id;

-- ✅ BON : Agrégation efficace
SELECT user_id, COUNT(*) as order_count
FROM orders
GROUP BY user_id;

🛠️ Qualité du Code et Maintenabilité

Style et Formatage SQL

-- ❌ MAUVAIS : Formatage et style médiocres
select u.id,u.name,o.total from users u left join orders o on u.id=o.user_id where u.status='active' and o.order_date>='2024-01-01';

-- ✅ BON : Formatage propre et lisible
SELECT u.id,
       u.name,
       o.total
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.status = 'active'
  AND o.order_date >= '2024-01-01';

Conventions de Nommage

  • Nommage Cohérent : Les tables, colonnes et contraintes suivent des patterns cohérents
  • Noms Descriptifs : Noms clairs et significatifs pour les objets de la base de données
  • Mots Réservés : Éviter d'utiliser les mots réservés de la base de données comme identifiants
  • Sensibilité à la Casse : Utilisation cohérente de la casse sur le schéma

Examen de la Conception du Schéma

  • Normalisation : Niveau de normalisation approprié (éviter la sur/sous-normalisation)
  • Types de Données : Choix de types de données optimaux pour le stockage et les performances
  • Contraintes : Utilisation appropriée de PRIMARY KEY, FOREIGN KEY, CHECK, NOT NULL
  • Valeurs par Défaut : Valeurs par défaut appropriées pour les colonnes

🗄️ Bonnes Pratiques Spécifiques à la Base de Données

PostgreSQL

-- Utiliser JSONB pour les données JSON
CREATE TABLE events (
    id SERIAL PRIMARY KEY,
    data JSONB NOT NULL,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Index GIN pour les requêtes JSONB
CREATE INDEX idx_events_data ON events USING gin(data);

-- Types tableau pour les colonnes multi-valeurs
CREATE TABLE tags (
    post_id INT,
    tag_names TEXT[]
);

MySQL

-- Utiliser les moteurs de stockage appropriés
CREATE TABLE sessions (
    id VARCHAR(128) PRIMARY KEY,
    data TEXT,
    expires TIMESTAMP
) ENGINE=InnoDB;

-- Optimiser pour InnoDB
ALTER TABLE large_table 
ADD INDEX idx_covering (status, created_at, id);

SQL Server

-- Utiliser les types de données appropriés
CREATE TABLE products (
    id BIGINT IDENTITY(1,1) PRIMARY KEY,
    name NVARCHAR(255) NOT NULL,
    price DECIMAL(10,2) NOT NULL,
    created_at DATETIME2 DEFAULT GETUTCDATE()
);

-- Index columnstore pour l'analytique
CREATE COLUMNSTORE INDEX idx_sales_cs ON sales;

Oracle

-- Utiliser des séquences pour l'auto-incrémentation
CREATE SEQUENCE user_id_seq START WITH 1 INCREMENT BY 1;

CREATE TABLE users (
    id NUMBER DEFAULT user_id_seq.NEXTVAL PRIMARY KEY,
    name VARCHAR2(255) NOT NULL
);

🧪 Test et Validation

Vérifications de l'Intégrité des Données

-- Vérifier l'intégrité référentielle
SELECT o.user_id 
FROM orders o 
LEFT JOIN users u ON o.user_id = u.id 
WHERE u.id IS NULL;

-- Vérifier la cohérence des données
SELECT COUNT(*) as inconsistent_records
FROM products 
WHERE price < 0 OR stock_quantity < 0;

Test de Performance

  • Plans d'Exécution : Examiner les plans d'exécution des requêtes
  • Test de Charge : Tester les requêtes avec des volumes de données réalistes
  • Test de Stress : Vérifier les performances sous charge concurrente
  • Test de Régression : S'assurer que les optimisations ne cassent pas la fonctionnalité

📊 Anti-Patterns Courants

Problème N+1

-- ❌ MAUVAIS : Requêtes N+1 dans le code applicatif
for user in users:
    orders = query("SELECT * FROM orders WHERE user_id = ?", user.id)

-- ✅ BON : Requête unique optimisée
SELECT u.*, o.*
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;

Suruse de DISTINCT

-- ❌ MAUVAIS : DISTINCT masquant les problèmes de jointure
SELECT DISTINCT u.name 
FROM users u, orders o 
WHERE u.id = o.user_id;

-- ✅ BON : Jointure appropriée sans DISTINCT
SELECT u.name
FROM users u
INNER JOIN orders o ON u.id = o.user_id
GROUP BY u.name;

Mésusage de Fonctions dans les Clauses WHERE

-- ❌ MAUVAIS : Les fonctions empêchent l'utilisation des index
SELECT * FROM orders 
WHERE YEAR(order_date) = 2024;

-- ✅ BON : Les conditions de plage utilisent les index
SELECT * FROM orders 
WHERE order_date >= '2024-01-01' 
  AND order_date < '2025-01-01';

📋 Checklist d'Examen SQL

Sécurité

  • [ ] Toutes les entrées utilisateur sont paramétrées
  • [ ] Aucune construction SQL dynamique avec concaténation de chaînes
  • [ ] Contrôles d'accès et permissions appropriés
  • [ ] Les données sensibles sont correctement protégées
  • [ ] Les vecteurs d'attaque par injection SQL sont éliminés

Performance

  • [ ] Des index existent pour les colonnes fréquemment interrogées
  • [ ] Aucun statement SELECT * inutile
  • [ ] Les JOINs sont optimisés et utilisent les types appropriés
  • [ ] Les clauses WHERE sont sélectives et utilisent les index
  • [ ] Les sous-requêtes sont optimisées ou converties en JOINs

Qualité du Code

  • [ ] Conventions de nommage cohérentes
  • [ ] Formatage et indentation appropriés
  • [ ] Commentaires significatifs pour la logique complexe
  • [ ] Types de données appropriés utilisés
  • [ ] Gestion d'erreurs implémentée

Conception du Schéma

  • [ ] Les tables sont correctement normalisées
  • [ ] Les contraintes appliquent l'intégrité des données
  • [ ] Les index supportent les patterns de requête
  • [ ] Les relations de clé étrangère sont définies
  • [ ] Les valeurs par défaut sont appropriées

🎯 Format de Sortie de l'Examen

Modèle de Problème

## [PRIORITÉ] [CATÉGORIE] : [Brève Description]

**Localisation** : [Nom de la table/vue/procédure et numéro de ligne si applicable]
**Problème** : [Explication détaillée du problème]
**Risque de Sécurité** : [Si applicable - risque d'injection, exposition de données, etc.]
**Impact sur les Performances** : [Coût de requête, impact sur le temps d'exécution]
**Recommandation** : [Correction spécifique avec exemple de code]

**Avant** :
```sql
-- SQL problématique

Après :

-- SQL amélioré

Amélioration Attendue : [Gain de performance, bénéfice de sécurité]



### Évaluation Récapitulative
- **Score de Sécurité** : [1-10] - Protection contre l'injection SQL, contrôles d'accès
- **Score de Performance** : [1-10] - Efficacité des requêtes, utilisation des index
- **Score de Maintenabilité** : [1-10] - Qualité du code, documentation
- **Score de Qualité du Schéma** : [1-10] - Patterns de conception, normalisation

### 3 Actions Prioritaires Principales
1. **[Correction de Sécurité Critique]** : Résoudre les vulnérabilités d'injection SQL
2. **[Optimisation de Performance]** : Ajouter des index manquants ou optimiser les requêtes
3. **[Qualité du Code]** : Améliorer les conventions de nommage et la documentation

Concentrez-vous sur la fourniture de recommandations exploitables et indépendantes de la base de données tout en mettant en évidence les optimisations spécifiques à la plateforme et les bonnes pratiques.

Skills similaires