As of MySQL 3.23.6, you can choose between three basic
table formats. When you create a new table, you can tell MySQL
which table type it should use for the table. MySQL will
always create a .frm
file to hold the table and column
definitions. Depending on the table type the index and data will be
stored in other files.
The default table type in MySQL is MyISAM
. If you are
trying to use a table type that is not incompiled or activated,
MySQL will instead create a table of type MyISAM
.
You can convert tables between different types with the ALTER
TABLE
statement. See section 7.8 ALTER TABLE
syntax.
Note that MySQL supports two different kind of
tables. Transactions safe tables (BDB
) and not transaction safe
tables (ISAM
,MyISAM
and HEAP
.
Advantages of transaction safe tables (TST)
MySQL
crashes or you get hardware problems, you
can get your data back; Either by automatic recovery or from a backup
+ the transaction log.
COMMIT
command.
ROLLBACK
to ignore your changes (if you are not
running in auto commit mode).
Advantages of not transaction safe tables (NTST):
You can combine TST and NTST tables in the same statements to get the best of both worlds.
MyISAM
is the default table type in MySQL 3.23. It's
based on the ISAM
code and has a lot of useful extensions.
The index is stored in a file with the .MYI
(MYIndex) extension
and the data is stored in file with the .MYD
(MYData) extension.
You can check/repair MyISAM
tables with the myisamchk
utility. See section 15.4 Using myisamchk
for crash recovery.
The following is new in MyISAM
:
INSERT
new rows in a table without deleted rows,
while other threads are reading from the table.
AUTO_INCREMENT
column. MyISAM
will automatically update this on INSERT/UPDATE
. The
AUTO_INCREMENT
value can be reset with myisamchk
. This
will make AUTO_INCREMENT
columns faster (at least 10 %) and old
numbers will not be reused as with the old ISAM. Note that when a
AUTO_INCREMENT
is defined on the end of a multi-part-key the old
behavior is still present.
AUTO_INCREMENT
column) the key tree will be split so that the high node only contains one
key. This will improve the space utilization in the key tree.
BLOB
and TEXT
columns can be indexed.
NULL
values are allowed in indexed columns. This takes 0-1
bytes/key.
myisamchk
.
MyISAM
file that indicates whether or not the
table was closed correctly. This will soon be used for automatic repair
in the MySQL server.
myisamchk
will mark tables as checked if one runs it with
--update-state
. myisamchk --fast
will only check those
tables that don't have this mark.
myisamchk -a
stores statistics for key parts (and not only for
whole keys as in ISAM
).
myisampack
can pack BLOB
and VARCHAR
columns.
MyISAM
also supports the following things, which MySQL
will be able to use in the near future.
VARCHAR
type; A VARCHAR
column starts
with a length stored in 2 bytes.
VARCHAR
may have fixed or dynamic record length.
VARCHAR
and CHAR
may be up to 64K.
All key segments have their own language definition. This will enable
MySQL to have different language definitions per column.
UNIQUE
; This will allow
you to have UNIQUE
on any combination of columns in a table. (You
can't search on a UNIQUE
computed index, however.)
MySQL can support different index types, but the normal type is
ISAM or MyISAM. These use a B-tree index and you can roughly calculate
the size for the index file as (key_length+4)/0.67
, summed over
all keys. (This is for the worst case when all keys are inserted in
sorted order and we don't have any compressed keys.)
String indexes are space compressed. If the first index part is a
string, it will also be prefix compressed. Space compression makes the
index file smaller than the above figures if the string column has a lot
of trailing space or is a VARCHAR
column that is not always used
to the full length. Prefix compression is used on keys that start
with a string. Prefix compression helps if there are many strings
with an identical prefix.
In MyISAM
tables, you can also prefix compress numbers by specifying
PACK_KEYS=1
when you create the table. This helps when you have
many integer keys which have an identical prefix when the numbers are stored
high-byte first.
MyISAM supports 3 different table types. 2 of them are chosen
automatically depending on the type of columns you are using. The third,
compressed tables, can only be created with the myisampack
tool.
This is the default format. It's used when the table contains no
VARCHAR
, BLOB
or TEXT
columns.
This format is the simplest and most secure format. It is also the fastest of the on-disk formats. The speed comes from the easy way data can be found on disk. When looking up something with an index and static format it is very simple, just multiply the row number by the row length.
Also when scanning a table it is very easy to read a constant number of records with each disk read.
The security comes from if your computer crashes when writing to a
static MyISAM file, myisamchk
can easily figure out where each
row starts and ends. So it can usually reclaim all records except the
partially written one. Note that in MySQL all indexes can always be
reconstructed.
CHAR
, NUMERIC
and DECIMAL
columns are space-padded
to the column width.
myisamchk
) unless a huge number of
records are deleted and you want to return free disk space to the operating
system.
This format is used if the table contains any VARCHAR
, BLOB
or TEXT
columns or if the table was created with
ROW_FORMAT=dynamic
.
This format is a litte more complex because each row has to have a header that says how long it is. One record can also end up at more than one location when it is made longer at an update.
You can use OPTIMIZE table
or myisamchk
to defragment a
table. If you have static data that you access/change a lot in the same
table as some VARCHAR
or BLOB
columns, it might be a good
idea to move the dynamic columns to other tables just to avoid
fragmentation.
''
) for string columns, or zero for numeric columns (this isn't
the same as columns containing NULL
values). If a string column
has a length of zero after removal of trailing spaces, or a numeric
column has a value of zero, it is marked in the bit map and not saved to
disk. Non-empty strings are saved as a length byte plus the string
contents.
myisamchk
-r
from time to time to get better performance. Use myisamchk -ei
tbl_name
for some statistics.
3 + (number of columns + 7) / 8 + (number of char columns) + packed size of numeric columns + length of strings + (number of NULL columns + 7) / 8There is a penalty of 6 bytes for each link. A dynamic record is linked whenever an update causes an enlargement of the record. Each new link will be at least 20 bytes, so the next enlargement will probably go in the same link. If not, there will be another link. You may check how many links there are with
myisamchk -ed
. All links may be removed with myisamchk -r
.
This is a read only type that is generated with the optional
myisampack
tool (pack_isam
for ISAM
tables).
myisampack
.
0
are stored using 1 bit.
BIGINT
column (8 bytes) may
be stored as a TINYINT
column (1 byte) if all values are in the range
0
to 255
.
ENUM
.
BLOB
or TEXT
columns.
myisamchk
.
You can also use the deprecated ISAM table type. This will disappear
rather soon because MyISAM
is a better implementation of the same
thing. ISAM uses a B-tree
index. The index is stored in a file
with the .ISM
extension and the data is stored in file with the
.ISD
extension. You can check/repair ISAM tables with the
isamchk
utility. See section 15.4 Using myisamchk
for crash recovery.
ISAM
has the following features/properties:
Most of the things for MyISAM
tables are also true for ISAM
tables. See section 8.1 MyISAM tables. The major differences compared to MyISAM
tables are:
pack_isam
rather than with myisampack
.
HEAP
tables use a hashed index and are stored in memory. This
makes them very fast, but if MySQL crashes you will lose all
data stored in them. HEAP
is very useful for temporary tables!
The MySQL internal HEAP tables uses 100% dynamic hashing
without overflow areas. There is no extra space needed for free lists.
HEAP
tables also don't have problems with delete + inserts, which
normally is common with hashed tables..
mysql> CREATE TABLE test TYPE=HEAP SELECT ip,SUM(downloads) as down FROM log_table GROUP BY ip; mysql> SELECT COUNT(ip),AVG(down) FROM test; mysql> DROP TABLE test;
Here are some things you should consider when you use HEAP
tables:
MAX_ROWS
in the CREATE
statement
to ensure that you accidently do not use all memory.
=
and <=>
(but are VERY fast).
HEAP
tables can only use whole keys to search for a row; compare this
to MyISAM
tables where any prefix of the key can be used to find rows.
HEAP
tables use a fixed record length format.
HEAP
doesn't support BLOB
/TEXT
columns.
HEAP
doesn't support AUTO_INCREMENT
columns.
HEAP
doesn't support an index on a NULL
column.
HEAP
table (this isn't common for
hashed tables).
HEAP
tables are shared between all clients (just like any other
table).
ORDER BY
).
HEAP
tables are allocated in small blocks. The tables
are 100% dynamic (on inserting). No overflow areas and no extra key
space is needed. Deleted rows are put in a linked list and are
reused when you insert new data into the table.
DELETE FROM heap_table
or
DROP TABLE heap_table
.
MyISAM
table to a HEAP
table.
HEAP
tables bigger than max_heap_table_size
.
Memory needed for one row in a HEAP
table is:
SUM_OVER_ALL_KEYS(max_length_of_key + sizeof(char*)*2) + ALIGN(length_of_row+1,sizeof(char*))
sizeof(char*)
is 4 on 32 bit machines and 8 on 64 bit machines.
Berkeley DB (http://www.sleepycat.com) has provided MySQL
with a transaction safe table handler. This will survive crashes and
also provides COMMIT
and ROLLBACK
on transactions. In
order to build MySQL 3.23.x (BDB support first appeared in 3.23.15) with
support for BDB
tables, you will need Berkeley DB 3.1.11 or newer
which can be downloaded from http://www.mysql.com/downloads/mysql-3.23.html;
or also from Sleepycat's download page at http://www.sleepycat.com/download.html.
Even if Berkeley DB is in itself very tested and reliably, the MySQL interface is still very alpha, but we are actively improving and optimizing it to get it this stable real soon.
If you are running with AUTOCOMMIT=0
then your changes in BDB
tables will not be updated until you execute COMMIT
. Instead of commit
you can execute ROLLBACK
to forget your changes. See section 7.26 BEGIN/COMMIT/ROLLBACK
syntax.
The following options to mysqld
can be used to change the behavour of
BDB tables:
--bdb-home= directory | Berkeley home direcory |
--bdb-lock-detect=# | Berkeley lock detect. One of (DEFAULT, OLDEST, RANDOM or YOUNGEST) |
--bdb-logdir=directory | Berkeley DB log file directory |
--bdb-nosync | Don't synchronously flush logs |
--bdb-recover | Start Berkeley DB in recover mode |
--bdb-tmpdir=directory | Berkeley DB tempfile name |
--skip-bdb | Don't use berkeley db. |
If you use --skip-bdb
, MySQL will not initialize the
Berkeley DB library and this will save a lot of memory. You can of course
not use BDB
tables if you are using this option.
Some characteristic of BDB
tables:
BDB
tables must have a primary key.
BDB
tables is part of the same index or
part of the the primary key then MySQL can execute the query
without having to access the actual row. In a MyISAM
table the
above holds only if the columns are part of the same index.
LOCK TABLES
works on BDB
tables as with other tables. If
you don't use LOCK TABLE
, MYSQL will issue an internal
multiple write lock on the table to ensure that the table will be
properly locked if one another thread issues a table lock.
ALTER TABLE
doesn't yet work on BDB
tables.
BDB
tables are done on page level.
MyISAM
tables as one has data in BDB
tables is stored in B-trees and not in a separate data file.
BDB
table may make an automatic rollback and any
read may fail with a deadlock error.
BDB
tables compared to MyISAM tables with don't use
PACK_KEYS=0
.
FLUSH LOGS
from time to time to sync to get checkpoints
for the BDB
tables.
BDB
tables than using other table
types.
Some things that we have to fix in the near future:
BDB
tables must have a primary key. This
will be fixed by having an automatic hidden auto_increment column for
the tables without a primary key.
LOCK TABLES
should work as for other MySQL tables.
ALTER TABLE
doesn't yet work.
SHOW TABLE STATUS
doesn't yet provide that much information for BDB
tables.
Go to the first, previous, next, last section, table of contents.