SQLite (prononcé []) est une bibliothèque écrite en langage C qui propose un moteur de base de données relationnelle accessible par le langage SQL. SQLite implémente en grande partie le standard SQL-92 et des propriétés ACID.

Contrairement aux serveurs de bases de données traditionnels, tels que MySQL, MariaDB ou PostgreSQL, sa particularité est de ne pas reproduire le schéma habituel client-serveur mais d'être directement intégrée aux programmes. L'intégralité de la base de données (déclarations, tables, index et données) est stockée dans un fichier indépendant de la plateforme.

D. Richard Hipp, le créateur de SQLite, a choisi de mettre cette bibliothèque ainsi que son code source dans le domaine public, ce qui permet son utilisation sans restriction aussi bien dans les projets open source que dans les projets propriétaires. Le créateur ainsi qu'une partie des développeurs principaux de SQLite sont employés par la société américaine Hwaci..

SQLite est le moteur de base de données le plus utilisé au monde, grâce à son utilisation :

dans de nombreux logiciels grand public comme Firefox, Skype, Google Gears, dans certains produits d'Apple, d'Adobe et de McAfee, dans les bibliothèques standards de nombreux langages comme PHP ou Python.

De par son extrême légèreté (moins de 600 Kio.), il est également très populaire sur les systèmes embarqués, notamment sur la plupart des smartphones et tablettes modernes : les systèmes d'exploitation mobiles iOS, Android et Symbian l'utilisent comme base de données embarquée.. Au total, on peut dénombrer plus d'un milliard de copies connues et déclarées de la bibliothèque..

Historique

D. Richard Hipp et un collègue commencèrent la conception de SQLite début 2000 lorsqu'ils travaillaient chez General Dynamics, alors en contrat avec l'US Navy. SQLite devait être utilisée dans des missiles guidés, dans le but de remplacer des bases de données IBM Informix fonctionnant sur des machines HP-UX. Le principal objectif était de pouvoir s'affranchir de toute installation ou administration : l'installation ou la mise à jour de la base de données Informix pouvait prendre une journée entière.

En , la première version de SQLite est publiée. Elle utilisait gdbm (GNU Database Manager) pour manipuler des arbres B.

SQLite 2.0 supprime la dépendance à gdbm et ajoute la prise en charge des transactions.

SQLite 3.0, produite avec l'aide d'AOL, est publiée en et ajoute, entre autres, la régionalisation (avec le support des collations et de l'Unicode) et la déclaration des types de données.

En , Hipp annonce souhaiter ajouter une interface NoSQL à SQLite, ainsi que UnQL, un sur-ensemble fonctionnel de SQL, conçu pour les bases de données orientées document.

SQLite est l'un des quatre formats recommandés par la bibliothèque du Congrès pour le stockage à long terme des ensembles de données...

Caractéristiques

Base de données embarquée

right La majorité des systèmes de gestion de base de données sont construits selon le paradigme client-serveur, c'est-à-dire qu'une bibliothèque logicielle cliente est intégrée et utilisée dans une ou plusieurs applications alors que le moteur de base de données fonctionne dans un espace d'exécution qui lui est propre, voire sur une machine différente, en tant que service informatique.

SQLite, au contraire, est directement intégrée dans l'application qui utilise sa bibliothèque logicielle, avec son moteur de base de données. L'accès à une base de données avec SQLite se fait par l'ouverture du fichier correspondant à celle-ci : chaque base de données est enregistrée dans un fichier qui lui est propre, avec ses déclarations, ses tables et ses index mais aussi ses données.

Cette caractéristique rend SQLite intéressante comme alternative aux fichiers textes, utilisés comme moyen de stockage intégré dans beaucoup d'applications (paramètres, historique, cache...), car elle rend l'accès aux données plus rapide, plus sécurisé, plus structuré, plus facile et totalement indépendant de la plateforme, tout en ne portant pas atteinte à la facilité de déploiement de l'application qui l'utilise.

La suppression de l'intermédiaire entre l'application et les données permet également de réduire légèrement la latence d'accès aux données comparée aux systèmes utilisant le paradigme client-serveur.

Cependant, cette architecture pose plusieurs problèmes : lorsqu'un nombre important de clients accèdent à une même base, si un des clients commence la lecture d'une partie, la totalité de la base est bloquée en écriture pour les autres clients, et inversement si un des clients démarre l'écriture dans une partie, la totalité de la base est bloquée en lecture pour les autres clients. Ces derniers sont alors mis en attente durant ce laps de temps, ce qui peut être contre-performant ; il est très compliqué de répartir la charge sur plusieurs machines : l'utilisation d'un système de fichiers sur le réseau engendre des latences et un trafic considérable, du fait que la base doit être rechargée chez le client à chaque ouverture. Ce problème est encore plus important avec des sites web où la base est rouverte pour chaque page demandée. De plus, il peut se produire des erreurs dans la synchronisation des verrous sur les fichiers qui pourraient autoriser l'écriture simultanée à deux clients différents sur une même partie de la base et ainsi aboutir à la corruption de la base de données ; avec des bases de grande envergure, il est impossible de diviser la base en plusieurs parties ou fichiers dans le but de distribuer la charge sur plusieurs machines. Certains systèmes de fichiers, comme le FAT 32, ont une taille maximale de fichier qui pourrait rapidement limiter l'expansion d'une base.

Il n'y a pas d'extension propre aux fichiers de base de données de SQLite, mais il est courant de rencontrer des extensions comme .sqlite ou .db, parfois suivie du numéro de version de la bibliothèque (.sqlite3, .db2, etc.). Il est possible d'utiliser une base de données uniquement sauvegardée en mémoire vive, sans créer de fichier de base de données sur le disque, via le nom de fichier spécial :memory:.

D'une manière générale, il est conseillé d'utiliser SQLite là où les données ne sont pas centralisées et où l'expansion de la taille de la base ne risque pas de devenir critique. Si la base de données a pour but de centraliser une grande masse de données et de les fournir à un grand nombre de clients, il est préférable d'utiliser des SGBD basés sur le paradigme client-serveur. SQLite a pour objectif de remplacer les fichiers texte et non les serveurs de base de données traditionnels.

Compilateur et machine virtuelle

right Lorsqu'une requête SQL est transmise à SQLite par l'intermédiaire de l'interface de programmation, elle est compilée avant d'être exécutée.

Le séquenceur du compilateur divise les commandes données en parties traitables séparément (une requête et sa sous-requête par exemple), celles-ci sont passées à l'analyseur syntaxique qui s'occupe de décomposer les requêtes en différents objets qui représentent les différents ordres et clauses du langage SQL. Ces objets sont passés au générateur de code qui crée un code intermédiaire de bas niveau, ou bytecode.

Le code obtenu est un ensemble d'instructions (137 instructions différentes) appelées OpCodes.. Celui-ci est lancé dans la machine virtuelle de SQLite, qui les voit comme de petits programmes décrivant des opérations de recherche, de lecture et de modifications des données..

Lorsque la machine virtuelle interprète ces instructions, elle fait appel au gestionnaire d'arbre B qui repose sur des couches de plus bas niveau dont le cache des pages disque et sa couche d'abstraction matérielle..

Gestion des droits SQLite n'intègre pas de gestion des droits d'accès et de modification des données. La gestion est faite par le système de fichiers du système d'exploitation : si le fichier contenant la base de données n'est pas accessible en écriture à un utilisateur, ce dernier ne pourra également pas modifier les enregistrements et la structure de la base de données.

La gestion des droits avec GRANT et REVOKE est donc inexistante, bien que ceux-ci fassent partie de la spécification SQL-92..

L'utilisation d'une base SQLite ne nécessite aucune procédure d'installation ou de configuration..

Portabilité

La bibliothèque est entièrement écrite en C-ANSI, la version normalisée du langage de programmation C, et n'utilise aucune autre bibliothèque externe que la bibliothèque standard du langage. Ceci rend SQLite compilable sans modification majeure sur toutes les architectures informatiques mettant à disposition un compilateur C respectant la norme ANSI..

Les fichiers de base de données de SQLite sont entièrement indépendants du système d'exploitation et de l'architecture sur laquelle ils sont utilisés. Le même fichier de base de données peut être utilisé sur deux architectures ayant un fonctionnement radicalement différent, SQLite fournissant une couche d'abstraction transparente pour le développeur. Les fichiers sont compatibles entre eux pour chaque version majeure de la bibliothèque depuis la version 3.0.0 de SQLite, ainsi un fichier créé avec la version 3.0.0 sera utilisable avec la version 3.6.19 et vice-versa, les fichiers créés entre deux versions majeures différentes (2.0.0 et 3.0.0 par exemple) peuvent s'avérer compatibles (en particulier en compatibilité ascendante), mais ce n'est pas toujours le cas..

Types de données

SQLite utilise un typage dynamique pour le contenu des cellules, contrairement à la quasi-totalité des SGBD qui utilisent un typage statique : lors de la création d'une nouvelle table dans la base de données, c'est un type recommandé ou d'affinité, non forcé, de la donnée à stocker dans la colonne qui est renseigné et non un type qui définit la façon dont celle-ci sera représentée en mémoire, cette tâche étant réservée à la cellule elle-même. Lorsque des données seront entrées dans la base, SQLite tentera de convertir les nouvelles données vers le type recommandé mais ne le fera pas si cela s'avère impossible..

Il existe plusieurs types d'affinité dans SQLite, ceux-ci définissant la façon dont SQLite va travailler lors de l'entrée des nouvelles données : TEXT : enregistre la donnée comme une chaine de caractères, sans limite de taille. Si un nombre est entré dans une colonne de ce type, il sera automatiquement converti en une chaine de caractères ; NUMERIC : tente d'enregistrer la donnée comme un entier ou comme un réel, mais si cela s'avère impossible, la donnée sera enregistrée comme une chaine de caractères ; INTEGER : enregistre la donnée comme un entier si celle-ci peut être encodée sans perte, mais peut utiliser les types REAL ou TEXT si ça ne peut être fait ; REAL : enregistre la donnée comme un réel, même s'il s'agit d'un entier. Si la valeur est trop grande, la donnée sera convertie en chaine de caractères ; NONE : la donnée est enregistrée telle quelle, sans conversion.

Ainsi, chaque type d'affinité peut accepter n'importe quel type de donnée, la seule exception est le type particulier INTEGER PRIMARY KEY, lorsqu'il est appliqué sur une seule colonne, car il ne s'agit pas d'un type habituel mais d'un alias à la colonne interne au moteur ROWID qui correspond à l'adresse de l'enregistrement, unique à travers la table..

L'utilisation d'un typage dynamique améliore l'homogénéité entre les données de la base de données et les types du langage utilisé pour l'interroger si celui-ci est également un langage au typage dynamique (comme Python, PHP, Perl ou Ruby) sans poser de réels problèmes avec les langages utilisant un typage statique (comme C/C++ ou Java).

Détermination du type d'affinité

Pour maintenir la compatibilité avec les autres bases de données relationnelles, SQLite convertit automatiquement les noms des types déclarés dans le type d'affinité correspondant le mieux, ainsi :