Schema-on-Write vs Schema-on-Read
Résumé
La question est quand on impose la structure des données. En schema-on-write, on la définit avant le chargement et les données sont validées en entrant : les requêtes sont rapides et fiables, mais changer la structure coûte. En schema-on-read, on dépose les données brutes et on les interprète au moment de la requête : l’ingestion est souple, mais la qualité n’est pas garantie. La plupart des plateformes modernes combinent les deux.
Prérequis
Savoir ce qu’est un schéma (colonnes, types, contraintes) et la différence entre ETL et ELT (voir Glossaire data engineering). Les exemples de code sont écrits pour BigQuery.
| Aspect | Schema-on-Write | Schema-on-Read |
|---|---|---|
| Schéma défini | Avant le chargement | À la requête |
| Ingestion | Plus lente : il faut transformer pour respecter le schéma | Rapide : on copie les fichiers |
| Requête | Rapide : données déjà typées | Plus lente : le schéma est appliqué à la volée |
| Évolution | Coûteuse, parfois réécriture de la table | Facile : on change la définition de lecture |
| Qualité | Validée à l’écriture | Non garantie : valeurs manquantes, invalides, doublons |
| Usage typique | Bases transactionnelles, BI sur données stables | Exploration, données non structurées, zone brute |
Schema-on-Write
On conçoit le schéma (tables, types, clés de partitionnement), on transforme les données pour le respecter, on les charge, puis on les interroge.
Exemple, une table native BigQuery :
CREATE TABLE `my_project.clinical.patients` (
patient_id STRING NOT NULL,
date_of_birth DATE NOT NULL,
blood_type STRING,
admitted_at TIMESTAMP
)
PARTITION BY DATE(admitted_at)
CLUSTER BY patient_id
OPTIONS (require_partition_filter = true);Un chargement avec un type incompatible échoue, ou ignore les lignes en erreur si l’option max_bad_records l’autorise : l’erreur est vue à l’ingestion, pas trois requêtes plus tard. PARTITION BY et CLUSTER BY réduisent les octets lus, donc le coût.
Coût d’évolution. Dans un RDBMS classique, changer une structure peut imposer une réécriture complète. BigQuery est plus souple : ajouter une colonne nullable est une opération de métadonnées, et ALTER TABLE … DROP COLUMN aussi, mais elle ne libère pas le stockage tout de suite et ne s’applique pas aux colonnes de partitionnement ou de clustering, aux clés primaires ou étrangères, ni aux champs imbriqués. Élargir un type est possible dans certains cas ; rendre un champ obligatoire ou changer un type de façon incompatible demande de recréer la table (CREATE OR REPLACE TABLE … AS SELECT).
Limite : les données sont façonnées pour un usage connu, donc plus difficiles à réutiliser pour un besoin imprévu.
Schema-on-Read
On dépose les fichiers tels quels et on définit leur structure au moment de les lire. Changer l’interprétation revient à changer la définition de la table ou de la requête, pas les fichiers.
Exemple : des événements JSON (un document par ligne, format JSON délimité par retour à la ligne) arrivent dans un bucket GCS, partitionnés par date.
gs://clickstream-raw/year=2026/month=07/day=19/events.json
Une table externe BigQuery les interroge sans les copier :
CREATE EXTERNAL TABLE `my_project.raw.clickstream`
WITH PARTITION COLUMNS (
year INT64,
month INT64,
day INT64
)
OPTIONS (
format = 'JSON',
uris = ['gs://clickstream-raw/*'],
hive_partition_uri_prefix = 'gs://clickstream-raw/'
);Pour une exploration ponctuelle sans créer de table, on peut passer par une table externe temporaire, définie à la volée via la CLI bq (option --external_table_definition) ou l’API.
À ne pas confondre
EXTERNAL_QUERYn’est pas la bonne fonction ici : elle sert aux requêtes fédérées vers Cloud SQL, Spanner ou AlloyDB à travers une connexion, pas à lire des fichiers dans GCS.
Limites. Les requêtes sur table externe sont en général plus lentes qu’en table native, parce que BigQuery ne gère ni le stockage ni le clustering des fichiers. L’auto-détection du schéma peut mal deviner les types sur des fichiers hétérogènes. Et il faut quand même comprendre la structure pour s’en servir.
Atout : la copie brute est conservée, donc on peut retraiter si la logique de transformation était fausse.
Technique liée : le partitionnement Hive
Les fichiers sont rangés en dossiers par valeur de colonne (year=2026/month=07/day=19/). Le moteur ne lit que les dossiers utiles : c’est le partition pruning, le même principe que PARTITION BY sur une table native, appliqué à des fichiers.
Où se situent les produits
La frontière n’est pas nette, et les produits sont hybrides.
- BigQuery : les tables natives imposent un schéma, mais l’évolution additive est peu coûteuse ; les tables externes reportent le schéma à la requête.
- Snowflake : tables à schéma imposé, mais le type
VARIANTstocke du semi-structuré interrogé sans schéma préalable. - MongoDB : pas de schéma imposé avant l’écriture ; chaque valeur est typée dans le document, et une validation de schéma est possible en option.
- Elasticsearch : le mapping (souvent déduit dynamiquement) fixe le type d’un champ à la première valeur vue.
- Data lakes, Hive, Trino : schema-on-read par construction.
- Schema registries (Avro, Protobuf, JSON Schema, avec Kafka ; Pub/Sub accepte Avro et Protobuf) : elles imposent des règles de compatibilité sur des flux, donc un schéma qui évolue sans tout casser.
Le médaillon comme compromis
L’architecture médaillon (détaillée dans la note suivante du parcours) applique ce compromis par étapes : on garde la copie brute dans la couche bronze (peu ou pas de contrainte de schéma), on la nettoie et on la type dans silver, on construit les tables modélisées pour la BI dans gold. La bronze reste intacte, ce qui sert de filet si une transformation était fausse.
Nuance
Ce qui distingue silver de bronze est le niveau de raffinement et de qualité, pas seulement la présence d’un schéma. Le détail est dans Staging, ODS, DWH et architecture médaillon.
Notes liées
- ACID vs BASE : l’autre axe, la cohérence. Les deux axes sont indépendants.
- Staging, ODS, DWH et architecture médaillon : le médaillon en détail.
- Data lake vs lakehouse : les limites du « schema on read » d’un lac et ce que corrige la couche de table.
- Glossaire data engineering : ETL, ELT, partition pruning.
- MOC Data Engineering : carte du vault.