Aller au contenu
guide technique

Poser des questions à MySQL en langage naturel

Interroger MySQL en langage naturel : utilisateur en lecture seule, TLS pour MySQL 8, les réglages serveur qui changent le SQL généré, la lecture sur réplica.

Par l'équipe Datarelix · Publié le

Vous pouvez poser des questions à MySQL en langage naturel, et l’histoire de la sûreté est courte : un utilisateur MySQL doté de SELECT et de rien d’autre ne peut pas écrire, et chaque instruction générée est de surcroît validée avant de s’exécuter. Ce que MySQL ajoute est opérationnel — l’authentification de la version 8 réclame TLS, la base de données est le périmètre entier, et une poignée de réglages serveur façonnent en silence le SQL généré comme les réponses.

À qui ce guide s’adresse, et ce qu’il suppose

Aux ingénieurs et analystes qui exploitent MySQL — RDS, Cloud SQL, Azure Database for MySQL, PlanetScale ou autogéré en 5.7+/8.x — et qui évaluent si l’interrogation en langage naturel peut y être pointée sans risque. Il suppose que vous pouvez exécuter CREATE USER et GRANT. Le formulaire de connexion champ par champ est dans le guide de connexion MySQL.

Un utilisateur, un privilège, une base

MySQL n’a pas de couche de schéma distincte de la base : la base est le périmètre — et tout le modèle de privilèges d’une analytique en lecture seule tient en trois instructions :

CREATE USER 'datarelix_reader'@'%' IDENTIFIED BY 'choisissez-un-mot-de-passe-fort';
GRANT SELECT ON votre_base.* TO 'datarelix_reader'@'%';
FLUSH PRIVILEGES;

Le joker d’hôte '%' accepte les connexions depuis toute adresse ; resserrez-le sur un CIDR si votre serveur applique un contrôle par hôte, en vous rappelant que MySQL apparie utilisateur et hôte ensemble. Le modèle complet est dans la référence GRANT de MySQL.

Prouvez la frontière avant d’aller plus loin, connecté avec le nouvel utilisateur :

-- Doit lister exactement un privilège : SELECT ON `votre_base`.*
SHOW GRANTS FOR CURRENT_USER();

-- Doit échouer avec « command denied », et c'est le but :
CREATE TABLE ne_doit_pas_marcher (id INT);

Ce privilège est la frontière qui vous appartient. La seconde se tient devant votre serveur quoi qu’il arrive : chaque instruction générée est analysée en arbre syntaxique complet et rejetée si ce n’est pas une lecture, si bien que INSERT, UPDATE, DELETE, le DDL et les échappatoires propres à MySQL n’ont aucun chemin, même si un identifiant trop privilégié était un jour fourni. Le mécanisme et son modèle de menace sont dans l’analytique IA en lecture seule.

L’authentification MySQL 8 demande TLS

MySQL 8 a fait de caching_sha2_password le greffon d’authentification par défaut, et celui-ci refuse d’envoyer un mot de passe sur un canal non sécurisé — l’erreur nomme le greffon et dit « requires secure connection ». Les MySQL managés servent TLS d’office ; en pratique, cela ne mord que les serveurs autogérés sans certificats. Connectez-vous en TLS ; retomber sur mysql_native_password fonctionne, mais soigne le symptôme plutôt que le transport. Une note Azure : Flexible Server prend le nom d’utilisateur nu — le suffixe user@servername appartenait au Single Server retiré et ne cause plus que des échecs de connexion.

Le SQL généré parle le dialecte MySQL, pas un SQL générique

Sur le schéma d’un détaillant fictif, « Comment le chiffre d’affaires mensuel a-t-il évolué sur les six derniers mois ? » génère quelque chose comme :

SELECT
  DATE_FORMAT(o.ordered_at, '%Y-%m') AS mois,
  SUM(oi.quantity * oi.unit_price) AS chiffre_affaires
FROM orders AS o
JOIN order_items AS oi ON oi.order_id = o.order_id
WHERE o.status = 'completed'
  AND o.ordered_at >= DATE_SUB(CURDATE(), INTERVAL 6 MONTH)
GROUP BY DATE_FORMAT(o.ordered_at, '%Y-%m')
ORDER BY mois;

Les marqueurs d’un vrai MySQL : l’arithmétique de dates DATE_SUB/CURDATE, DATE_FORMAT pour le grain mensuel, LIMIT plutôt que TOP ou FETCH FIRST, les accents graves seulement quand un identifiant l’exige, et un GROUP BY qui satisfait le mode de regroupement strict. Comment une question devient cette requête est expliqué dans text-to-SQL expliqué — et les décisions incorporées ici (commandes terminées seulement, brut des remboursements, mois civils) sont exactement ce que la vérification de la requête sert à attraper.

Les réglages serveur qui changent les réponses en silence

Réalité serveurComment cela se manifesteCe qu’il faut savoir
ONLY_FULL_GROUP_BY — actif par défaut depuis la 5.7Sur un serveur où quelqu’un l’a désactivé, une colonne non agrégée dans une requête groupée renvoie une valeur de ligne arbitraire — en silence.Le SQL généré agrège chaque colonne sélectionnée, ce qui est correct dans les deux réglages. C’est dans les rapports historiques écrits à la main que vit la version silencieuse de ce bogue.
TIMESTAMP contre DATETIMETIMESTAMP convertit via le fuseau de session ; DATETIME est stocké tel quel, sans fuseau. Le mélange fausse les fenêtres temporelles.Sachez lequel votre schéma utilise avant de croire un chiffre au grain horaire.
CONVERT_TZ avec des fuseaux nommésRenvoie NULL tant que les tables de fuseaux du serveur ne sont pas chargées — le classique des résultats soudain vides.Chargez-les avec mysql_tzinfo_to_sql, selon la gestion des fuseaux de MySQL.
Collations mélangéesJoindre une colonne utf8mb3 à une colonne utf8mb4 peut lever « Illegal mix of collations » ou cesser d’utiliser un index, sans bruit.Se voit surtout sur d’anciennes bases migrées sur place.
lower_case_table_namesLes noms de tables sont sensibles à la casse sur Linux par défaut, insensibles sur Windows et macOS.Un nom qui marchait sur le portable de dev peut manquer la table en production. La découverte remonte les noms exactement comme le serveur les stocke.
Pas de FULL OUTER JOINMySQL ne l’a tout simplement pas.L’équivalent généré est une UNION de jointures gauche et droite — plus verbeux, même résultat.
Tables MyISAMLe moteur historique n’a aucune prise en charge des clés étrangères : les vieilles tables ne portent aucune relation déclarée.Les chemins de jointure sont alors inférés du nommage — voir ci-dessous.

Visez un réplica, pas le serveur primaire

Les questions analytiques n’ont jamais besoin d’écrire, ce qui fait d’un réplica en lecture la cible naturelle : le primaire continue de servir l’application pendant que les balayages ad hoc atterrissent ailleurs, et le privilège de l’utilisateur lecteur se réplique avec le reste. RDS, Cloud SQL et Azure proposent tous des réplicas en une case à cocher. La seule réserve est le retard de réplication — une réponse peut être en retrait de quelques secondes sur le primaire. Pour une question analytique, cela compte rarement ; pour une question « que se passe-t-il en ce moment », cela vaut la peine de savoir quel point de terminaison vous avez connecté.

Connecter MySQL à Datarelix

Datarelix se connecte à MySQL 5.7+ et 8.x par nom d’utilisateur et mot de passe ou par chaîne de connexion mysql:// ; le mot de passe est stocké chiffré, chaque autre champ en configuration simple. Les greffons mysql_native_password et caching_sha2_password fonctionnent tous deux. L’introspection parcourt INFORMATION_SCHEMA pour les tables, colonnes, clés primaires et clés étrangères déclarées — sur les bases adossées à Vitess comme PlanetScale, où les clés étrangères sont d’ordinaire absentes, la découverte ne trouve aucune relation déclarée et les jointures sont inférées du nommage des colonnes : vérifiez les jointures des premières réponses et décrivez les colonnes cryptiques — pourquoi le contexte sémantique compte.

Chaque requête s’exécute sous un plafond de temps d’exécution de 30 secondes appliqué côté serveur, les résultats sont plafonnés à 5 000 lignes, et un LIMIT manquant est ajouté automatiquement. La configuration et le tableau de dépannage sont dans le guide de connexion MySQL.

Les limites sur MySQL

Une base par connexion — les jointures inter-bases dans une même question sont exclues, même si le SQL de MySQL sait adresser autre_base.table. Il n’existe aucun chemin d’écriture, et aucun n’est prévu. Le plafond de lignes fait de l’export massif le mauvais outil. Et la qualité des réponses suit celle du schéma : une base bien nommée aux clés déclarées répond bien ; un schéma historique fait de colonnes cryptiques, de tables MyISAM et de codes de statut non documentés produit du SQL fluide sur la mauvaise colonne, jusqu’à ce que vous curiez des descriptions.

Références

Le comportement des privilèges suit la référence GRANT de MySQL ; celui du greffon d’authentification suit la documentation de caching_sha2_password ; celui des fuseaux horaires suit la gestion des fuseaux de MySQL. Les affirmations produit décrivent Datarelix tel que livré en août 2026 et sont énoncées canoniquement sur la page sécurité. L’exemple SQL utilise un schéma de démonstration fictif ; il est illustratif, pas une sortie capturée.

Créez le lecteur, puis reposez une question déjà tranchée

Exécutez les trois instructions ci-dessus — sur un réplica si vous en avez un — puis suivez le guide de démarrage et posez une question à laquelle vos rapports existants répondent déjà. Comparez les définitions du SQL généré à celles du rapport avant de comparer les chiffres. Vos 14 premiers jours tournent aux limites Pro, sans carte bancaire.