Příručka:Schéma databáze - změny

From mediawiki.org
This page is a translated version of the page Manual:Schema changes and the translation is 100% complete.

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)

Hlavní stránka: Manual:SQL patch file

V této metodě, která se používá do roku 2020 při provádění změny schématu:

  1. Změňte tables.sql na dvou různých místech (maintenance/tables.sql za MySQL a maintenance/postgres/tables.sql za PostgreSQL)
  2. 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
  3. Propojte tyto soubory DDL (z kroku 2) do MysqlUpdater, SqliteUpdater, PostgresUpdater

Příklady

Automatické generování

Verze MediaWiki:
1.35

Abstraktní schéma pro všechny tabulky jádra MediaWiki najdete v "maintenance/tables.json". Tato abstrakce používá ke generování souborů DDL Doctrine DBAL library (knihovna doktrín DBAL).

  1. Změňte strukturu tables.json.
  2. Spusťte skript údržby a vygenerujte tři soubory DDL:
    php maintenance/run.php generateSchemaSql.php --json maintenance/tables.json --sql maintenance/ --type=all
    
  3. Vytvořte soubor .json změny abstraktního schématu (viz níže) a vložte jej do adresáře maintenance/abstractSchemaChanges/
  4. Sestavte opravy schématu pomocí skriptu údržby, například:
    php maintenance/run.php generateSchemaChangeSql.php --json maintenance/abstractSchemaChanges/patch-logging-rename-indexes.json --sql maintenance/archives/ --type=all
    
  5. Přidejte je k MysqlUpdater, SqliteUpdater, PostgresUpdater
  6. 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é.
Common Doctrine DBAL typy a jejich ekvivalent
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
1.36
mwtimestamp BINARY(14)/VARBINARY(14) (if "allowInfinite":true) BLOB TIMESTAMPTZ
1.36
mwtinyint TINYINT SMALLINT SMALLINT
1.36


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).