Spec-Zone.ru › MySQL 5.7

12.15 Функции информации

Таблица 12.20 Функции информации

Таблица 12.20 Функции информации
Имя Описание
BENCHMARK() Повторять выполнение выражения
CHARSET() Возвращает кодовую таблицу аргумента
COERCIBILITY() Возвращает значение принудительности сортировки для строкового аргумента
COLLATION() Возвращает сортировку строкового аргумента
CONNECTION_ID() Возвращает идентификатор соединения (идентификатор потока) для соединения
CURRENT_USER(), CURRENT_USER Имя и имя хоста аутентифицированного пользователя
DATABASE() Возвращает имя базы данных по умолчанию (текущей)
FOUND_ROWS() Для SELECT с клаузой LIMIT, число строк, которое было бы возвращено без клаузы LIMIT
LAST_INSERT_ID() Значение столбца AUTOINCREMENT для последнего INSERT
ROW_COUNT() Количество обновленных строк
SCHEMA() Синоним для DATABASE()
SESSION_USER() Синоним для USER()
SYSTEM_USER() Синоним для USER()
USER() Имя пользователя и имя хоста, предоставленные клиентом
VERSION() Возвращает строку, указывающую версию сервера MySQL

  • BENCHMARK(count,expr)

    Функция BENCHMARK() выполняет выражение expr многократно count раз. Ее можно использовать для измерения скорости обработки выражения MySQL. Результатное значение равно 0, или NULL для неподходящих аргументов, таких как NULL или отрицательный счёт повторений.

    Предполагается использование из клиента mysql, который сообщает о времени выполнения запросов:

    mysql> SELECT BENCHMARK(1000000,AES_ENCRYPT('hello','goodbye'));
    +---------------------------------------------------+
    | BENCHMARK(1000000,AES_ENCRYPT('hello','goodbye')) |
    +---------------------------------------------------+
    |                                                 0 |
    +---------------------------------------------------+
    1 row in set (4.74 sec)
    

    Сообщаемое время - это время, затраченное на клиентской стороне, а не процессорное время на серверной стороне. Рекомендуется выполнять BENCHMARK() несколько раз и интерпретировать результат с учетом степени загрузки машины сервера.

    BENCHMARK() предназначена для измерения времени выполнения скалярных выражений, что имеет значительные последствия для использования и интерпретации результатов:

    • Можно использовать только скалярные выражения. Хотя выражение может быть подзапросом, оно должно возвращать один столбец и не более одной строки. Например, BENCHMARK(10, (SELECT * FROM t)) завершается неудачно, если таблица t имеет более одного столбца или более одной строки.

    • Выполнение оператора SELECT expr N раз отличается от выполнения SELECT BENCHMARK(N, expr) с точки зрения задействованной накладной работы. У них очень разные профили выполнения, и не следует ожидать, что они займут одинаковое время. Первый включает в себя парсер, оптимизатор, блокировку таблиц и оценку выполнения N раз каждый. Последний включает только оценку выполнения N раз, а все остальные компоненты только один раз. Уже выделенные структуры памяти повторно используются, а такие оптимизации выполнения, как локальное кэширование уже оцененных результатов для агрегатных функций, могут изменить результаты. Таким образом, использование BENCHMARK() измеряет производительность компонента выполнения, придавая ему больший вес и удаляя “шум”, вносимый сетью, парсером, оптимизатором и т. д.

  • CHARSET(str)

    Возвращает кодовую таблицу строкового аргумента.

    mysql> SELECT CHARSET('abc');
            -> 'latin1'
    mysql> SELECT CHARSET(CONVERT('abc' USING utf8));
            -> 'utf8'
    mysql> SELECT CHARSET(USER());
            -> 'utf8'
    
  • COERCIBILITY(str)

    Возвращает значение принудительности сортировки для строкового аргумента.

    mysql> SELECT COERCIBILITY('abc' COLLATE latin1_swedish_ci);
            -> 0
    mysql> SELECT COERCIBILITY(USER());
            -> 3
    mysql> SELECT COERCIBILITY('abc');
            -> 4
    mysql> SELECT COERCIBILITY(1000);
            -> 5
    

    Значения возврата имеют указанные в следующей таблице значения. Более низкие значения имеют более высокий приоритет.

    Принудительность Значение Пример
    0 Явная сортировка Значение с клаузой COLLATE
    1 Отсутствие сортировки Конкатенация строк с разными сортировками
    2 Неявная сортировка Значение столбца, параметр хранимой процедуры или локальная переменная
    3 Система констант Значение возврата USER()
    4 Принудительно Литеральная строка
    5 Числовой Числовое или временное значение
    6 Игнорируемый NULL или выражение, полученное от NULL

    Дополнительную информацию см. в разделе 10.8.4 «Принудительность сортировки в выражениях».

  • COLLATION(str)

    Возвращает сортировку строкового аргумента.

    mysql> SELECT COLLATION('abc');
            -> 'latin1_swedish_ci'
    mysql> SELECT COLLATION(_utf8'abc');
            -> 'utf8_general_ci'
    
  • CONNECTION_ID()

    Возвращает идентификатор соединения (идентификатор потока) для соединения. Каждое соединение имеет уникальный среди подключенных клиентов идентификатор.

    Значение, возвращаемое CONNECTION_ID(), имеет тот же тип, что и в столбце ID таблицы схемы информации PROCESSLIST, столбце Id вывода SHOW PROCESSLIST и столбце PROCESSLIST_ID таблицы схемы производительности threads.

    mysql> SELECT CONNECTION_ID();
            -> 23786
    
    Предупреждение

    Изменение значения сессии переменной системы pseudo_thread_id меняет значение, возвращаемое функцией CONNECTION_ID().

  • CURRENT_USER, CURRENT_USER()

    Возвращает сочетание имени пользователя и имени хоста для MySQL-аккаунта, который сервер использовал для аутентификации текущего клиента. Этот аккаунт определяет ваши привилегии доступа. Возвращаемое значение — строка в наборе символов utf8.

    Значение CURRENT_USER() может отличаться от значения USER().

    mysql> SELECT USER();
            -> 'davida@localhost'
    mysql> SELECT * FROM mysql.user;
    ERROR 1044: Access denied for user ''@'localhost' to
    database 'mysql'
    mysql> SELECT CURRENT_USER();
            -> '@localhost'
    

    Пример иллюстрирует, что хотя клиент указал имя пользователя davida (как указано значением функции USER()), сервер аутентифицировал клиента с использованием анонимного пользовательского аккаунта (как видно из пустой части имени пользователя в значении CURRENT_USER()). Одна из возможных причин — отсутствие записи в таблицах предоставления прав для davida.

    Внутри хранимой программы или представления CURRENT_USER() возвращает аккаунт пользователя, который определил объект (как указано его значением DEFINER), если не определено свойство SQL SECURITY INVOKER. В последнем случае CURRENT_USER() возвращает вызывающего объект.

    У триггеров и событий нет возможности определить свойство SQL SECURITY, поэтому для этих объектов CURRENT_USER() возвращает аккаунт пользователя, который определил объект. Для возвращения вызывающего используйте USER() или SESSION_USER().

    Следующие инструкции поддерживают использование функции CURRENT_USER() для замещения имени (и, возможно, хоста) затронутого пользователя или определяющего; в таких случаях CURRENT_USER() расширяется по мере необходимости:

    • DROP USER

    • RENAME USER

    • GRANT

    • REVOKE

    • CREATE FUNCTION

    • CREATE PROCEDURE

    • CREATE TRIGGER

    • CREATE EVENT

    • CREATE VIEW

    • ALTER EVENT

    • ALTER VIEW

    • SET PASSWORD

    Для получения информации о последствиях этого расширения функции CURRENT_USER() для репликации см. Раздел 16.4.1.8, «Репликация CURRENT_USER()».

  • DATABASE()

    Возвращает имя базы данных по умолчанию (текущей) в виде строки в наборе символов utf8. Если базы данных по умолчанию нет, DATABASE() возвращает NULL. Внутри хранимой процедуры база данных по умолчанию — база данных, к которой процедура относится, которая необязательно совпадает с базой данных по умолчанию в контексте вызова.

    mysql> SELECT DATABASE();
            -> 'test'
    

    Если база данных по умолчанию отсутствует, DATABASE() возвращает NULL.

  • FOUND_ROWS()

    Выражение SELECT может включать в себя предложение LIMIT, чтобы ограничить количество строк, возвращаемых сервером клиенту. В некоторых случаях желательно узнать, сколько строк вернуло бы выражение без LIMIT, но без повторного выполнения этого выражения. Чтобы получить это количество строк, включите опцию SQL_CALC_FOUND_ROWS в выражение SELECT, а затем вызовите FOUND_ROWS() после этого:

    mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
        -> WHERE id > 100 LIMIT 10;
    mysql> SELECT FOUND_ROWS();
    

    Второе SELECT возвращает число, указывающее, сколько строк вернуло бы первое SELECT, если бы оно было написано без предложения LIMIT.

    В отсутствие опции SQL_CALC_FOUND_ROWS в последнем успешно выполненном SELECT выражении, FOUND_ROWS() возвращает количество строк в наборе результатов, возвращенном этим выражением. Если выражение включает предложение LIMIT, FOUND_ROWS() возвращает количество строк до лимита. Например, FOUND_ROWS() возвращает 10 или 60 соответственно, если выражение включает LIMIT 10 или LIMIT 50, 10.

    Количество строк, доступное через FOUND_ROWS(), является временным и не предназначено для использования после выражения, следующего за SELECT SQL_CALC_FOUND_ROWS выражением. Если вам нужно обратиться к значению позже, сохраните его:

    mysql> SELECT SQL_CALC_FOUND_ROWS * FROM ... ;
    mysql> SET @rows = FOUND_ROWS();
    

    Если вы используете SELECT SQL_CALC_FOUND_ROWS, MySQL должен вычислить, сколько строк содержится в полном наборе результатов. Однако это быстрее, чем повторное выполнение запроса без LIMIT, потому что набор результатов не нужно отправлять клиенту.

    SQL_CALC_FOUND_ROWS и FOUND_ROWS() могут быть полезны в ситуациях, когда вы хотите ограничить количество строк, возвращаемых запросом, но также определить количество строк в полном наборе результатов без повторного выполнения запроса. Примером является веб-скрипт, отображающий постраничный вывод с ссылками на страницы, которые показывают другие разделы результата поиска. Использование FOUND_ROWS() позволяет определить, сколько дополнительных страниц требуется для остальной части результата.

    Использование SQL_CALC_FOUND_ROWS и FOUND_ROWS() сложнее для выражений UNION, чем для простых выражений SELECT, потому что LIMIT может встречаться в нескольких местах в выражении UNION. Оно может применяться к отдельным SELECT выражениям в UNION или глобально для всего результата UNION.

    Цель SQL_CALC_FOUND_ROWS для UNION заключается в том, чтобы оно возвращало количество строк, которое было бы возвращено без глобального LIMIT. Условия использования SQL_CALC_FOUND_ROWS с UNION следующие:

    • Ключевое слово SQL_CALC_FOUND_ROWS должно появляться в первом SELECT выражении в UNION.

    • Значение FOUND_ROWS() является точным только если используется UNION ALL. Если используется UNION без ALL, происходит удаление дубликатов, и значение FOUND_ROWS() является только приблизительным.

    • Если в UNION отсутствует LIMIT, SQL_CALC_FOUND_ROWS игнорируется и возвращает количество строк во временной таблице, которая создается для обработки UNION.

    Вне описанных случаев поведение FOUND_ROWS() не определено (например, его значение после SELECT выражения, завершившегося ошибкой).

    Важно

    FOUND_ROWS() не реплицируется надежно с помощью репликации на основе выражений. Эта функция автоматически реплицируется с помощью репликации на основе строк.

  • LAST_INSERT_ID(), LAST_INSERT_ID(expr)

    Без аргумента, LAST_INSERT_ID() возвращает значение типа BIGINT UNSIGNED (64-битное) , представляющее первое автоматически сгенерированное значение, успешно вставленное в столбец AUTO_INCREMENT в результате последнего выполненного оператора INSERT. Значение LAST_INSERT_ID() остается неизменным, если не было успешно вставлено ни одной строки.

    С аргументом, LAST_INSERT_ID() возвращает целое беззнаковое число.

    Например, после вставки строки, которая генерирует значение AUTO_INCREMENT, вы можете получить это значение следующим образом:

    mysql> SELECT LAST_INSERT_ID();
            -> 195
    

    Текущий выполняемый оператор не влияет на значение LAST_INSERT_ID(). Предположим, что вы генерируете значение AUTO_INCREMENT с помощью одного оператора, а затем ссылаетесь на LAST_INSERT_ID() в операторе INSERT с несколькими строками, который вставляет строки в таблицу со своим столбцом AUTO_INCREMENT. Значение LAST_INSERT_ID() остается стабильным во втором операторе; его значение для второй и последующих строк не зависит от предыдущих вставок строк. (Однако, если вы смешиваете ссылки на LAST_INSERT_ID() и LAST_INSERT_ID(expr), результат неопределен.)

    Если предыдущий оператор вернул ошибку, значение LAST_INSERT_ID() является неопределенным. Для транзакционных таблиц, если оператор отменен из-за ошибки, значение LAST_INSERT_ID() остается неопределенным. Для ручных ROLLBACK, значение LAST_INSERT_ID() не восстанавливается до значения до начала транзакции; оно остается таким, каким было в момент ROLLBACK.

    Внутри тела хранимой процедуры (процедуры или функции) или триггера значение LAST_INSERT_ID() меняется так же, как и для операторов, выполняемых вне тела таких объектов. Влияние хранимой процедуры или триггера на значение LAST_INSERT_ID(), видимое последующими операторами, зависит от типа процедуры:

    • Если хранимая процедура выполняет операторы, которые изменяют значение LAST_INSERT_ID(), измененное значение видно операторами, которые следуют за вызовом процедуры.

    • Для хранимых функций и триггеров, которые изменяют значение, оно восстанавливается при завершении функции или триггера, поэтому последующие операторы не видят измененного значения.

    Сгенерированный идентификатор сохраняется на сервере на уровне соединения. Это означает, что значение, возвращаемое функцией данному клиенту, является первым сгенерированным значением AUTO_INCREMENT для последнего оператора, влияющего на столбец AUTO_INCREMENT этим клиентом. Это значение не может быть изменено другими клиентами, даже если они генерируют значения AUTO_INCREMENT. Это поведение гарантирует, что каждый клиент может получить свой собственный идентификатор, не беспокоясь о деятельности других клиентов, и без необходимости блокировок или транзакций.

    Значение LAST_INSERT_ID() не изменяется, если вы установите для столбца AUTO_INCREMENT строки значение, отличное от “магического” (то есть, значение, которое не является NULL и не является 0).

    Важно

    Если вы вставляете несколько строк с помощью одного оператора INSERT, LAST_INSERT_ID() возвращает значение, сгенерированное только для первой вставленной строки. Причина в том, что это позволяет легко воспроизвести тот же оператор INSERT на другом сервере.

    Например:

    mysql> USE test;
    
    mysql> CREATE TABLE t (
           id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
           name VARCHAR(10) NOT NULL
           );
    
    mysql> INSERT INTO t VALUES (NULL, 'Bob');
    
    mysql> SELECT * FROM t;
    +----+------+
    | id | name |
    +----+------+
    |  1 | Bob  |
    +----+------+
    
    mysql> SELECT LAST_INSERT_ID();
    +------------------+
    | LAST_INSERT_ID() |
    +------------------+
    |                1 |
    +------------------+
    
    mysql> INSERT INTO t VALUES
           (NULL, 'Mary'), (NULL, 'Jane'), (NULL, 'Lisa');
    
    mysql> SELECT * FROM t;
    +----+------+
    | id | name |
    +----+------+
    |  1 | Bob  |
    |  2 | Mary |
    |  3 | Jane |
    |  4 | Lisa |
    +----+------+
    
    mysql> SELECT LAST_INSERT_ID();
    +------------------+
    | LAST_INSERT_ID() |
    +------------------+
    |                2 |
    +------------------+
    

    Хотя второй оператор INSERT вставил три новые строки в t, сгенерированный идентификатор для первой из этих строк был 2, и именно это значение возвращается функцией LAST_INSERT_ID() для следующего оператора SELECT.

    Если вы используете INSERT IGNORE и строка проигнорирована, значение LAST_INSERT_ID() остается неизменным от текущего значения (или возвращается 0, если соединение еще не выполнило успешную операцию INSERT) и для не транзакционных таблиц счетчик AUTO_INCREMENT не инкрементируется. Для InnoDB таблиц, счетчик AUTO_INCREMENT инкрементируется, если innodb_autoinc_lock_mode установлено на 1 или 2, как показано в следующем примере:

    mysql> USE test;
    
    mysql> SELECT @@innodb_autoinc_lock_mode;
    +----------------------------+
    | @@innodb_autoinc_lock_mode |
    +----------------------------+
    |                          1 |
    +----------------------------+
    
    mysql> CREATE TABLE `t` (
           `id` INT(11) NOT NULL AUTO_INCREMENT,
           `val` INT(11) DEFAULT NULL,
           PRIMARY KEY (`id`),
           UNIQUE KEY `i1` (`val`)
           ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    
    # Insert two rows
    
    mysql> INSERT INTO t (val) VALUES (1),(2);
    
    # With auto_increment_offset=1, the inserted rows
    # result in an AUTO_INCREMENT value of 3
    
    mysql> SHOW CREATE TABLE t\G
    *************************** 1. row ***************************
           Table: t
    Create Table: CREATE TABLE `t` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `val` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `i1` (`val`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
    
    # LAST_INSERT_ID() returns the first automatically generated
    # value that is successfully inserted for the AUTO_INCREMENT column
    
    mysql> SELECT LAST_INSERT_ID();
    +------------------+
    | LAST_INSERT_ID() |
    +------------------+
    |                1 |
    +------------------+
    
    # The attempted insertion of duplicate rows fail but errors are ignored
    
    mysql> INSERT IGNORE INTO t (val) VALUES (1),(2);
    Query OK, 0 rows affected (0.00 sec)
    Records: 2  Duplicates: 2  Warnings: 0
    
    # With innodb_autoinc_lock_mode=1, the AUTO_INCREMENT counter
    # is incremented for the ignored rows
    
    mysql> SHOW CREATE TABLE t\G
    *************************** 1. row ***************************
           Table: t
    Create Table: CREATE TABLE `t` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `val` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `i1` (`val`)
    ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
    
    # The LAST_INSERT_ID is unchanged because the previous insert was unsuccessful
    
    mysql> SELECT LAST_INSERT_ID();
    +------------------+
    | LAST_INSERT_ID() |
    +------------------+
    |                1 |
    +------------------+
    

    Дополнительную информацию см. в Разделе 14.6.1.6, «Обработка AUTO_INCREMENT в InnoDB».

    Если expr передаётся в качестве аргумента функции LAST_INSERT_ID(), функция возвращает значение аргумента и запоминает его как следующее значение, которое будет возвращено функцией LAST_INSERT_ID(). Это можно использовать для имитации последовательностей:

    1. Создайте таблицу для хранения счётчика последовательности и инициализируйте её:

      mysql> CREATE TABLE sequence (id INT NOT NULL);
      mysql> INSERT INTO sequence VALUES (0);
      
    2. Используйте таблицу для генерации номеров последовательности так:

      mysql> UPDATE sequence SET id=LAST_INSERT_ID(id+1);
      mysql> SELECT LAST_INSERT_ID();
      

      Оператор UPDATE инкрементирует счётчик последовательности и приводит к тому, что следующий вызов функции LAST_INSERT_ID() возвращает обновлённое значение. Оператор SELECT извлекает это значение. Функцию C API также можно использовать для получения значения. Смотрите .

    Вы можете генерировать последовательности без вызова LAST_INSERT_ID(), но использование функции таким образом удобно, потому что значение ID сохраняется на сервере как последнее сгенерированное автоматически значение. Она безопасна в многопользовательской среде, потому что несколько клиентов могут выполнить оператор UPDATE и получить свои значения последовательности с помощью оператора SELECT (или ), не влияя и не будучи затронутыми другими клиентами, которые генерируют свои собственные значения последовательности.

    Обратите внимание, что обновляется только после операторов INSERT и UPDATE, поэтому вы не можете использовать функцию C API для получения значения для LAST_INSERT_ID(expr) после выполнения других SQL-операторов, таких как SELECT или SET.

  • ROW_COUNT()

    ROW_COUNT() возвращает значение следующим образом:

    • Утверждения DDL: 0. Это относится к утверждениям, таким как CREATE TABLE или DROP TABLE.

    • Утверждения DML, отличные от SELECT: Количество затронутых строк. Это относится к утверждениям, таким как UPDATE, INSERT или DELETE (как и прежде), но теперь также к утверждениям, таким как ALTER TABLE и LOAD DATA.

    • SELECT: -1, если утверждение возвращает набор результатов, или количество строк “затронутых”, если нет. Например, для SELECT * FROM t1, ROW_COUNT() возвращает -1. Для SELECT * FROM t1 INTO OUTFILE 'file_name', ROW_COUNT() возвращает количество строк, записанных в файл.

    • Утверждения SIGNAL: 0.

    Для утверждений UPDATE значение затронутых строк по умолчанию равно количеству фактически изменённых строк. Если вы укажете флаг CLIENT_FOUND_ROWS при подключении к mysqld, значение затронутых строк будет равно количеству строк “найденных”; то есть, соответствующих условию WHERE.

    Для утверждений REPLACE значение затронутых строк равно 2, если новая строка заменила старую строку, потому что в этом случае одна строка была вставлена после удаления дубликата.

    Для утверждений INSERT ... ON DUPLICATE KEY UPDATE значение затронутых строк на строку равно 1, если строка вставляется как новая строка, 2, если существующая строка обновляется, и 0, если существующая строка устанавливается в свои текущие значения. Если вы укажете флаг CLIENT_FOUND_ROWS, значение затронутых строк равно 1 (а не 0), если существующая строка устанавливается в свои текущие значения.

    Значение ROW_COUNT() аналогично значению из функции C API и количеству строк, которое отображает клиент mysql после выполнения утверждения.

    mysql> INSERT INTO t VALUES(1),(2),(3);
    Query OK, 3 rows affected (0.00 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    mysql> SELECT ROW_COUNT();
    +-------------+
    | ROW_COUNT() |
    +-------------+
    |           3 |
    +-------------+
    1 row in set (0.00 sec)
    
    mysql> DELETE FROM t WHERE i IN(1,2);
    Query OK, 2 rows affected (0.00 sec)
    
    mysql> SELECT ROW_COUNT();
    +-------------+
    | ROW_COUNT() |
    +-------------+
    |           2 |
    +-------------+
    1 row in set (0.00 sec)
    
    Важно

    ROW_COUNT() не дублируется надёжно с помощью репликации на основе утверждений. Эта функция автоматически дублируется с помощью репликации на основе строк.

  • SCHEMA()

    Эта функция является синонимом для DATABASE().

  • SESSION_USER()

    SESSION_USER() является синонимом для USER().

  • SYSTEM_USER()

    SYSTEM_USER() является синонимом для USER().

  • USER()

    Возвращает текущее имя пользователя MySQL и имя хоста в виде строки в кодировке utf8.

    mysql> SELECT USER();
            -> 'davida@localhost'
    

    Значение указывает имя пользователя, которое вы указали при подключении к серверу, и хост клиента, с которого вы подключились. Это значение может отличаться от значения CURRENT_USER().

  • VERSION()

    Возвращает строку, которая указывает версию сервера MySQL. Строка использует кодировку utf8. Значение может иметь суффикс в дополнение к номеру версии. См. описание системной переменной version в Разделе 5.1.7, «Системные переменные сервера».

    Эта функция небезопасна для репликации на основе утверждений. Выводится предупреждение, если вы используете эту функцию, когда binlog_format установлено в STATEMENT.

    mysql> SELECT VERSION();
            -> '5.7.44-standard'
    

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-5.7-en/information-functions.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API