MySQL: руководство профессионала [Алексей В Паутов] (fb2) читать постранично, страница - 4


 [Настройки текста]  [Cбросить фильтры]

+--------------+---------------+

| 2 | -2 |

+--------------+---------------+


Пример 4. В строгом режиме вставка значения, которое является слишком большим, приводит к переполнению и ошибке, а не к усечению до допустимого значения. Когда MySQL не выполняется в строгом режиме, происходит усечение к допустимому значению:


mysql> SET sql_mode='';

Query OK, 0 rows affected (0.00 sec)


mysql> CREATE TABLE t (i TINYINT);

Query OK, 0 rows affected (0.01 sec)


mysql> INSERT INTO t SET i = 128;

Query OK, 1 row affected, 1 warning (0.00 sec)


mysql> SELECT i FROM t;

+------+

| i |

+------+

| 127 |

+------+

1 row in set (0.00 sec)


Однако, условие переполнения происходит, если включен строгий режим:


mysql> SET sql_mode='STRICT_ALL_TABLES';

Query OK, 0 rows affected (0.00 sec)


mysql> CREATE TABLE t (i TINYINT);

Query OK, 0 rows affected (0.00 sec)


mysql> INSERT INTO t SET i = 128;

ERROR 1264 (22003): Out of range value adjusted for column 'i' at row 1


mysql> SELECT i FROM t;

Empty set (0.00 sec)


Пример 5: В строгом режиме и с настройкой ERROR_FOR_DIVISION_BY_ZERO деление на нуль вызывает ошибку, а не результат NULL.

В нестрогом режиме деление на нуль имеет результат NULL:


mysql> SET sql_mode='';

Query OK, 0 rows affected (0.01 sec)


mysql> CREATE TABLE t (i TINYINT);

Query OK, 0 rows affected (0.00 sec)


mysql> INSERT INTO t SET i = 1 / 0;

Query OK, 1 row affected (0.00 sec)


mysql> SELECT i FROM t;

+------+

| i |

+------+

| NULL |

+------+

1 row in set (0.03 sec)


Однако, деление на нуль выдает ошибку, если соответствующие SQL-режимы активны:


mysql> SET sql_mode='STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO';

Query OK, 0 rows affected (0.00 sec)


mysql> CREATE TABLE t (i TINYINT);

Query OK, 0 rows affected (0.00 sec)


mysql> INSERT INTO t SET i = 1 / 0;

ERROR 1365 (22012): Division by 0


mysql> SELECT i FROM t;

Empty set (0.01 sec)


Пример 6. До MySQL 5.0.3 литералы с точным значением и с приблизительным значением преобразованы в значения с плавающей запятой двойной точности:


mysql> SELECT VERSION();

+------------+

| VERSION() |

+------------+

| 4.1.18-log |

+------------+

1 row in set (0.01 sec)


mysql> CREATE TABLE t SELECT 2.5 AS a, 25E-1 AS b;

Query OK, 1 row affected (0.07 sec)

Records: 1 Duplicates: 0 Warnings: 0


mysql> DESCRIBE t;

+-------+-------------+------+-----+---------+-------+

| Field | Type | Null | Key | Default | Extra |

+-------+-------------+------+-----+---------+-------+

| a | double(3,1) | | | 0.0 | |

| b | double | | | 0 | |

+-------+-------------+------+-----+---------+-------+

2 rows in set (0.04 sec)


Начиная с MySQL 5.0.3, литерал с приблизительным значением все еще преобразован в значение с плавающей запятой, но литерал с точным значением обработан как DECIMAL:


mysql> SELECT VERSION();

+-----------------+

| VERSION() |

+-----------------+

| 5.1.6-alpha-log |

+-----------------+

1 row in set (0.11 sec)


mysql> CREATE TABLE t SELECT 2.5 AS a, 25E-1 AS b;

Query OK, 1 row affected (0.01 sec)

Records: 1 Duplicates: 0 Warnings: 0


mysql> DESCRIBE t;

+-------+-----------------------+------+-----+---------+-------+

| Field | Type | Null | Key | Default | Extra |

+-------+-----------------------+------+-----+---------+-------+

| a | decimal(2,1) unsigned | NO | | 0.0 | |

| b | double | NO | | 0 | |

+-------+-----------------------+------+-----+---------+-------+

2 rows in set (0.01 sec)


Пример 7. Если параметр функции точный числовой тип, результат также точный числовой тип, с масштабом по крайней мере, как у параметра. Рассмотрите эти инструкции:


mysql> CREATE TABLE t (i INT, d DECIMAL, f FLOAT);

mysql> INSERT INTO t VALUES(1,1,1);

mysql> CREATE TABLE y SELECT AVG(i), AVG(d), AVG(f) FROM t;


Результаты до MySQL 5.0.3:


mysql> DESCRIBE y;

+--------+--------------+------+-----+---------+-------+

| Field | Type | Null | Key | Default | Extra |

+--------+--------------+------+-----+---------+-------+

| AVG(i) | double(17,4) | YES | | NULL | |

| AVG(d) | double(17,4) | YES | | NULL | |

| AVG(f) | double | YES | | NULL | |

+--------+--------------+------+-----+---------+-------+


Результат двойной точности, независимо от типа параметра. А вот результаты в MySQL 5.0.3 и выше:

mysql> DESCRIBE y;

+--------+---------------+------+-----+---------+-------+

| Field | Type | Null | Key | Default | Extra |

+--------+---------------+------+-----+---------+-------+

| AVG(i) | decimal(14,4) | YES | | NULL | |

| AVG(d) | decimal(14,4) | YES | | NULL | |

| AVG(f) | double | YES | | NULL | |

+--------+---------------+------+-----+---------+-------+


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

Глава 2. Типы памяти и таблиц

MySQL поддерживает несколько типов памяти, которые действуют как драйверы для различных типов таблицы.

С MySQL 5.1 MySQL AB представил новую подключаемую архитектуру памяти, которая позволяет типам памяти загружаться и выгружаться по мере надобности. Если раньше приходилось перекомпилировать сервер, чтобы встроить поддержку соответствующего типа таблиц, теперь это не требуется.

Эта глава описывает каждый из типов памяти MySQL, кроме NDB Cluster. Это также содержит описание новой архитектуры хранения.

2.1. Краткий обзор архитектуры хранения данных в MySQL

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