SQL

Qu’est-ce qu’un fichier SQL ?

Un tableau transformé en instructions INSERT, prêt à être chargé dans une base de données.

Ce qu’est SQL

SQL est un format texte que n’importe quel éditeur ouvre. Il est utilisé pour l’échange entre programmes et l’archivage.

L’extension est .sql et le nom complet SQL Insert Statements. L’un et l’autre comptent moins que ce que le fichier peut contenir, et c’est le sujet du reste de cette page.

D’où vient SQL

Il remonte à 1986. La spécification est ISO/IEC 9075.

À un format resté lisible aussi longtemps, on peut confier quelque chose qu’on veut retrouver dans dix ans.

La spécification est publique

Elle est publiée intégralement : n’importe qui peut l’implémenter à partir du document plutôt qu’en l’observant, et c’est pourquoi ce format apparaît dans tant de programmes et pourquoi des fichiers écrits il y a vingt ans s’ouvrent encore. Une spécification publiée n’est pas pour autant libre de redevances : quand un format enveloppe un codec, les brevets sont une question à part, que la norme ne tranche pas.

On peut y laisser des notes

SQL a une syntaxe de commentaires, et c’est la différence entre un fichier qu’une personne entretient et un fichier qu’un programme écrit. Les commentaires sont la première chose perdue en convertissant vers un format qui n’en a pas, et rien ne vous prévient.

Ce qui ouvre SQL

PostgreSQL, MySQL et DBeaver le lisent, comme la plupart des programmes du même genre.

Quand un fichier ne s’ouvre pas, le format est rarement en cause : le plus souvent, c’est le programme qui est plus ancien que lui. Convertir vers quelque chose de plus ancien est le contournement fiable, et c’est à cela que sert le reste de ce site.

L’ouvrir dans un navigateur

Aucun navigateur ne le lit.

C’est de loin la raison la plus fréquente de le convertir : non pas que le format soit mauvais, mais que l’endroit où vous voulez montrer le fichier ne sache pas le lire.

C’est un format de travail

SQL est fait pour être ouvert et modifié. Gardez le fichier dans ce format tant que le travail dure, et exportez depuis lui chaque fois qu’une version finie est nécessaire.

Un langage, et un fichier qui en contient

SQL est un langage d’interrogation standardisé depuis 1986. Un fichier .sql est un fichier texte contenant des instructions, et c’est là toute la définition du format — il n’y a pas d’en-tête, pas de structure, aucun moyen de savoir depuis l’extension ce que fait un fichier particulier. Il peut créer des tables, insérer un million de lignes, modifier un schéma, ou ne contenir que trois requêtes que quelqu’un voulait conserver.

Dans la pratique, ceux que les gens échangent se répartissent en deux groupes. Un vidage est une base de données ou une table réécrite sous forme d’instructions qui la recréent ailleurs. Une migration est un script qui modifie un schéma de manière contrôlée. Les deux sont du texte, les deux s’ouvrent dans n’importe quel éditeur, et confondre les deux est la façon dont un script destiné à ajouter une colonne finit par supprimer une table.

Ce que contient réellement un vidage

Habituellement trois choses en séquence. Une instruction qui supprime la table si elle existe, ce qui explique pourquoi exécuter un vidage contre une base en production n’est pas un acte réversible. Une instruction CREATE TABLE qui définit les colonnes et leurs types. Puis les lignes, sous forme d’instructions INSERT — parfois une par ligne, parfois quelques centaines de lignes regroupées dans une seule instruction, ce qui est considérablement plus rapide à charger et bien plus difficile à lire.

Autour de cela, un vrai vidage ajoute des éléments d’intendance : des déclarations d’encodage, des paramètres qui suspendent la reconstruction des index pendant le chargement des données, et une enveloppe transactionnelle pour qu’un échec en cours de route ne laisse rien debout. Cette intendance est spécifique à chaque base, et c’est la raison principale pour laquelle un vidage d’une base ne se chargera pas dans une autre.

Les dialectes, et le problème

La norme spécifie un noyau, et chaque base l’étend. Le format des identificateurs diffère — accents graves en MySQL, guillemets doubles en PostgreSQL, crochets en SQL Server. Les clés auto-incrémentées s’écrivent de trois façons différentes. Les fonctions de date, les fonctions de chaîne, la gestion des booléens et les noms de types eux-mêmes divergent tous.

Donc un vidage MySQL ne se charge pas dans PostgreSQL, et l’erreur produite est généralement une plainte de syntaxe à la ligne quatre plutôt que quoi que ce soit qui explique pourquoi. Convertir entre dialectes est un vrai travail et surtout mécanique ; si vous déplacez des données plutôt qu’un schéma, passer par CSV est très souvent plus rapide et plus fiable que de traduire le SQL.

Charger un fichier sans outil graphique

En ligne de commande, chaque base a son propre client et l’invocation est courte : psql pour PostgreSQL, le client mysql pour MySQL et MariaDB, sqlite3 pour SQLite, tous prenant le fichier en entrée. C’est la voie la plus rapide pour un gros vidage de loin — un outil graphique qui lit le fichier en mémoire d’abord peinera au-delà de quelques centaines de mégaoctets.

Deux choses à faire avant de l’exécuter. Lisez le début du fichier pour voir s’il supprime quelque chose. Et créez la base cible d’abord si le vidage ne la crée pas lui-même, parce qu’un vidage écrit pour un nom de base n’en inventera pas silencieusement un autre.

NULL, et ce que veut dire l’absence

Un fichier SQL distingue la valeur NULL d’une chaîne vide ou d’un zéro, et cette distinction survit mal à beaucoup d’exportateurs. Un vidage de MySQL écrit NULL sans guillemets, un vidage issu d’un tableur convertit souvent la cellule vide en chaîne vide, et le résultat chargé dans une base se retrouve avec un mélange de NULL et de chaînes vides qui n’a aucun sens dans les requêtes.

La règle pratique consiste à vérifier ce que produit l’export sur quelques lignes et à choisir un séparateur explicite si possible. Pour un vidage destiné à un autre système, un passage intermédiaire par CSV avec une convention claire sur les cellules vides évite l’ensemble du problème, au prix d’une étape supplémentaire.

Un vidage correctement écrit enveloppe ses INSERT dans un BEGIN et un COMMIT, ce qui garantit qu’un échec en cours de route laisse la base dans l’état antérieur. Beaucoup de vidages le font, et beaucoup ne le font pas, et un vidage qui ne le fait pas appliqué à une base en production peut très bien laisser la moitié des tables remplies et l’autre vide, sans retour possible. Si le vidage reçu ne le fait pas, deux solutions : envelopper l’exécution dans une transaction côté client, ou charger d’abord dans une base de test avant de toucher à la production. La première est immédiate et protège contre les erreurs de réseau et les coupures de session. La seconde est plus coûteuse en temps mais révèle aussi les erreurs de schéma, qui ne se voient pas toujours à la lecture du fichier.

Pourquoi un import volumineux échoue en cours de route

Habituellement l’une de quatre. Une limite de taille de paquet ou d’instruction, atteinte par un INSERT groupé contenant plusieurs milliers de lignes — la limite du serveur, pas celle du fichier. Un timeout dans un client graphique qui n’a pas d’équivalent en ligne de commande. Une mauvaise correspondance d’encodage, qui se manifeste par du texte maltraité plutôt que par une erreur et qu’il vaut mieux détecter tôt. Ou une contrainte de clé étrangère qui rejette des lignes arrivant avant la table à laquelle elles se réfèrent.

Ce dernier cas est le plus fréquent et le moins évident. Les vidages le gèrent normalement en désactivant la vérification des contraintes autour du chargement, et un vidage édité à la main — quelques tables extraites d’un fichier plus gros — perd cette protection. Charger dans l’ordre des dépendances, ou restaurer l’enveloppe, est la solution.

Quand le vidage n’est pas le bon format pour ce que vous avez

Un vidage sert à recréer une base. Si ce que vous voulez, ce sont les données — pour les analyser, les charger dans un tableur, les remettre à quelqu’un qui ne gère pas de base — le CSV est un meilleur contenant, et le Parquet l’est encore mieux pour tout ce qui est suffisamment volumineux pour que la différence se voie.

L’inverse mérite aussi d’être connu. Transformer un tableur en instructions INSERT est la manière standard d’introduire une table dans une base quand vous n’avez pas de connexion directe vers elle, ce qui est courant avec de l’hébergement géré : aucun port ouvert, mais une console de requêtes qui exécutera volontiers un fichier que vous y collez.

Lire et éditer un fichier en sécurité

C’est du texte, donc n’importe quel éditeur l’ouvre. Un éditeur qui comprend la syntaxe SQL vaut la peine d’être utilisé pour tout ce que vous avez l’intention d’exécuter, parce qu’il colorera les instructions et rendra visible un guillemet non équilibré avant que la base ne le trouve.

Un vidage peut être très volumineux, et la manière sensée d’inspecter un fichier de plusieurs gigaoctets consiste à regarder les premières et dernières dizaines de lignes plutôt que d’ouvrir l’ensemble. Les premières lignes indiquent le dialecte, l’encodage, et si quelque chose est supprimé ; les dernières indiquent si le vidage s’est terminé, ce qui est la chose la plus utile à savoir sur un fichier que quelqu’un vous a envoyé.

Les données, au même endroit

Identifiants et origine du format SQL.
Extension.sql
Type de médiaapplication/sql
Première publication1986
SpécificationISO/IEC 9075