Типы и структура таблиц в MySQL
База данных MySQL поддерживает несколько разных видов таблиц, все они имеют свои особенные возможности и ограничения.
Начну своё описание с «родного» для баз данных MySQL типа таблиц MyISAM. Если в операторе create table не задать тип таблицы то будет назначен именно этот тип.
Каждая MyISAM таблица хранится на диске в трёх файлах (в поддиректории каталога mysql/data), имена этих файлов совпадают с названием таблицы, а расширение может принимать одно из следующих значений:
.frm — структура таблицы, этот файл содержит информацию об именах и типах столбцов и индексов;
.MYD — в этом файле содержатся данные таблицы;
.MYI — в этом файле содержатся индексы таблицы.
Таблицы MyISAM обладают рядом особенностей:
1. Данные хранятся в кроссплатформенном формате, что позволяет переносить базы с сервера непосредственным копированием файлов, минуя промежуточные формы.
2. Максимальное количество индексов — 64 (с версии 4.1.2). Каждый индекс может быть максимум из 16 столбцов.
3. С версии MySQL 4.1, для каждого текстового столбца может быть задана своя кодировка.
4. Допускается индексирование текстовых столбцов, в том числе и переменной длины.
5. Поддерживается полнотекстовый поиск.
6. Таблицы имеют специальный флаг, указывающий на правильность закрытия таблицы. Если сервер был остановлен аварийно, то при загрузке незакрытые флаги будут сигнализировать о возможных поврежденных таблицах и сервер попытается автоматически их проверить и восстановить.
Создание MyISAM таблицы с явным указанием типа:
create table teble1 (i INT) ENGINE = MyISAM;
//Или
create table teble1 (i INT) TYPE = MyISAM;
Использование ключевого слова ENGINE является предпочтительным, однако возможно только с версии MySQL 4.0.18.
MERGE
В MySQL существует тип таблиц MERGE, он позволяет объединять несколько таблиц типа MyISAM в одну. Этот тип в основном применяется для снятия ограничения на объём для таблиц MyISAM, в том случае если операционная или файловая система не позволяют создавать файлы более определённого размера (например 4gb для FAT32 и т.п.). Таблицы MyISAM объединяемые в одну таблицу MERGE, должны иметь идентичную структуру, т.е. одинаковые столбцы, индексы и порядок их следования.
Для созданной таблицы типа MERGE появятся файлы структуры таблицы с расширением .rfm и файлы с расширением .MRG. Файлы .MRG содержат список индексных файлов, работа с которыми должна вестись как с единым файлом.
К объединенной таблице можно применять команды SELECT, DELETE и UPDATE. Если попытаться удалить таблицу MERGE при помощи команды DROP TABLE, то будет уничтожена именно MERGE таблица, исходные таблицы MyISAM не будут затронуты.
Пример создания таблицы MERGE:
create table table_one (
id int not null auto_increment primary key,
name char(20));
create table table_two (
id int not null auto_increment primary key,
name char(20));
insert into table_one (name) values ('11'), ('22'), ('33');
insert into table_two (name) values ('aa'), ('bb'), ('cc');
create table summ_table (
id int not null auto_increment,
name char(20), index(id))
engine=merge union=(table_one,table_two) insert_method=last;
Результат выборки из таблицы summ_table выглядит так:
select * from summ_table;
ID | NAME
1 | 11
2 | 22
3 | 33
1 | aa
2 | bb
3 | cc
В объединённой таблице summ_table поле id уже не является уникальным!
(Таблицы MERGE не могут содержать уникальных ключей.)
Из примера видно, что при помощи параметра UNION задаются таблицы для объединения, а при помощи параметра INSERT_METHOD можно задать параметр добавления записей в MyISAM таблицы (в качестве значения в этом случае передаётся одна из трёх констант).
FIRST — При вставке новой записи в таблицу MERGE, запись размещается в первой таблице из списка в параметре UNION.
LAST — Запись размещается в последней таблице списка.
NO — Данное значение по сути идентично отсутствию параметра, и означает что вставка в MERGE таблицу невозможна, а использования оператора INSERT приведёт к ошибке.
MEMORY (HEAP)
Следующий тип таблиц MEMORY (HEAP) хранится в оперативной памяти, из-за чего все запросы к таким таблицам выполняются очень быстро. Недостаток у таких таблиц один — полная потеря данных в случае сбоя работы сервера. В связи с этим в таких таблицах хранят в основном временные данные, которые можно легко восстановить заново.
HEAP является синонимом MEMORY. Однако предпочтительнее использовать MEMORY — который является более поздним.
При создании таблицы типа MEMORY, создаётся один файл с расширением frm, в котором определяется структура таблицы. При остановке или перезагрузке сервера, данные о структуре таблицы остаются, но вся информация содержащаяся в этой таблице теряется, поскольку хранится только в оперативной памяти. При каждой перезагрузке сервера, пересоздавать таблицу не нужно, её структура остаётся.
Таблицы типа MEMORY имеют ряд ограничений:
1. Индексы используются только в операциях сравнения с операторами "=" и "<=>", с другими операторами, такими как ">" или "<", индексирование столбцов не имеет смысла.
2. Как и с MERGE таблицами возможно использование только неуникальных индексов.
3. Не допустимы столбцы типов TEXT и BLOB.
4. До версии MySQL 4.1 в таблицах данного типа не поддерживаляс AUTO_INCREMENT.
Пример создания таблиц типа MEMORY:
create table tbl1 (field1 INT) ENGINE=MEMORY;
//или
create table tbl1 (field1 INT) ENGINE=HEAP;
EXAMPLE
Тип EXAMPLE является заглушкой, создать таблицу такого типа можно а вот получить или передать данные нельзя. При создании таблиц такого типа, как и с таблицами MEMORY создаётся только один файл frm, в нём определяется структура таблицы.
Тип EXAMPLE был введён для удобства и даемонстрирует, каким образом следует создавать свои таблицы. На мой личный взгляд — самой сомнительной полезности тип. :)
Пример создания таблицы и попытки модификации данных:
create table tab1 (field1 INT) engine=example;
//При попытке сделать вставку...
insert into tab1 values (1),(2),(3);
ERROR 1031 (HY000): Table storage engine for 'tab1' doesn't have this option
BDB (BerkeleyDB)
Таблицы BDB обслуживаются транзакционным обработчиком BerkeleyDB, который разработан компанией Sleepycat. При создании таблиц этого типа формируются два файла. Один с расширением frm и в нём хранится структура таблицы, другой с расширением db в нём хранятся данные и индексы.
Особенности таблиц BDB:
1. Для таблиц ведётся журнал, что позволяет повысить устойчивость базы и увеличить вероятность успешного восстановления в случае сбоя.
2. Таблицы типа BDB хранятся в виде бинарных деревьев. Этот метод хранения замедляет сканирование таблицы (допустим для выборки всех строк таблицы) и увеличивает занимаемое таблицей место на диске. Однако поиск отдельных значений в таблице становится быстрее. Все остальные таблицы хранят в виде бинарных деревьев свои индексы.
3. Все таблицы BDB должны иметь первичный ключ, при отсутствии создаётся скрытый первичный ключ с атрибутом AUTO_INCREMENT.
4. Для данного типа таблиц поддерживаются транзакции на уровне страниц.
5. Подсчёт количества строк в таблице при помощи функции COUNT() происходит медленнее, из-за того что подсчёт строк для таблиц BDB (в отличие от MyISAM) на стороне сервера не поддерживается и полный пересчёт происходит при каждом обращении.
6. Ключи не являются упакованными, как в таблицах MyISAM и занимают больше места.
7. В случае, когда таблица BDB занимает всё свободное место на диске, происходит откат транзакции и вывод сообщения об ошибке. В отличие от BDB, таблицы MyISAM просто будут ждать появления свободного места, что приведёт к зависанию сервера.
8. Файлы таблиц BDB нельзя переносить между системами простым копированием, поскольку при их создании путь к файлу таблицы сохраняется. Для переноса базы необходимо использовать утилиту mysqldump.
Пример создания таблицы BDB:
create table tab1 (field1 INT) engine=BDB;
InnoDB
Тип таблиц InnoDB разработан компанией Innobase Oy. Таблицы такого типа предоставляют высокую производительность и устойчивое хранение данных в таблицах объёмом до 1 Тбайт и нагрузкой на сервер до 800 вставок/обновлений в секунду.
Особенности типа InnoDB:
1. Все таблицы хранятся в едином табличном пространстве, поэтому имена таблиц должны быть уникальны.
2. Хранение данных в едином табличном пространстве позволяет снять ограничение на объём таблиц. Файл с таблицами может быть разбит на несколько частей и распределён по нескольким дискам или даже хостам.
3. Таблицы поддерживают автоматическое восстановление после сбоя.
4. Поддерживаются транзакции.
5. Этот тип таблиц в MySQL единственный, который поддерживает каскадное удаление и внешние ключи.
6. Выполняется блокировка на уровне отдельных записей.
7. Имеется расширенная поддержка кодировок.
Пример создания таблицы InnoDB:
create table tab1 (field1 INT, field2 CHAR(10), INDEX (field1)) ENGINE=InnoDB;
«Экзотические типы таблиц» — к этим типам я отношу те, которыми сам никогда не пользовался и они мною, мало изучены — но тем не менее они существуют и стоит о них упомянуть.
NDB Cluster
Тип таблиц NDB Cluster предназначен для организации кластеров MySQL, в случае когда таблицы распределены между несколькими компьютерами, объединенными в сеть.
ARCHIVE
Тип ARCHIVE предназначен для хранения большого объёма данных в сжатом формате. При создании таких таблиц, создаётся файл совпадающий с именем таблицы и с расширением frm, в котором хранится структура таблицы. Помимо этого, создаются два файла с расширениями ARZ и ARM, в которых хранятся данные и мета-данные соответственно. Кроме того, при оптимизации таблицы может появиться файл с расширением ARN.
ARCHIVE таблицы поддерживают только два SQL оператора: INSERT и SELECT. Оператор SELECT выполняется методом полного сканирования таблицы.
CSV
Формат CSV, представляет собой обычный текстовый файл, записи в котором хранятся в строках, а поля разделены точкой с запятой. При создании таблицы формируются два файла. Один с расширением frm, содержащим структуру таблицы. Второй с расширением CSV — содержащим данные в CSV — формате. (Также, данные в CSV формате можно читать другими программами, например при помощи Excel)
FEDERATED
Тип FEDERATED позволяет хранить данные на удалённых таблицах, которые находятся на других машинах в сети. При создании таблицы создаётся только файл структуры с расширением frm, поскольку данные хранятся на удалённой машине.
Для создания таблицы FEDERATED необходимо сначала создать таблицу на удалённой машине, затем на рабочей машине с указанием на удалённую.
Пример создания таблицы FEDERATED:
//Сначала создаём таблицу на удалённой машине...
create table test1( field1 INT) engine=MyISAM;
//Теперь создаём таблицу FEDERATED на рабочей машине...
create table test2( field1 INT) engine=FEDERATED COMMENT='mysql://user_name@remote_host:3306/host_name/test1';
Структура таблиц на машинах должна быть идентична.
В поле комментария таблицы FEDERATED указывается строка подключения к таблице на удалённой машине.
Следует так-же заметить что в таблицах данного типа не поддерживаются транзакции.
Вот пожалуй и всё.