12.2.1 Набор символов
Набор символов — это коллекция символов в наборе.
Строковые выражения имеют атрибут repertoires, который может принимать два значения:
ASCII: выражение может содержать только символы ASCII; другими словами, символы в диапазоне ЮникодаU+0000доU+007F.UNICODE: выражение может содержать символы в диапазоне ЮникодаU+0000доU+10FFFF. Это включает символы в базовой многоязычной плоскости (BMP) в диапазоне (U+0000доU+FFFF) и дополнительные символы за пределами диапазона BMP (U+10000доU+10FFFF).
Диапазон ASCII является подмножеством диапазона UNICODE, поэтому строку с набором символов ASCII можно безопасно преобразовать в набор символов любой строки с набором символов UNICODE без потери информации. Её также можно безопасно преобразовать в любой набор символов, являющийся надмножеством набора символов ascii. (Все наборы символов MySQL являются надмножествами ascii, за исключением swe7, который повторно использует некоторые знаки препинания для шведских акцентированных символов.)
Использование repertoires позволяет преобразовать наборы символов в выражениях во многих случаях, когда MySQL в противном случае вернёт ошибку «“незаконная смесь наборов кодирования”», когда правила принудительной применимости наборов кодирования недостаточно, чтобы разрешить неоднозначности. (Для получения информации о принудительной применимости см. Раздел 12.8.4, «Принудительная применимость наборов кодирования в выражениях».)
Следующее обсуждение предоставляет примеры выражений и их repertoires и описывает, как использование repertoires изменяет оценку строковых выражений:
-
Набор символов для строковой константы зависит от содержимого строки и может отличаться от набора символов строки. Рассмотрим следующие операторы:
SET NAMES utf8mb4; SELECT 'abc'; SELECT _utf8mb4'def';
Хотя набор символов является
utf8mb4в каждом из предыдущих случаев, строки фактически не содержат никаких символов за пределами диапазона ASCII, поэтому их repertoires являетсяASCII, а неUNICODE. -
Столбец с набором символов
asciiимеет набор символовASCIIиз-за его набора символов. В следующей таблицеc1имеет набор символовASCII:CREATE TABLE t1 (c1 CHAR(1) CHARACTER SET ascii);
Следующий пример иллюстрирует, как repertoires позволяет определить результат в случае, когда без repertoires возникает ошибка:
CREATE TABLE t1 ( c1 CHAR(1) CHARACTER SET latin1, c2 CHAR(1) CHARACTER SET ascii ); INSERT INTO t1 VALUES ('a','b'); SELECT CONCAT(c1,c2) FROM t1;Без repertoires возникает эта ошибка:
ERROR 1267 (HY000): Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (ascii_general_ci,IMPLICIT) for operation 'concat'
С использованием repertoires, преобразование подмножества в надмножество (
asciiвlatin1) может произойти, и результат возвращается:+---------------+ | CONCAT(c1,c2) | +---------------+ | ab | +---------------+
Функции с одним строковым аргументом наследуют repertoires своего аргумента. Результат
UPPER(_utf8mb4'abc')имеет набор символовASCII, потому что его аргумент имеет набор символовASCII. (Несмотря на_utf8mb4ввод, строка'abc'не содержит символов за пределами диапазона ASCII.)-
Для функций, возвращающих строку, но не имеющих строковых аргументов и использующих
character_set_connectionв качестве набора символов результата, результат repertoires являетсяASCII, еслиcharacter_set_connectionявляетсяascii, иUNICODEв противном случае:FORMAT(
numeric_column, 4);Использование repertoires изменяет способ, которым MySQL оценивает следующий пример:
SET NAMES ascii; CREATE TABLE t1 (a INT, b VARCHAR(10) CHARACTER SET latin1); INSERT INTO t1 VALUES (1,'b'); SELECT CONCAT(FORMAT(a, 4), b) FROM t1;
Без repertoires возникает эта ошибка:
ERROR 1267 (HY000): Illegal mix of collations (ascii_general_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation 'concat'
С использованием repertoires возвращается результат:
+-------------------------+ | CONCAT(FORMAT(a, 4), b) | +-------------------------+ | 1.0000b | +-------------------------+
-
Функции с двумя или более строковыми аргументами используют repertoires аргумента “шире” для repertoires результата, где
UNICODEшире, чемASCII. Рассмотрим следующие вызовыCONCAT():CONCAT(_ucs2 X'0041', _ucs2 X'0042') CONCAT(_ucs2 X'0041', _ucs2 X'00C2')
Для первого вызова набор символов является
ASCII, так как оба аргумента находятся в диапазоне ASCII. Для второго вызова набор символов являетсяUNICODE, так как второй аргумент находится за пределами диапазона ASCII. -
Набор символов для значений возвращаемых функциями определяется на основе repertoires только тех аргументов, которые влияют на набор символов и наборы кодирования результата.
IF(column1 < column2, 'smaller', 'greater')
Набор символов результата является
ASCII, так как два строковых аргумента (второй аргумент и третий аргумент) оба имеют набор символовASCII. Первый аргумент не имеет значения для repertoires результата, даже если выражение использует строковые значения.
© 2025 Oracle
Licensed under the GPLv2 License.