Impostare i set di caratteri e le collation
In MariaDB, il set di caratteri predefinito è latin1, mentre la collation predefinita è latin1_swedish_ci. Il set di caratteri e la collation possono essere specificati a livello di server e, via via verso i livelli più specifici, fino al livello di colonna, ma anche a livello di connessione client-server. Quando si cambia il set di caratteri senza specificare una collation, viene utilizzata quella di default. Il set di caratteri e la collation possono essere visualizzati con l'istruzione SHOW COLLATION. Per esempio, se si vuole conoscere la collation di default di latin2:
SHOW COLLATION LIKE 'latin2%'; +---------------------+---------+----+---------+----------+---------+ | Collation | Charset | Id | Default | Compiled | Sortlen | +---------------------+---------+----+---------+----------+---------+ | latin2_czech_cs | latin2 | 2 | | Yes | 4 | | latin2_general_ci | latin2 | 9 | Yes | Yes | 1 | | latin2_hungarian_ci | latin2 | 21 | | Yes | 1 | | latin2_croatian_ci | latin2 | 27 | | Yes | 1 | | latin2_bin | latin2 | 77 | | Yes | 1 | +---------------------+---------+----+---------+----------+---------+
Quando si cambia set di caratteri o collation la modifica si propaga verso il basso, quindi ad esempio una colonna per la quale non è stata specificata una collation utilizzerà quella di default della tabella se esiste, la tabella userà quella del database se esiste, e il database quella del server. E' quindi possibile avere un controllo estremamente granulare sui set di caratteri e le collation utilizzati.
Livello Server
La variabile di sistema character_set_server serve a modificare il character set predefinito del server. Può essere impostata all'avvio o dinamicamente, con il comando SET:
SET character_set_server = 'latin2';
Similarmente, la variabile collation_server determina la collation di default del server.
SET collation_server = 'latin2_czech_cs';
Livello Database
Le istruzioni CREATE DATABASE e ALTER DATABASE hanno le clausole opzionali character set e collation. Se non sono specificate, vengono utilizzati i valori predefiniti.
CREATE DATABASE czech_slovak_names CHARACTER SET = 'keybcs2' COLLATE = 'keybcs2_bin';
ALTER DATABASE czech_slovak_names COLLATE = 'keybcs2_general_ci';
Ecco come determinare il character set di default utilizzato da un database:
SHOW CREATE DATABASE czech_slovak_names; +--------------------+--------------------------------------------------------------------------------+ | Database | Create Database | +--------------------+--------------------------------------------------------------------------------+ | czech_slovak_names | CREATE DATABASE `czech_slovak_names` /*!40100 DEFAULT CHARACTER SET keybcs2 */ | +--------------------+--------------------------------------------------------------------------------+
In alternativa, per il character set e la collation:
SELECT * FROM INFORMATION_SCHEMA.SCHEMATA; +--------------+--------------------+----------------------------+------------------------+----------+ | CATALOG_NAME | SCHEMA_NAME | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME | SQL_PATH | +--------------+--------------------+----------------------------+------------------------+----------+ | def | czech_slovak_names | keybcs2 | keybcs2_general_ci | NULL | | def | information_schema | utf8 | utf8_general_ci | NULL | | def | mysql | latin1 | latin1_swedish_ci | NULL | | def | performance_schema | utf8 | utf8_general_ci | NULL | | def | test | latin1 | latin1_swedish_ci | NULL | +--------------+--------------------+----------------------------+------------------------+----------+
E' anche possibile specificare solo la collation: siccome ogni collation è associata a un solo character set, questo verrà impostato automaticamente.
CREATE DATABASE danish_names COLLATE 'utf8_danish_ci'; SHOW CREATE DATABASE danish_names; +--------------+----------------------------------------------------------------------------------------------+ | Database | Create Database | +--------------+----------------------------------------------------------------------------------------------+ | danish_names | CREATE DATABASE `danish_names` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_danish_ci */ | +--------------+----------------------------------------------------------------------------------------------+
Anche se vi sono le variabili character_set_database e collation_database, che possono essere impostate dinamicamente, esse sono utilizzate per impostare il character set e la collation del database di default, e dovrebbero essere impostate solo dal server.
Livello Tabella
Le istruzioni CREATE TABLE e ALTER TABLE supportano le clausole opzionali character set e collation, un'estensione di MariaDB e MySQL allo standard SQL.
CREATE TABLE english_names (id INT, name VARCHAR(40)) CHARACTER SET 'utf8' COLLATE 'utf8_icelandic_ci';
Se nessuna delle due è specificata, vengono usati i valori di default del database. Se si specifica solo il character set, viene usata la collation di default del character set scelto. Se si specifica solo la collation, viene usato il character set a questa associato.
Livelo Colonna
I character set e le collattion possono essere specificati anche per le colonne di tipo carattere - CHAR, TEXT e VARCHAR. Le istruzioni CREATE TABLE e ALTER TABLE supportano le clausole opzionali character set e collation a questo scopo - a differenza di quelle a livello di tabella, quelle a livello di colonna sono definite nello standard SQL.
CREATE TABLE european_names ( croatian_names VARCHAR(40) COLLATE 'cp1250_croatian_ci', greek_names VARCHAR(40) CHARACTER SET 'greek');
Se nessuna delle due è specificata, vengono usati i valori di default della tabella. Se è specificato solo il character set viene utilizzata la collation di default di quel set di caratteri, mentre se è specificata solo la collation viene usato il character set ad essa associato.
Se si usa ALTER TABLE per modificare il character set di una colonna, occorre accertarsi che quel set di caratteri sia compatibile con i propri dati. MariaDB mappa i caratteri come può, ma se non si presta attenzione è possibile perdere dei dati.
E' possibile servirsi dell'istruzione SHOW CREATE TABLE o del database INFORMATION SCHEMA per determinare i set di caratteri e le collation delle colonne.
SHOW CREATE TABLE european_names\G *************************** 1. row *************************** Table: european_names Create Table: CREATE TABLE `european_names` ( `croatian_names` varchar(40) CHARACTER SET cp1250 COLLATE cp1250_croatian_ci DEFAULT NULL, `greek_names` varchar(40) CHARACTER SET greek DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_danish_ci
SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME LIKE 'european%'\G *************************** 1. row *************************** TABLE_CATALOG: def TABLE_SCHEMA: danish_names TABLE_NAME: european_names COLUMN_NAME: croatian_names ORDINAL_POSITION: 1 COLUMN_DEFAULT: NULL IS_NULLABLE: YES DATA_TYPE: varchar CHARACTER_MAXIMUM_LENGTH: 40 CHARACTER_OCTET_LENGTH: 40 NUMERIC_PRECISION: NULL NUMERIC_SCALE: NULL DATETIME_PRECISION: NULL CHARACTER_SET_NAME: cp1250 COLLATION_NAME: cp1250_croatian_ci COLUMN_TYPE: varchar(40) COLUMN_KEY: EXTRA: PRIVILEGES: select,insert,update,references COLUMN_COMMENT: *************************** 2. row *************************** TABLE_CATALOG: def TABLE_SCHEMA: danish_names TABLE_NAME: european_names COLUMN_NAME: greek_names ORDINAL_POSITION: 2 COLUMN_DEFAULT: NULL IS_NULLABLE: YES DATA_TYPE: varchar CHARACTER_MAXIMUM_LENGTH: 40 CHARACTER_OCTET_LENGTH: 40 NUMERIC_PRECISION: NULL NUMERIC_SCALE: NULL DATETIME_PRECISION: NULL CHARACTER_SET_NAME: greek COLLATION_NAME: greek_general_ci COLUMN_TYPE: varchar(40) COLUMN_KEY: EXTRA: PRIVILEGES: select,insert,update,references COLUMN_COMMENT:
Letterali
I set di caratteri e le collation possono essere specificati anche per i letterali.
[_charset_name]'string' [COLLATE collation_name]
Per esempio:
SELECT _latin2 'Müller'; +-----------+ | MĂźller | +-----------+ | MĂźller | +-----------+
SELECT 'Mueller' = 'Müller' COLLATE 'latin1_german2_ci'; +---------------------------------------------------+ | 'Mueller' = 'Müller' COLLATE 'latin1_german2_ci' | +---------------------------------------------------+ | 1 | +---------------------------------------------------+