Příručka:Schéma databáze - změny
Toto je stránka nápovědy popisující, jak vytvořit záplaty změny schématu pro jádro MediaWiki a jeho rozšíření pro lidi, kteří potřebují změnit rozložení databáze jako součást své vývojové práce.
Slovník pojmů (glosář)
- Schéma - aktuální rozvržení databáze MediaWiki.
- Změna schématu - atomická část migrace schématu, která se přidává prostřednictvím potvrzení. Například "Přidání tabulky foo", "Vypuštění sloupce z tabulky baz" a tak dále.
- Database management system (DBMS) (systém pro správu databází) - základní technologie spravující databázi MediaWiki. V jádru MediaWiki jsou podporované: MySQL, SQLite a PostgreSQL. Může to být více pomocí rozšíření.
- Data definition language (DDL) (jazyk pro definici dat) - syntaxe, která definuje schéma a změny schématu (v různých DBMS se může lišit). Například "ALTER TABLE", "DROP COLUMN". Jsou uloženy jako soubory ".sql".
- Database Abstraction Layer (DBAL) (vrstva abstrakce databáze) - most mezi databázovým schématem nezávislým na DBMS a definicemi změn schématu a skutečnými DDL.
Přehled
Každá změna schématu musí zvládnout dvě části. Za prvé, nové instalace musí mít nové schéma místo starého a za druhé, stará instalace musí být schopna aktualizovat na nové. V první části opravíme soubory DDL schématu (uložené jako tables.sql) a pro druhou část poskytneme záplaty "ALTER TABLE" a zapojíme je do logiky aktualizátoru.
Jsme uprostřed migrace z jednoho vyhrazeného DDL na DBMS na pouze jedno abstrahované schéma. V závislosti na tabulce můžete změnit několik nezpracovaných souborů SQL nebo změnit pouze jeden soubor json a vygenerovat soubory SQL pomocí skriptu údržby.
Manuální změna schématu (nedoporučeno)
V této metodě, která se používá do roku 2020 při provádění změny schématu:
- Změňte tables.sql na dvou různých místech (maintenance/tables.sql za MySQL a maintenance/postgres/tables.sql za PostgreSQL)
- Proveďte soubor DDL se změnou schématu jako cestu aktualizace aktuálních instalací pro MySQL a vložte soubor do maintenance/archives/
- Pokud jiné typy DBMS s touto opravou nefungují, musíte pro ně vytvořit vyhrazenou opravu. Například SQLite nemá ALTER TABLE, což znamená, že musíte vytvořit dočasnou tabulku, zkopírovat data, odstranit starou tabulku a přejmenovat novou tabulku na starý název. Příklad
- Propojte tyto soubory DDL (z kroku 2) do MysqlUpdater, SqliteUpdater, PostgresUpdater
Příklady
- Vypuštění sloupce - všimněte si, že jsme dříve podporovali pět DBMS místo tří
- Změna indexů
- Přidání nové tabulky
Automatické generování
Verze MediaWiki: | ≥ 1.35 |
Abstraktní schéma pro všechny tabulky jádra MediaWiki najdete v "sql/tables.json". Tato abstrakce používá ke generování souborů DDL Doctrine DBAL library (knihovna doktrín DBAL). On your local working MediaWiki install, with the relevant extension installed, you should:
- Změňte strukturu tables.json.
- Spusťte skript údržby a vygenerujte tři soubory DDL:
php maintenance/run.php generateSchemaSql.php --json sql/tables.json --sql sql/ --type=all
- Vytvořte soubor .json změny abstraktního schématu (viz níže) a vložte jej do adresáře sql/abstractSchemaChanges/
- Sestavte opravy schématu pomocí skriptu údržby, například:
php maintenance/run.php generateSchemaChangeSql.php --json sql/abstractSchemaChanges/patch-logging-rename-indexes.json --sql sql/ --type=all
- Přidejte je k MysqlUpdater, SqliteUpdater, PostgresUpdater
- Při vytváření opravy nezapomeňte zkontrolovat změny a automaticky generované soubory DDL v gitu.
Příklad patchů
Příklad abstraktního schématu
[
{
"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" ]
}
]
Poznámky
- Výchozí hodnota v Doctrine DBAL je
"notnull": true
. Pokud chcete, aby váš sloupec mohl mít hodnotu null, nastavte jej explicitně pomocí"notnull": false
. - Seznam typů sloupců Doctrine DBAL lze nalézt v: https://github.com/doctrine/dbal/blob/3.3.8/src/Types/Types.php
- Od MediaWiki 1.38 nejsou typy Doctrine DBAL, které nejsou uvedeny v následující tabulce, dostupné.
Doktrína DBAL/Abstraktní schéma | MySQL | SQLite | PostgreSQL | Verze | |
---|---|---|---|---|---|
bigint | BIGINT | BIGINT | BIGSERIAL (pokud autoinkrementace)/BIGINT | ||
binary | VARBINARY | BLOB | TEXT | ||
blob | TINYBLOB/BLOB/MEDIUMBLOB/LONGBLOB (na základě velikosti) | 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 (na základě velikosti) | CLOB | TEXT | ||
mwenum | ENUM | TEXT | TEXT |
| |
mwtimestamp | BINARY(14)/VARBINARY(14) (if "allowInfinite":true )
|
BLOB | TIMESTAMPTZ |
| |
mwtinyint | TINYINT | SMALLINT | SMALLINT |
|
Změna abstraktního schématu
Pro provedení změny schématu vytvoříte soubor json se snímkem abstraktních schémat pro tabulku před a po (prosím jedna změna schématu na tabulku). Potom podobným způsobem spustíte skript údržby, který se bude lišit mezi dvěma tabulkami a poté automaticky vygeneruje soubory DDL pro změnu schématu.
Příklad změny abstraktního schématu
{
"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" ]
}
}
Tyto dvě tabulky jsou stejné, ale typ "actor_user" se změnil z "integer" na "bigint". Důvodem rozdílu namísto abstrahování samotné změny je to, že SQLite ve většině případů nemá ALTER TABLE, což znamená, že DBAL potřebuje znát schéma, aby mohl vytvořit soubor DDL se změnou schématu pomocí dočasných tabulek.
Nejlepší postupy při výběru typu dat
- Pro časová razítka použijte datový typ mwtimestamp (phab:T42626).
- Místo VARCHAR nebo CHAR použijte VARBINARY nebo BINARY (jinak se musíte vypořádat s kódováním v databázích)
- Pokud skutečně nepotřebujete zápornou hodnotu, použijte UNSIGNED pro jakýkoli typ celočíselné hodnoty, abyste zdvojnásobili jeho kapacitu.
- Použití ENUM se důrazně nedoporučuje (phab:T119173).