Manuel:Modifications du schéma
Ceci est une page d'aide qui décrit la manière de réaliser les correctifs de modification du schéma pour le noyau MediaWiki et ses extensions, à destination des personnes qui doivent modifier la structure de la base se données au cours de leur travail de développement.
Glossaire
- Schéma - Structure actuelle de la base de données MediaWiki.
- Modification du schéma - Une partie atomique de la migration du schéma qui est ajoutée par une validation. Par exemple Ajouter la table 'foo' , Supprimer la colonne 'bar' de la table 'baz' etc.
- Database management system (DBMS) — système de gestion de base de données - La technologie sous-jascente gérant la base de données. Sont pris en charge par le noyau MediaWiki : MySQL, SQLite et PostgreSQL. Il peut y en avoir d'autres en utilisant des extensions.
- Data definition language (DDL) — langage de définition des données - Syntaxe définissant le schéma et les définitions du schéma (peut être différent selon le DBMS). Par exemple ALTER TABLE, DROP COLUMN. Ils sont stockés en tant que fichiers .sql.
- Database Abstraction Layer (DBAL) — niveau d'abstraction de la base de données - Pont entre le schéma de la base de données indépendant du DBMS, les définitions de modification du schéma et les DDL actuels.
Présentation
Chaque modification du schéma doit gérer deux parties. D'abord les nouvelleles installations doivent avoir le nouveau schéma au lieu de l'ancien, et ensuite les anciennes installations doivent pouvoir être mises à jour vers les nouvelles. Pour les premières, on corrige les fichiers DDL du schéma (sauvegardé dans tables.sql) et pour les secondes on fournit des correctifs ALTER TABLE que l'on intègre dans la logique de mise à jour.
Nous sommes au milieu d'une migration qui part d'un DDL dédié par DBMS vers un seul schéma abstrait. Selon la table, vous pouvez modifier plusieurs fichiers SQL bruts, ou modifier un fichier json en générant les fichiers SQL via un script de maintenance.
Manuel (obsolète)
Dans cette méthode utilisée jusqu'en 2020, quand vous réalisez une modification du schéma :
- Changez tables.sql à deux endroits différents (maintenance/tables.sql pour MySQL et maintenance/postgres/tables.sql pour PostgreSQL)
- Faites un fichier de modification du DDL du schéma comme chemin de mise à niveau des installations actuelles pour MySQL et mettez le fichier dans maintenance/archives/
- Si les autres types de DBMS ne fonctionnent pas avec ce patch, vous devez leur faire un patch spécifique. Par exemple, SQLite n'a pas de ALTER TABLE, ce qui signifie que vous devez créer une table temporaire, y recopier les données, supprimer l'ancienne table et renommer la nouvelle table avec l'ancien nom. Exemple
- Lier ces fichiers DDL (de l'étape 2) dans MysqlUpdater, SqliteUpdater, PostgresUpdater
Exemples
- Supprimer une colonne - Noter que nous avons pris en charge cinq DBMS au lieu de trois
- Modifier les index
- Ajouter une nouvelle table
Généré automatiquement
Version de MediaWiki : | ≥ 1.35 |
maintenance/tables.json contient le schéma abstrait de toutes les tables du noyau MediaWiki. Cette abstraction utilise la bibliothèque Doctrine DBAL pour générer les fichiers DDL. On your local working MediaWiki install, with the relevant extension installed, you should:
- Modifier la structure tables.json.
- Exécuter le script de maintenance pour générer les trois fichiers DDL :
php maintenance/run.php generateSchemaSql.php --json maintenance/tables.json --sql maintenance/ --type=all
- Créer un fichier .json de modification du schéma abstrait (voir ci-dessous) et le mettre dans le répertoire maintenance/abstractSchemaChanges/
- Construire les correctifs du schéma en utilisant le script de maintenance, par exemple :
php maintenance/run.php generateSchemaChangeSql.php --json maintenance/abstractSchemaChanges/patch-logging-rename-indexes.json --sql maintenance/archives/ --type=all
- Les ajouter à MysqlUpdater, SqliteUpdater, PostgresUpdater
- Ne pas oublier de sortir de Git vos modifications ainsi que les fichiers DDL générés automatiquement lorsque vous faites le correctif.
Exemples de correctifs
Exemple de schéma abstrait
[
{
"name": "actor",
"comment": "The \"actor\" table associates user names or IP addresses with integers for the benefit of other tables that need to refer to either logged-in or logged-out users. If something can only ever be done by logged-in users, it can refer to the user table directly.",
"columns": [
{
"name": "actor_id",
"comment": "Unique ID to identify each actor",
"type": "bigint",
"options": { "unsigned": true, "notnull": true, "autoincrement": true }
},
{
"name": "actor_user",
"comment": "Key to user.user_id, or NULL for anonymous edits",
"type": "integer",
"options": { "unsigned": true, "notnull": false }
},
{
"name": "actor_name",
"comment": "Text username or IP address",
"type": "binary",
"options": { "length": 255, "notnull": true }
}
],
"indexes": [
{ "name": "actor_user", "columns": [ "actor_user" ], "unique": true },
{ "name": "actor_name", "columns": [ "actor_name" ], "unique": true }
],
"pk": [ "actor_id" ]
}
]
Notes
- La valeur par défaut dans Doctrine DBAL est
"notnull": true
. Si vous souhaitez que votre colonne soit nulle, faites le explicitement via"notnull": false
. - La liste des types de colonnes de la Doctrine DBAL est disponible dans : https://github.com/doctrine/dbal/blob/3.3.8/src/Types/Types.php
- Depuis MediaWiki 1.38, les types de Doctrine DBAL qui ne sont pas énumérés dans le tableau suivant ne sont pas disponibles.
Doctrine DBAL/Schéma abstrait | MySQL | SQLite | PostgreSQL | Version | |
---|---|---|---|---|---|
bigint | BIGINT | BIGINT | BIGSERIAL (si auto-incrémenté)/BIGINT | ||
binary | VARBINARY | BLOB | TEXT | ||
blob | TINYBLOB/BLOB/MEDIUMBLOB/LONGBLOB (fonction de la taille) | BLOB | TEXT | ||
datetimetz | DATETIME | DATETIME | TIMESTAMPTZ (1.36+) TIMESTAMP(0) WITH TIME ZONE (1.35) |
||
float | FLOAT/DOUBLE PRECISION (if "doublePrecision":true ) (1.36+)DOUBLE PRECISION (1.35) |
DOUBLE PRECISION | FLOAT/DOUBLE PRECISION (if "doublePrecision":true ) (1.36+)DOUBLE PRECISION (1.35) |
||
integer | INT | INTEGER | INT | ||
smallint | SMALLINT | SMALLINT | SMALLINT | ||
string | VARCHAR | VARCHAR | VARCHAR | ||
text | TINYTEXT/TEXT/MEDIUMTEXT/LONGTEXT (fonction de la taille) | CLOB | TEXT | ||
mwenum | ENUM | TEXT | TEXT |
| |
mwtimestamp | BINARY(14)/VARBINARY(14) (if "allowInfinite":true )
|
BLOB | TIMESTAMPTZ |
| |
mwtinyint | TINYINT | SMALLINT | SMALLINT |
|
Modification du schéma abstrait
Pour effectuer une modification du schéma, créer un fichier json à partir d'une capture de l'écran précédent et après les schémas abstraits pour la table (une modification de schema par table, s'il vous plaît). Ensuite, exécutez un script de maintenance de la même manière et il fera la différence entre deux tables et génèrera automatiquement les fichiers DDL de changement du schéma.
Exemple de modification du schéma abstrait
{
"before": {
"name": "actor",
"columns": [
{
"name": "actor_id",
"type": "bigint",
"options": { "unsigned": true, "notnull": true, "autoincrement": true }
},
{
"name": "actor_user",
"type": "integer",
"options": { "unsigned": true, "notnull": false }
},
{
"name": "actor_name",
"type": "binary",
"options": { "length": 255, "notnull": true }
}
],
"indexes": [
{ "name": "actor_user", "columns": [ "actor_user" ], "unique": true },
{ "name": "actor_name", "columns": [ "actor_name" ], "unique": true }
],
"pk": [ "actor_id" ]
},
"after": {
"name": "actor",
"columns": [
{
"name": "actor_id",
"type": "bigint",
"options": { "unsigned": true, "notnull": true, "autoincrement": true }
},
{
"name": "actor_user",
"type": "bigint",
"options": { "unsigned": true, "notnull": false }
},
{
"name": "actor_name",
"type": "binary",
"options": { "length": 255, "notnull": true }
}
],
"indexes": [
{ "name": "actor_user", "columns": [ "actor_user" ], "unique": true },
{ "name": "actor_name", "columns": [ "actor_name" ], "unique": true }
],
"pk": [ "actor_id" ]
}
}
Les deux tables sont les mêmes mais le type de actor_user est passé de integer à bigint. La raison de faire une différence plutôt qu'une abstraction de la modification elle-même est que SQLite dans la plupart des cas ne dispose pas de ALTER TABLE, ce qui signifie que DBAL doit connaître le schéma pour construire un fichier DDL de modification du schéma utilisant des tables temporaires.
Meilleures pratiques pour choisir le type de données
- Pour les horodatages, utiliser le type de données mwtimestamp (phab:T42626).
- Au lieu de VARCHAR ou CHAR, utiliser VARBINARY ou BINARY (sinon vous devrez vous occuper de l'encodage dans les bases de données)
- À moins que vous n'ayez vraiment besoin d'une valeur négative, utilisez UNSIGNED pour tout type de valeur entière pour en doubler la capacité.
- L'utilisation de ENUM est à éviter fortement (phab:T119173).