---
term: 'Requêtes de Base de Données'
seoTitle: "Qu'est-ce qu'une requête de base de données ? Les langages de requête expliqués"
headline: "Qu'est-ce qu'une requête de base de données ?"
slug: requetes-de-base-de-donnees
category: database
shortDefinition: 'Une requête de base de données est une demande structurée — filtrer, trier, projeter, paginer — dans un langage que le moteur sait planifier et exécuter.'
relatedTerms:
  - database-index
  - n-plus-one-query-problem
  - relational-queries-document-databases
  - graphql-vs-rest
contrastsWith:
  - auto-generated-database-apis
faq:
  - question: "Qu'est-ce qu'une requête de base de données, en termes simples ?"
    answer: "Une demande structurée qui demande à la base de données de récupérer ou de modifier des données — \"donne-moi les articles publiés avec plus de mille vues, les plus récents d'abord, vingt à la fois\". Elle s'écrit dans un langage de requête ou se construit via un SDK, suit une syntaxe stricte pour que le moteur puisse l'analyser, et renvoie exactement la tranche de données qu'elle décrit."
  - question: 'SQL est-il déclaratif ou impératif ?'
    answer: "Déclaratif — vous indiquez quelles données vous voulez, et l'optimiseur du moteur décide comment les obtenir : quels index utiliser, quel ordre de jointure, quel algorithme. Cette répartition du travail est l'idée centrale des requêtes modernes, et elle dépasse SQL : les API de requête documentaires et GraphQL sont elles aussi déclaratives. Le code impératif boucle sur des enregistrements ; les requêtes déclaratives décrivent des résultats."
  - question: "Comment une requête s'exécute-t-elle concrètement ?"
    answer: "Un pipeline en quatre étapes : le moteur analyse le texte pour en faire un arbre syntaxique, le valide par rapport au schéma, planifie et optimise — en choisissant index, ordres de jointure et algorithmes selon un coût estimé — puis exécute le plan retenu et renvoie les résultats en flux. Le plan est inspectable : EXPLAIN montre exactement ce que l'optimiseur a décidé, et c'est là que commence tout débogage de performance."
  - question: "Quelle est l'anatomie d'une requête ?"
    answer: "Cinq verbes couvrent presque tout : filtrer (quels enregistrements — WHERE), trier (dans quel ordre — ORDER BY), projeter (quels champs — la liste du SELECT), paginer (combien, à partir d'où — LIMIT/OFFSET ou un curseur) et agréger (des synthèses calculées — GROUP BY). Chaque langage de requête et chaque SDK expriment ces cinq mêmes verbes ; seule la syntaxe change."
  - question: 'Comment les index rendent-ils les requêtes rapides ?'
    answer: "Ils remplacent le parcours par la recherche ciblée : au lieu de lire chaque enregistrement pour trouver les correspondances (coût linéaire en la taille de la table), le moteur parcourt une structure triée qui le mène directement à elles (coût logarithmique). La différence est invisible à mille lignes et décisive à dix millions. EXPLAIN vous dit lequel des deux fait votre requête — un parcours séquentiel sur une grande table est le signal d'alarme classique."
  - question: "Qu'est-ce que l'injection SQL et comment les requêtes paramétrées l'empêchent-elles ?"
    answer: "L'injection, c'est une saisie malveillante qui modifie la structure d'une requête — les classiques astuces à base de guillemet et de commentaire qui transforment un contrôle de connexion en tautologie. Les requêtes paramétrées ferment la brèche en séparant le code des données : le texte de la requête contient des placeholders, les valeurs sont liées séparément, et la saisie utilisateur n'est jamais traitée que comme une valeur — jamais analysée comme syntaxe de requête. Les SDK et les query builders paramètrent par construction."
  - question: 'Quelle est la différence entre pagination par offset et pagination par curseur ?'
    answer: "La pagination par offset (sauter N, prendre 20) est simple et permet d'aller à n'importe quelle page, mais le moteur doit compter puis écarter les lignes sautées — la page 500 coûte plus cher que la page 1 — et des écritures concurrentes peuvent décaler les résultats d'une page à l'autre. La pagination par curseur (\"après cette clé, prendre 20\") reste rapide et stable à n'importe quelle profondeur, au prix de l'impossibilité de sauter directement à une page. Les fils d'actualité veulent des curseurs ; les petites tables d'administration se contentent très bien d'offsets."
  - question: 'Les SDK et les query builders dispensent-ils de connaître les requêtes ?'
    answer: "Ils dispensent d'écrire la syntaxe, pas d'en comprendre la sémantique. Une chaîne de builder se compile vers la même anatomie filtrer-trier-projeter-paginer et touche les mêmes index — ou les rate. L'échec classique est le pattern N+1 : une requête par élément dans une boucle, invisible dans le code, brutal en production. L'anatomie et le modèle de coût se transposent à toutes les surfaces."
codeLanguages: [javascript, dart, swift, kotlin]
externalAuthorities:
  - name: 'Query language (Wikipedia)'
    url: 'https://en.wikipedia.org/wiki/Query_language'
  - name: 'PostgreSQL — Using EXPLAIN'
    url: 'https://www.postgresql.org/docs/current/using-explain.html'
  - name: 'GraphQL specification and docs'
    url: 'https://graphql.org/learn/'
  - name: 'SDK query documentation'
    url: 'https://docs.parseplatform.org/js/guide/#queries'
cta:
  title: 'Des requêtes sans le langage de requête'
  text: "Sur Back4app, le query builder de chaque SDK se compile en requêtes indexées et paramétrées sur vos données — les cinq mêmes verbes, aucune surface d'injection, plus GraphQL quand les clients veulent demander exactement ce dont ils ont besoin."
  linkText: 'Commencez gratuitement'
  linkUrl: 'https://www.back4app.com/signup'
author: 'Back4app Engineering'
publishedDate: '2026-09-11'
translationKey: database-queries
---

**Une requête de base de données est une demande structurée — filtrer, trier, projeter, paginer — dans un langage que le moteur sait planifier et exécuter.** L'idée profonde sous chaque langage de requête, c'est le *déclaratif* : vous décrivez le résultat, et le moteur choisit le chemin. Maîtrisez une fois les cinq verbes et le modèle de coût, et chaque syntaxe — SQL, API documentaires, GraphQL, builders de SDK — devient un accent, pas une nouvelle langue.

## Points clés

| Question | Réponse |
| --- | --- |
| Ce que c'est | Une demande précise : quels enregistrements, dans quel ordre, quels champs, combien |
| Le paradigme | Déclaratif — vous dites *quoi* ; l'optimiseur décide *comment* |
| Le pipeline | Analyse → validation → planification/optimisation → exécution |
| Le modèle de coût | Recherche par index vs. parcours complet — EXPLAIN vous dit lequel vous avez obtenu |
| La règle de sécurité | Paramétrez toujours ; ne concaténez jamais une saisie dans une requête |

## La même requête dans quatre langages de requête

La même demande — *articles publiés, plus de 1 000 vues, les plus récents d'abord* — à travers les familles de langages :

```sql
-- SQL : le déclaratif originel
SELECT title, views FROM articles
WHERE  status = 'published' AND views > 1000
ORDER  BY published_at DESC
LIMIT  20;
```

```javascript
// API de requête documentaire
db.articles.find(
  { status: 'published', views: { $gt: 1000 } },  // filtrer
  { title: 1, views: 1 }                          // projeter
).sort({ publishedAt: -1 }).limit(20)

// GraphQL : les clients déclarent la forme qu'ils veulent recevoir
query {
  articles(where: { status: "published", views_gt: 1000 },
           orderBy: publishedAt_DESC, first: 20) {
    title
    views
  }
}
```

Et le builder du SDK — la surface qu'utilise réellement la plupart du code applicatif, compilée vers la même anatomie :

**JavaScript:**

```javascript
// JavaScript / Node.js — Back4app JS SDK
// Filter, sort, project, paginate — the full anatomy in one query
const query = new Parse.Query('Article');
query.equalTo('status', 'published');       // filter
query.greaterThan('views', 1000);           // filter (range)
query.descending('publishedAt');            // sort
query.select('title', 'views');             // project: only these fields
query.limit(20).skip(40);                   // paginate: page 3
const articles = await query.find();
```

**Flutter:**

```dart
// Flutter / Dart — Back4app Flutter SDK
// Filter, sort, project, paginate — the full anatomy in one query
final query = QueryBuilder<ParseObject>(ParseObject('Article'))
  ..whereEqualTo('status', 'published')     // filter
  ..whereGreaterThan('views', 1000)         // filter (range)
  ..orderByDescending('publishedAt')        // sort
  ..keysToReturn(['title', 'views'])        // project: only these fields
  ..setLimit(20)..setAmountToSkip(40);      // paginate: page 3
final response = await query.query();
```

**Swift:**

```swift
// iOS / Swift — Back4app Swift SDK
// Filter, sort, project, paginate — the full anatomy in one query
let query = Article.query("status" == "published", "views" > 1000)
  .order([.descending("publishedAt")])      // sort
  .select("title", "views")                 // project: only these fields
  .limit(20).skip(40)                       // paginate: page 3
query.find { result in
  if case .success(let articles) = result { render(articles) }
}
```

**Kotlin:**

```kotlin
// Android / Kotlin — Back4app Android SDK
// Filter, sort, project, paginate — the full anatomy in one query
val query = ParseQuery.getQuery<ParseObject>("Article")
query.whereEqualTo("status", "published")   // filter
query.whereGreaterThan("views", 1000)       // filter (range)
query.orderByDescending("publishedAt")      // sort
query.selectKeys(listOf("title", "views"))  // project: only these fields
query.limit = 20; query.skip = 40           // paginate: page 3
query.findInBackground { articles, e -> if (e == null) render(articles) }
```

## Comment une base de données exécute une requête

```mermaid
flowchart LR
  accTitle: Pipeline d'exécution d'une requête
  accDescr: Le moteur analyse le texte de la requête pour en faire un arbre syntaxique, le valide par rapport au schéma, planifie et optimise en choisissant index et stratégies de jointure selon le coût, puis exécute le plan et renvoie les résultats.
  Q["Texte de la requête"] --> P["Analyse<br/>arbre syntaxique"]
  P --> V["Validation<br/>par rapport au schéma"]
  V --> O["Planification & optimisation<br/>index · ordre de jointure · coût"]
  O --> E["Exécution<br/>résultats en flux"]
```

L'optimiseur est la raison pour laquelle l'interrogation déclarative fonctionne : il pèse les [index](/glossary/fr/index-de-base-de-donnees/) disponibles, estime le nombre de lignes et choisit le plan le moins coûteux — et [EXPLAIN](https://www.postgresql.org/docs/current/using-explain.html) montre sa décision. La méthode de performance en une ligne : lancez EXPLAIN, cherchez le parcours complet, ajoutez l'index que le filtre réclame, regardez à nouveau.

## Déclaratif vs. impératif

| Dimension | Requête déclarative | Code impératif |
| --- | --- | --- |
| Vous écrivez | Le résultat voulu | Les étapes pour le calculer |
| Qui optimise | Le moteur, à chaque exécution | Vous, une fois, à l'écriture |
| S'adapte au volume de données | Oui — les plans évoluent avec les statistiques | Non — la boucle reste la boucle |
| Où ça vit | SQL, API documentaires, GraphQL, builders | Boucles applicatives sur des enregistrements |
| Symptôme d'échec | Mauvais plan (corrigé par index/hints) | Boucles N+1, explosions mémoire |

L'anatomie qui se retrouve partout : **filtrer** (`WHERE`), **trier** (`ORDER BY`), **projeter** (la liste du SELECT — ne demandez que ce dont vous avez besoin), **paginer** (`LIMIT` plus offset ou curseur), **agréger** (`GROUP BY` et consorts). Cinq verbes, toutes les surfaces.

## Les deux règles qui évitent la plupart des incidents de requête

**Paramétrez, toujours.** L'injection, c'est une saisie malveillante qui devient *structure* de la requête — un problème entièrement résolu par des placeholders qui lient la saisie en tant que valeurs :

```javascript
// Vulnérable : saisie concaténée dans la structure de la requête
db.query(`SELECT * FROM users WHERE name = '${input}'`);   // jamais ça

// Sûr : paramétré — la saisie est une donnée, pas de la syntaxe
db.query('SELECT * FROM users WHERE name = $1', [input]);
```

Les builders de SDK et les variables GraphQL le font par construction — l'un des gains de sécurité discrets des surfaces de requête de plus haut niveau.

**Paginez selon la forme de l'accès.** La pagination par offset (`LIMIT 20 OFFSET 400`) peut sauter à n'importe quelle page, mais paie la profondeur de façon linéaire et vacille sous les écritures concurrentes ; la pagination par curseur (`WHERE published_at < $last`) est stable et à coût constant à toute profondeur, mais n'avance que vers l'avant. Fils d'actualité et scroll infini veulent des curseurs ; les tables d'administration numérotées par page sont le terrain légitime de l'offset.

## Cas d'usage courants

- **Lectures applicatives.** Vues en liste, écrans de détail, recherche — le quatuor filtrer-trier-projeter-paginer dans son habitat naturel.
- **Agrégation et reporting.** Comptages, sommes, synthèses groupées — poussés vers le moteur, là où sont les données, au lieu d'être calculés dans le code applicatif.
- **Surfaces d'API.** Les [API générées automatiquement](/glossary/fr/apis-generees-automatiquement/) traduisent les paramètres d'URL ou les sélections GraphQL en ces mêmes requêtes — l'anatomie transparaît à travers chaque abstraction.
- **Filtres temps réel.** Les abonnements live sont des requêtes permanentes — les mêmes prédicats, évalués en continu.
- **Déboguer la production.** EXPLAIN plus le journal des requêtes lentes, c'est la boucle de diagnostic pour la catégorie d'incident "c'est devenu lent".

## Langage brut, builder ou SDK ? Matrice de décision

| Optez pour… | Quand… | Attention à… |
| --- | --- | --- |
| Le langage de requête brut | Agrégation complexe, rapports, migrations | L'injection si vous concaténez ; la portabilité |
| Un query builder / SDK | CRUD applicatif et listes — l'essentiel du code | Les boucles N+1 ; les builders masquent le plan |
| GraphQL | Les clients doivent choisir les champs et imbriquer les relations | Un coût de requête non borné sans limites |
| Logique stockée / côté serveur | Opérations en plusieurs étapes au plus près des données | Une logique cachée hors de la codebase |

La règle honnête de la [discussion sur les couches d'abstraction](/glossary/fr/couche-d-abstraction-de-base-de-donnees/) s'applique mot pour mot : des builders pour les 90 % de routine, des requêtes brutes là où le contrôle se justifie — et la connaissance de l'anatomie se transpose dans les deux cas.

## Limites et trade-offs

- **Le déclaratif n'est pas gratuit.** L'optimiseur ne vaut que ce que valent ses statistiques et ses index ; une bonne requête sur de mauvais index reste lente.
- **Les requêtes cachent leur coût.** Une ligne de chaîne de builder peut être un parcours de millions de lignes ; EXPLAIN est le seul miroir honnête.
- **Le piège N+1 vit au-dessus de la requête.** Des requêtes individuelles parfaites, émises dans une boucle, sont collectivement pathologiques — le traitement par lot et les includes existent pour ça.
- **La pagination profonde se dégrade.** La profondeur d'offset a un coût linéaire ; concevez vos fils autour des curseurs dès le premier jour.
- **La prolifération des langages est réelle.** SQL, API documentaires, GraphQL, DSL de recherche — les équipes paient une taxe par surface ; l'anatomie commune est l'antidote.

## Les requêtes sur Back4app

Back4app est une plateforme open-source de Backend as a Service (BaaS) qui combine une base de données gérée, des API REST et GraphQL générées automatiquement, l'authentification, le stockage de fichiers et des fonctions serverless avec Cloud Code. Son approche des requêtes, c'est la voie du builder de SDK menée jusqu'au bout : le [query builder](https://docs.parseplatform.org/js/guide/#queries) de chaque SDK — les onglets de code ci-dessus — compile filtrer, trier, projeter et paginer en requêtes paramétrées sans surface d'injection, `include()` gère les relations sans boucles N+1, les mêmes prédicats alimentent les [live queries](https://www.back4app.com) pour les mises à jour en temps réel, et GraphQL sert les clients qui veulent déclarer leurs propres formes. Cinq verbes, toutes les surfaces, un seul backend.
