Beruflich Dokumente
Kultur Dokumente
Introduction [p 5]
General Information about MySQL [p 6]
What is MySQL? [p 6]
History of MySQL [p 6]
The main features in MySQL [p 6]
What is the current MySQL version? [p 7]
How do I get MySQL? [p 7]
Should I get MySQL in source or binary distribution? [p 8]
Which operating systems does MySQL support? [p 8]
What languages are supported by MySQL. [p 8]
How/when will you release updates? [p 9]
What is UNIREG ? [p 9]
General SQL information and tutorials [p 10]
What are stored procedurs and triggers and so on [p 10]
MySQL mailing lists and how to ask questions [p 11]
Subscribing to/un-subscribing from the MySQL mailing list. [p 11]
Asking questions or reporting bugs. [p 11]
Guidelines for answering questions on the mailing list. [p 12]
When do I have/want to pay for MySQL? [p 13]
How much does MySQL cost? [p 13]
How do I get comercial support [p 14]
Types of comercial support [p 14]
How do I pay for a license? [p 15]
Who do I contact when I want support/a license? [p 15]
What Copyright does MySQL use? [p 16]
When may I distribute MySQL commercially without a fee [p 16]
I’m selling a product that can be configured to use MySQL [p 17]
I am running a commercial web server using MySQL. [p 17]
Do I need a license to sell commercial perl/tcl/PHP etc applications? [p 17]
Possible future changes in the licensing. [p 18]
How standards compatible are MySQL [p 19]
What extension has MySQL to ANSI SQL92? [p 19]
What functionality is missing in MySQL. [p 20]
What standards does MySQL follow? [p 21]
What functions exist only for compatibility? [p 21]
Limitations of BLOB and TEXT types [p 21]
How to go cope without COMMIT-ROLLBACK [p 21]
Compiling and installing MySQL [p 24]
Compiling MySQL [p 24]
Problems starting MySQL [p 24]
Automatic start/stop of MySQL [p 25]
How to debug MySQL [p 25]
How does MySQL privileges work [p 26]
How does the privilege system work? [p 26]
1
Adding new user privileges to MySQL [p 28]
Default privileges. [p 28]
A example of permission setup. [p 29]
MySQL language reference [p 30]
Literals. How do you write strings and numbers? [p 30]
Column types. [p 31]
More about data types [p 33]
Database size info. [p 33]
The numeric types [p 33]
TIMESTAMP type [p 33]
TEXT and BLOB types [p 33]
ENUM type [p 34]
SET type [p 34]
Column indexes [p 35]
Multiple field indexes [p 35]
Type mapping (to ease moving tabel definitions between different databases engines)
[p 35]
CREATE TABLE syntax. [p 36]
ALTER TABLE syntax [p 37]
DROP TABLE syntax. [p 38]
DELETE syntax. [p 38]
SELECT syntax [p 39]
Functions [p 40]
INSERT syntax [p 45]
LOAD DATA INFILE syntax [p 45]
UPDATE syntax [p 47]
SHOW syntax. Get information about names of columns. [p 47]
EXPLAIN syntax. Get information about a SELECT. [p 47]
DESCRIBE syntax. Get information about columns. [p 48]
Lock tables syntax [p 48]
SET OPTION syntax. [p 48]
GRANT syntax. (Compatibility function). [p 49]
CREATE INDEX syntax (Compatibility function). [p 49]
DROP INDEX syntax (Compatibility function). [p 49]
Is MySQL picky about reserved words? [p 49]
How safe/stable is MySQL [p 52]
How stable is MySQL? [p 52]
Why are there is so many release of MySQL? Is it because there are so many bugs? [p 54]
Checking a table for errors. [p 54]
How to repair tables. [p 55]
Is there anything special to do when upgrading/downgrading MySQL? [p 56]
How to get maximum performance out of MySQL [p 57]
How does MySQL use memory ? [p 57]
How does MySQL use keys? [p 58]
How does MySQL open & close tables? [p 59]
How should I arrange my table to be as fast/small as possible? [p 59]
What affects the speed of the INSERT statement? [p 60]
2
What affects the speed of DELETE statement? [p 60]
What kind of optimisation is done on the WHERE clause? [p 60]
How can I change the buffer sizes of mysqld ? [p 61]
What options to use to get MySQL to run at full speed? [p 62]
How to get MySQL to run as fast as possible with little memory? [p 62]
What are the different row formats? Or when to use VARCHAR/CHAR? [p 63]
Why so many open tables? [p 64]
MySQL Utilites [p 65]
Overview of the different MySQL programs [p 65]
The MySQL table check, optimize and repair program [p 66]
Getting low level table information [p 66]
The MySQL compressed read only table generator [p 70]
Adding functions to MySQL [p 75]
Adding new functions to MySQL [p 75]
ODBC [p 76]
Which operating systems does MySQL ODBC support? [p 76]
How should I report problems with MySQL ODBC? [p 76]
Programs known to work with MyODBC. [p 76]
How do I fill in the various fields in the ODBC administrator program? [p 76]
Problems [p 78]
Why do I get ’Access denied’? [p 78]
How to run MySQL as a normal user. [p 79]
Problems with file permissions [p 79]
Problems using DATE fields. [p 80]
MySQL client tools and API’s [p 81]
MySQL C API [p 81]
Why is it that after mysql_query() returns success, mysql_store_result()
sometimes returns NULL? [p 82]
What results can I get from a query? [p 83]
How can I get the unique ID for the last row? [p 83]
What is the difference between mysql_use_result() and
mysql_store_result() modes? [p 83]
Problems linking with C API. [p 84]
How to make a threadsafe client [p 84]
Making a threadsafe client [p 84]
What is the difference between different thread packages? [p 85]
MySQL Perl API’s [p 85]
mysqlperl [p 85]
DBD::mysql [p 85]
MySQL JAVA connectivity (JDBC) [p 85]
MySQL C++ API’s [p 85]
MySQL TCL API’s [p 85]
MySQL Python API’s [p 86]
MySQL Python API’s [p 86]
How does MySQL compare with other databases [p 87]
How does MySQL compare with mSQL [p 87]
How about mSQL tools like msql-tcl, msqljava? [p 88]
3
How different from mSQL are the MySQL client/server communications protocols? [p 88]
What are the differences in the SQL syntax between MySQL & mSQL 2.0? [p 89]
Problems with AND and OR priority [p 91]
This document was generated on 3 November 1997 using the texi2html translator version 1.51
(extended by davida@detron.se).
4
Go to the first, previous, next [p 6] , last [p 87] section, table of contents [p 1] .
Introduction
This is the technical manual about MySQL. This version is about the 3.21.x version of MySQL.
This manual is currently available in TeXInfo, Raw text, Info, Postscript and HTML versions.
The primary document is the TeXInfo file. The HTML version is automatically produced with
texi2html. The ASCII and info version is produced using makeinfo. The Postscript version is
produced using texi2dvi and divps.
If you have any suggestions concerning additions or corrections, please send them to the MySQL
mailing list mysql@tcx.se withthe following subject line; documentation suggestion:
[Insert Topic Here]. See section Subscribing to/un-subscribing from the MySQL mailing list.
[p 11] .
This manual is written and maintained by David Axmark, Michael (Monty) Widenius and Kim Aldale.
5
Go to the first [p 5] , previous [p 5] , next [p 11] , last [p 87] section, table of contents [p 1] .
The base upon which MySQL is built is a set of routines that have been used in a highly demanding
production environment for many years. While MySQL is currently still in development it already
offers a rich and highly useful function set. <P>
See the ‘CREDITS’ file in the distribution for persons that have been involved in the MySQL
project.
History of MySQL
We once started off with the intension to use mSQL to connect to our own fast low level (ISAM)
tables. However, after some testing we came to the conclusion that mSQL was not fast or flexible
enough for our needs. This resulted in a new SQL interface to our database but with almost the same
API interface as mSQL. This API was chosen to ease porting of third party code.
It is not perfectly clear where the name MySQL derives from. Our base directory and a large amount
of our libraries and tools have had the prefix ’my’ for well over 10 years. However, Monty’s daughter
(some years younger) is also named My. So which of the two gave its name to MySQL is still a
mystery, even for us.
6
Very fast B-tree disk tables with key compression.
Fixed and variable length records.
16 indexes/table. Each index may consist of 1 to 15 columns/parts of columns. Max key length is
127 bytes. A key may be a prefix of a CHAR field.
ODBC Open-DataBase-Connectivity for Windows95 (with source). All ODBC 2.5 functions and
lots of others.
In memory hash tables always used as temporary tables.
Can handle big databases (we are using MySQL with some databases that contain 50,000,000
records).
All columns have default values. One can always use INSERT on any subset of columns.
Uses GNU autoconf for portability.
Written in C and C++. Tested with gcc 2.7.2.
A thread based memory allocation system (very fast and no memory trashing).
No memory leaks. Tested with a commercial memory leakage detector (purify).
A very fast table check and repair utility (isamchk).
All data saved in ISO8859_1 format. All comparisons for normal string columns are case
insensitive.
Full ISO8859_1 (Latin1) support. For example Scandinavian åäö is allowed in table and column
names.
Sorts by ISO8859_1 Latin1 (the Swedish way at the moment). It is possible to change this in the
source by adding new sort order arrays.
Alias on tables and columns as in the SQL92 standard. avg & count).
INSERT,UPDATE and DELETE returns how many rows were affected.
Function names do not clash with table or column names. For example ABS is a valid column
name. The only restriction is that space is not allowed between a function name and the ’(’ when
using functions.
All MySQL commands have --help or -? for help.
The server currently supports error messages to clients in many languages. See section What
languages are supported by MySQL. [p 8] .
The clients uses a TCP connection or unix socket when connecting to the MySQL server.
User commands as show tables, show keys from table and show columns from
table
7
Should I get MySQL in source or binary distribution?
If you want to read (and/or modify) the C and C++ code that makes up MySQL you should always get
a source distribution. The code is always the ultimate manual. The source distribution also contains
more tests and examples than the binary distribution.
For most people who want to run MySQL on a platform that has binary releases, a binary version of
MySQL is more convenient. However, TcX’s binary release is not compiled in the same way as the
source release so there are some differences in where support files are located.
A working Posix thread library is needed for the server. On Solaris 2.5 we use SUN PThreads (the
native thread support in 2.4 and earlier versions are not good enough) and on Linux we use Linux
Threads by Xavier Leroy @email{Xavier.Leroy@inria.fr}.
The MySQL distribution includes a patched version of Provenzano’s Pthreads from MIT (see
http://www.mit.edu:8001/people/proven/pthreads.html) in thedistribution. This can be used for some
operating systems that does not have posix threads.
We have also tried to use another user level thread package named FSU Pthreads (see
http://www.informatik.hu-berlin.de/~mueller/pthreads.html). Thisimplementation is being used for the
SCO port.
See the thr_lock and thr_alarm programs in the mysys directory for some tests/examples of these
problems. More information can be found in the ‘PORTING’ file in the distribution.
‘mysql_base_dir/share/LANGUAGE/’
8
How/when will you release updates?
We are going to use the following policy when updating MySQL:
Each minor patch will increment the last number in the version string. When there are new features or
minor incompatibilities with previous versions, the second number in the version string will be
incremented.
On the rare occasions when a fatal bug is found that can’t be avoided we will make new binary
releases for Solaris & Linux as soon as possible. Other people may make binary releases for other
systems but probably less frequently.
For other fatal bugs we will make patches available as soon as we have located and fixed the bug.
For non crucial but annoying bugs we will make patches available if they are sent to me,
otherwise we will combine many of them into a bigger patch.
When there are more then about 10 patches we will make a new full source release.
When we have made a lot of changes we will make a new source and binary release. (About once
a month?)
What is UNIREG ?
Unireg is our tty interface builder, but it uses a low level connection to our NISAM (with is used by
MySQL) and because of this it is very quick. It has existed since 1979 (on Unix in C since ~1986).
We update most of our production databases with the UNIREG interface and serve web pages through
MySQL (and in some extreme cases the UNIREG report generator).
Unireg takes about 3M of disk space and works on at least the following platforms: SUN OS 4.x,
Solaris, Linux, HPUX, ICL Unix, DNIX, SCO and MSDOS.
9
Unireg is currently only available in Swedish and Finnish.
The price tag for UNIREG is 10,000 Swedish kr (about 1500$ US), but this includes support.
UNIREG is distributed as a binary. (But all the ISAM sources can be found in MySQL). Usually we
compile the binary for the customer at their site.
This one has been recommended by a lot of people on the MySQL mailing list.
Judith S. Bowman, Sandra L. Emerson and Marcy Darnovsky
"The Practical SQL Handbook: Using Structured Query Language"
Second Edition
Addison Wesley
ISBN 0-201-62623-3
http://www.awl.com
And another book also recommended by people on the MySQL mailing list.
Understanding SQL
ISBN 0-89588-644-8
Publisher Sybex 510 523 8233
Alameda CA USA
A trigger is a stored procedure that is invoked when something happens. For example one can install a
stored procedure that checks every delete to a transaction table and does a automatic delete on the
corresponding customer when all his transactions are deleted.
Go to the first [p 5] , previous [p 5] , next [p 11] , last [p 87] section, table of contents [p 1] .
10
Go to the first [p 5] , previous [p 6] , next [p 13] , last [p 87] section, table of contents [p 1] .
Please do not send mail about [un]subscribing to mysql@tcx.se since any mail sent to this address
isautomatically forwarded to hundreds of other users.
Your local site may have many subscribers to MySQL. In that case, it may have a local mailing list,
so that a single message from tcx.se is sent to the site and propagated to the local list. In such cases,
please contact your system administrator to be added to or dropped from the local MySQL list.
I think I have found a bug. What information do you need to help me?
If you can, please use the mysqlbug script that can be found in the scripts directory in the
distribution. If that is not possible, remember to specify (if relevant) the following:
1. State which version of MySQL you are using (for example mysql-3.20.0.tgz). You can find out
which version you are running by typing mysqladmin version.
2. The manufacturer and model of machine you are working on.
3. The operating system. For most operating systems you can get this from uname -a.
4. Sometimes the amount of memory (real and virtual) is also relevant.
5. If this is a bug when compiling: Include the exact error messages and also a few lines around the
offending code in the file from which you got the error.
6. If this is a run time bug, please describe exactly how you got the error. If you can include a test
program which shows the error you can get a more explicit answer.
If you are a support customer, please post the bug report to the specified mailing list for higher priority
treatment.
11
When answers are sent to you individually and not to the mailing list, it is considered good etiquette to
summarise the answers and mail them to the mailing list.
Try to summarise the essential part of the question in your reply, but don’t feel obliged to quote the
whole question.
Go to the first [p 5] , previous [p 6] , next [p 13] , last [p 87] section, table of contents [p 1] .
12
Go to the first [p 5] , previous [p 11] , next [p 19] , last [p 87] section, table of contents [p 1] .
The easiest way to pay for MySQL is to use the license form at TcX’s secure server at
@url{https://www.tcx.se/license.htmy}
We hope everybody understands that you only have to pay if you are selling MySQL directly or
selling a product which includes the MySQL server. You may not include MySQL in a
distribution if you charge for some part of it. For internal use you do not have to pay us if you do
not want to.
The client code is in the Public Domain or under the GPL (read-line). So there should not be any
problems with client code in commercial programs.
We may add some additional functionality in the commercial version. The likely test candidate
for this is fast compressed read only databases. The current server includes support to read such
databases but not the packing tool. If we get enough revenue from support we will probably
release this under the same license as the other stuff.
But if you like MySQL and want to encourage further development you are welcome to purchase
a license or support.
For more information see the rest of this chapter and the file ‘PUBLIC’ in the distribution.
The client access part of MySQL is in the public domain. The command line client includes parts that
is under the GNU Public License (readline).
These are our current license prices. All prices in US Dollars. If you pay by credit card the currency is
FIM (Finish Marks) so the prices will differ slightly.
13
licenses Price/Copy Minimum at one time Minimum Payment
100-1000 $40 100 $4000
1000-2500 $25 200 $5000
2500-5000 $20 400 $8000
The OEM prices require that you act as a middle-man for eventual problems/extension requests from
users. We also require that the OEM customer has a support contract. If you have a low margin high
volume product you can always talk to us about other terms. If you do, please be informative about
your product, pricing, market and any other information that may be relevant.
If you discover what we consider a real bug, we are likely to fix it in any case. But if you pay for
support we will notify you about the fix status instead of just fixing it in a later release.
14
4. You are allowed to alter the MySQL TODO.
5. Your email will be dealt with before normal email support users and non registred users.
6. If you have a very specific problem we can try to log in on your system and try to solve it
’in place’.
‘login support’
One year of email/phone/telnet support costs $2000. In this we include support for fast
compressed read only databases (no blobs yet). The current server includes support to read such
databases but not the packing tool. If we get enough revenue from support we will probably
release this under the same license as the server sometime in the future...
‘extented login supprt’
One year of extented email/phone/telnet support costs $5000. This of course also includes the
compressed read only database support.
T.C.X DATAKONSULT AB
BOX 6434
11382 STOCKHOLM
Specify: license and/or support and your name and email address.
In Europe and Japan you can use EuroGiro (that should be cheaper) to the same account.
If you want to pay by cheque make it payable to "Monty Program KB". And mail it to the address
below.
Monty Program KB
Michael Widenius
Gamla Skomakarbolev. 1 E 11
00740 Helsingfors
Finland
If you want to pay with credit card over Internet you can use https://www.tcx.se/license.htmy
15
Detron HB
David Axmark
Kungsgatan 65 B
753 21 UPPSALA
SWEDEN
Voice Phone +46-18-10 22 80
Fax +46-8-729 69 05 (I prefer email if possible as the fax machine happens to be in another town.)
E-Mail: mysql-c@detron.se
1. The MySQL specific source needed to make the mysqlclient library and programs in the
‘client’ directory is in the public domain. Each file which is in the public domain has a
header which clearly states so. This is everything in ‘client’ directory and some parts of
mysys, mystring and dbug libraries.
2. Some small parts of the source (GNU getopt) are covered by the "GNU LIBRARY GENERAL
PUBLIC LICENSE". See the ‘mysys/COPYING.LIB’ file.
3. Some parts of the source (GNU readline) are covered by the "GNU GENERAL PUBLIC
LICENSE". See the ‘readline/COPYING’ file.
4. Some parts of the source (the regexp library) are covered by a Berkeley style copyright.
5. The other source needed for the MySQL server is AGPL. See the file PUBLIC for more info.
The SQL client library should be totally free so it can be included in commercial products
without limitations.
People who want free access to the software we have put a lot of work into can have it so long
they do not try to make money directly by distributing it for profit.
People who want the right to keep their own software proprietary, but also want the value from
our work, can pay for the privilege.
That means that normal in house use is FREE. But if you use it for something important to you,
you may want to support further development of MySQL by purchasing a support license.
MySQL may be *used* freely, including by commercial entities for evaluation or unsupported internal
use. However, *distribution* for commercial purposes of MySQL, or anything containing or derived
from MySQL in whole or in part, requires a written commercial license from TcX AB, the sole entity
authorised by to grant such licenses.
You may not include MySQL "free" in a package containing anything for which a charge is being
made except as noted below.
The intent of the exception provided in the second clause is to allow commercial organisations
operating an FTP server or a bulletin board to distribute MySQL freely from it, provided that:
16
1. The organisation complies with the other provisions of the FPL, which include among other
things a requirement to distribute the full source code of MySQL and of any derived work, and to
distribute the FPL itself along with MySQL;
2. the only charge for downloading MySQL is a charge based on the distribution service and not
one based on the content of the information being retrieved (i.e., the charge would be the same
for retrieving a random collection of bits of the same size);
3. the server or BBS is accessible to the general public, i.e., the phone number or IP address is not
kept secret, and anyone may obtain access to the information (possibly by paying a subscription
or access fee that is not dependent on or related to purchasing anything else).
If you want to distribute software in a commercial context that incorporates MySQL and you do *not*
want to meet these conditions, you should contact TcX AB to find out about commercial licensing.
Commercial licenses involve a payment, and include support and other benefits. These are the only
ways you legally can distribute MySQL or anything containing MySQL: either by distributing
MySQL under the requirements of the FPL, or by getting a commercial license from TcX AB.
If your product REQUIRED MySQL to work you would have to pay a license. If MySQL just added
some new features it should fall inside normal use. For example is using MySQL added logging to a
database instead of a text file it should not require a license. This would of course mean that the user
has to fetch and install MySQL by himself. If the program is (almost) useless without MySQL you
would have to get a MySQL license to sell your product.
No you are not selling MySQL itself. But is this case we would like you to purchase MySQL support.
That is either your support of MySQL or our support of you (the later is more expensive since our
time is limited).
If you’ve designed it strictly around MySQL then you’ve really made a commercial product that
requires the engine, so yes, I would think you have to pay.
If, however, you can support any database with a base level of functionality (and you don’t rely on
anything that only MySQL supports) you probably DO NOT have to pay.
17
It also depends on what you’re doing for the client. Are you tying into a database you expect to
already exist by the time your software is purchased? Then you again probably don’t have to pay. Or
do you plan to distribute MySQL or give them detailed instructions on installing it with your
software? Then you probably do.
One thing I’d like to suggest, folks. Look, development won’t last forever if nobody pays. I agree that
buying a copy for every software user is prohibitive compared to other products available but would it
not be courtesy for commercial developers to register their OWN copy that they develop with?
Go to the first [p 5] , previous [p 11] , next [p 19] , last [p 87] section, table of contents [p 1] .
18
Go to the first [p 5] , previous [p 13] , next [p 24] , last [p 87] section, table of contents [p 1] .
The field types MEDIUMINT, SET, EMUN???? and the different BLOB and TEXT types.
The field attributes auto_increment, unsigned and zerofill.
MySQL maps all tables to filenames and with MySQL one can use standard system tools to
backup, rename, move, delete and copy tables. This forces MySQL to be case sensitive on table
names on operating systems that have case sensitive filenames (like most Unix systems). If you
have a problem remembering table names, create everything in lowercase.
Use of INTO OUTFILE and STRAIGHT_JOIN in a SELECT statement. See section SELECT
syntax [p 39] .
EXPLAIN SELECT to get a description on how tables are joined.
Use of key names, keys on a subpart of a field, and use of KEY or INDEX in a CREATE TABLE
statement. See section CREATE TABLE syntax. [p 36]
Use of DROP column or CHANGE column in a ALTER TABLE statement. See section
ALTER TABLE syntax [p 37] .
Use of LOAD DATA INFILE. This syntax is in many cases compatible with Oracles LOAD
DATA INFILE. See section LOAD DATA INFILE syntax [p 45] .
Using " instead of ’ to enclose strings.
Using the escape \ character.
The SET OPTION statement. See section SET OPTION syntax. [p 48]
Using, in the SELECT part of a GROUP BY statement, fields or functions that do not appear in
the GROUP BY list. In MySQL this means ’any matching value’. By using this one can get a
much higher performance by avoiding sorting and grouping unnecessary items. This is often used
in this context:
SELECT order.customerid,customer.name,max(payments) from order,customer
WHERE order.customerid = customer.customerid GROUP BY order.customerid;
In ANSI SQL you would have to add the customer.name in the GROUP BY clause which is
redundant in MySQL.
To make it easier for user that comes from different SQL environments mysql supports a lot of
aliases for many functions. For example all string functions support both the ANSI SQL and the
ODBC syntax.
The || and && operators is in MySQL synonyms for OR and AND, like in the C programming
language. Likewise | and & stands for bitwise OR and AND. Because if this nice syntax, MySQL
doesn’t support the ANSI SQL operator || for string concatenation, but one have to use
CONCAT() instead. As CONCAT() takes any number of arguments it’s easy to convert use of
the || operatior to MySQL.
Use of any of the following functions:
=, <>, <= ,<, >=,>, AND, OR, or LIKE in a column statement
LAST_INSERT_ID. See section How can I get the unique ID for the last row? [p 83]
19
REGEXP or NOT REGEXP.
CONCAT() or CHAR() with 1 or more than 2 arguments. In MySQL the above functions
can take any number of arguments.
BIT_COUNT(), ELT(), FROM_DAYS(), FORMAT(), IF(), PASSWORD(),
ENCRYPT(), PERIOD_ADD(), PERIOD_DIFF(), TO_DAYS(), or WEEKDAY().
Use of TRIM to trim substrings. ANSI SQL only supports removal of single characters.
The STD(), BIT_OR and BIT_AND group functions.
Use of MIN() or MAX() as functions, not group functions.
20
UPDATE table_name SET credit=credit-!payment!
Where instead of !payment! we automaticly insert the value of the payment. What do you think
will happen when ’payment’ is negative ? Because 1--1 is legal in SQL, we think is terrible that
’--’ means start comment. If you have a sql program in a textfile that contains -- comments you
should use
replace " --" " #" < text-file-with-funny-comments.sql | mysql database.
You can also change the -- to # comments in the command file with:
replace " --" " #" -- text-file-with-funny-comments.sql
21
(typical times are at least 2-3 times faster) is the lack of COMMIT-ROLLBACK.
For the moment, we are much more for implementing the SQL server language (stored procedures).
With this you very seldom really need COMMIT-ROLLBACK besides being able to do many more
things without losing any speed.
Loops that need transactions can normally be coded with the help of LOCK TABLES and one doesn’t
need cursors when one can update records on the fly.
We have transactions and cursors on the TODO but not quite prioritised. If it is implemented it will be
as a option to CREATE TABLE. That means that COMMIT-ROLLBACK will only work on those
tables and only those tables will be slower.
We at TcX have a greater need for a real fast database than a 100% general database. Whenever we
find a way to implement these without any speed loss we will probably do it, but for the moment there
is many more important things to do. Check the TODO for how we prioritise things at the moment.
Customers with extended mail support can alter this slightly, so things may be reprioritised.
The current problem is actually ROLLBACK. Without ROLLBACK you can do anything with LOCK
TABLES. To support ROLLBACK MySQL would had to be changed to store all old records that was
updated and revert everything back to the starting point if ROLLBACK was issued. For simple cases
this isn’t that hard to do (the current isamlog could be used for this), but if one wants to have
ROLLBACK with ALTER/DROP/CREATE TABLE it would make everything much harder to
implement.
- Test conditions.
- Update if everything is ok.
UNLOCK TABLES.
This is usually much faster, but not always. The only thing this doesn’t handle if someone does a kill
on the process...
One can also use functions to update things in one operation. By doing all updates relatively and/or
only update those fields that actually have changed one can get a very efficient application.
For example, when we are doing updates on some customer information, we only update the customer
data that has changed and only test that not any of the changed data, or data that depends on the
changed data, has changed in the original row. The test for change is down with the WHERE clause in
the UPDATE statement. If the record wasn’t updated we give the client a message: "Some of the data
you have changed has been changed by another user", and then we show the old row versus the new
row in a window. The user can then decide which version of the customer record he should use.
This gives us something like ’column locking’ but actually even better, because we only update some
of the columns with relative information. This means that a typical update statement looks something
like:
22
UPDATE tablename SET pay_back=pay_back+’relative change’
As you can see, this is very efficient and even if another client has changed the ’money_he_ows_us’
or ’pay_back’ amount this will still work.
In many cases, users have wanted ROLLBACK and/or LOCK TABLES to manage unique identifiers
for some tables. This can be handled much more efficiently by using an AUTO_INCREMENT column
and the MySQL API function mysql_insert_id. See section How can I get the unique ID for the
last row? [p 83]
At TcX we have never had any need for row level locking as we have always been able to code around
it. I know some cases that really need row locking, but they are very few. If you want to have row
level locking you can do something like:
UPDATE table_name SET row_flag=1 WHERE id=ID ;
MySQL returns affected rows = 1 if the row was found and row_flag wasn’t 1 in the original
document. On the TODO there is GET_LOCK and RELEASE_LOCK for those that want to implement
application level locking.
Go to the first [p 5] , previous [p 13] , next [p 24] , last [p 87] section, table of contents [p 1] .
23
Go to the first [p 5] , previous [p 19] , next [p 26] , last [p 87] section, table of contents [p 1] .
There is also a benchmark suite so you can compare how MySQL perform on different platforms. In
the near future this will also be used to comapre MySQL to other SQL databases.
> cd bench
> run-auto-increment-test
You can also run the tests in the test subdirectory. To run ‘auto_increment.tst’:
./mysql -vf test < ./tests/auto_increment.tst
24
Expected results are shown in the file ‘./tests/auto_increment.res’.
You might want to add these start and stop commands in the appropriate places in your /etc/rc* files
when you start using MySQL for production applications.
If you have compiled MySQL with --with-debug=yes you can can also get a very informative log
with:
libexec/mysqld --debug
You can get more information about the debug switches by examining the file dbug/dbug.c.
If you have a problem with mysqld that it crashes and you want this quickly solved, you should
include a trace file with your mail if possible. Trace files can be posted directly to
@email{mysql-support@tcx.se} to avoid long messages to the standard mail list. If the trace file is big
you should use ftp and send it to ftp://www.tcx.se/pub/mysql/secret/ together with a
mysqldump of any tables that you think can help to solve the problem. The context of the above
directory is hidden for outside users so no one except the TCX staff can look at what you send into it.
Go to the first [p 5] , previous [p 19] , next [p 26] , last [p 87] section, table of contents [p 1] .
25
Go to the first [p 5] , previous [p 24] , next [p 30] , last [p 87] section, table of contents [p 1] .
The grant tables privileges on rows are select, insert, update and delete.
The table and database privileges are create and drop. Create and drop are for both tables and
databases. Since a user with a drop grant can delete any table, this is the same thing as a drop grant for
the database.
Other privileges give the right to use files (for LOAD DATA INFILE and SELECT INTO OUTFILE)
and to use the administrative commands shutdown, reload, refresh and process, to get the current
process list.
The privilege tables are read into mysqld with mysqladmin reload. If the privilege tables are
empty or non-existent or if the server is started with --skip-grant-tables, full access is
granted to everyone.
You can always test your privileges with the script mysqlaccess, which Yves Carlier has provided
for the MySQL distribution. See section Why do I get ’Access denied’? [p 78]
The host and db fields may contain a SQL regexp with chars % and _. Leaving any of these fields
empty is equivalent to setting it to ’%’.
A host may be localhost, a hostname, an IP number or an SQL expression. An empty host in
the db table means any host in the host table. An empty host in the host or user table means any
host that can create a TCP connection to your server.
A db is the name of a database or an SQL regexp.
An empty user field means any username will do.
An empty password means that the entry will only be used if no password is supplied.
The privileges from the user table are OR’ed to the db table. This means that a superuser only
needs to be in the user table with all privilege-flags set to Y.
Everything granted in the user table is valid for every database that cannot be found in the db table.
For this reason, it might be wise to grant users (apart from superusers) privileges on a per-database
basis only.
The host table is mainly there to maintain a list of "secure" servers. At TcX host contains a list of
all machines on the local network. These are granted all privileges.
26
The connecting user’s privileges are calculated by the following algorithm:
1. First sort all three tables by host by putting hosts without wildcards first, followed by hosts with
wildcards and entries with host = "". Within each host, di.e. very much like GROUP BY
Host, sort by user using the same rules. Finally, in the db table, sort by db using the same rules.
In the steps below, we will look through the sorted tables and always use the first match found.
2. Get the privileges for the connecting user from the db table using the first match found. Call this
set of privileges P.
3. If host = "" for the entry found in the db table, AND P with the privileges for the host in the
host table, i.e. remove all privileges that are not "Y" in both. (If host <> "", P is not
affected. In suchcases, host must have matched the connecting host’s name at least partially.
Therefor it can be assumed that the privileges found in this row match the connecting host’s
profile.)
4. OR (add) P with the privileges for the user from the user table, i.e. add all privileges that are
"Y" in user.
Let’s show an example of the sorting and matching! Suppose that the user table contains this:
+-----------+----------+-
| Host | User | ...
+-----------+----------+-
| % | root | ...
| % | jeffrey | ...
| localhost | root | ...
| localhost | | ...
+-----------+----------+-
localhost/root
localhost/any
any/jeffrey
any/root
So jeffrey attempting to connect on localhost will be matched by the localhost/any line, not by
the any/jeffrey line. The first match found is used!
So if you have access problems, print out the user table, sort it by hand, and see where the match is
being made.
Here follows an example to add a user ’custom’ that can connect from hosts ’localhost’,
’server.domain’ and ’whitehouse.gov’. He wants to have password ’stupid’. The database
’bankacount’ he only want to use from ’localhost’ and the ’customer’ database he wants to be able to
reach from all three hosts.
shell> mysql mysql.
mysql> insert into users (host,user,password)
values(’localhost’,’custom’,password(’stupid’));
mysql> insert into users (host,user,password)
values(’server.domain’,’custom’,password(’stupid’));
mysql> insert into users (host,user,password)
values(’whitehouse.gov’,’custom’,password(’stupid’));
27
mysql> insert into db
(host,db,user,Select_priv,Insert_priv,Update_priv,Delete_priv,
Create_priv,Drop_priv)
values
(’localhost’,’bankacount’,’custom’,’Y’,’Y’,’Y’,’Y’,’Y’,’Y’);
mysql> insert into db
(host,db,user,Select_priv,Insert_priv,Update_priv,Delete_priv,
Create_priv,Drop_priv)
values
(’%’,’customers’,’custom’,’Y’,’Y’,’Y’,’Y’,’Y’,’Y’);
You can of course also use xmysqladmin, mysql_webadmin, mysqladmin and even xmysql to
insert/change and update values in the privilege tables. You can find these utilities in the Contrib
directory.
This assumes the current user has insert privileges for the mysql db table and reload privileges. The
server (mysqld) has to be running. If it is not, start it with safe_mysqld --log &.
> mysql mysql
insert into user values (’%’,’monty’,password(’something’),’Y’,’Y’,’Y’,’Y’,’Y’,’Y’,’Y’,’Y’,’Y’,’Y’) ;
insert into user (host,user,password) values(’localhost’,’dummy’,") ;
insert into user values (’%’,’admin’,",’N’,’N’,’N’,’N’,’N’,’N’,’Y’,’N’,’Y’,’Y’) ;
quit
> mysqladmin reload
Monty
Full superuser, but must use password when using MySQL.
admin
Doesn’t need a password but is only allowed to use mysqladmin reload, mysqladmin
refresh and mysqladmin processlist. May be granted individual database privileges
through table db.
dummy
Must be granted individual database privileges through table db.
Default privileges.
The default privileges (set in ‘scripts/mysql_install_db’) is that root can do anything. Any
user can do anything with any database whose name is ’test’ or starts with ’test_’. A normal user can’t
use mysqladmin shutdown or mysqladmin processlist. See the script
(‘scripts/mysql_install_db’) for an example on how to add other users.
The privilege tables are read into mysqld with ’mysqladmin reload’. If the privilege tables are empty
(or non-existent) full access are granted to everyone.
28
A example of permission setup.
A common mistake is to try something like:
Then (of course) a mysqladmin reload to make the authentication change take effect, then trying
to connect to the server:
And like before mysqladmin reload to make the authentication change take effect.
Go to the first [p 5] , previous [p 24] , next [p 30] , last [p 87] section, table of contents [p 1] .
29
Go to the first [p 5] , previous [p 26] , next [p 52] , last [p 87] section, table of contents [p 1] .
\0 A ascii 0 character.
\n A newline character.
\t A tab character.
\r A return character.
\b A backspace character.
\’ A ’ character.
\" A " character.
\\ A \ character.
\% A % character. This is used in wild-card strings to search after %.
\_ A _ character. This is used in wild-card strings to search after _.
A ’ inside a string started with ’ may be written as ".
A " inside a string started with " may be written as "".
+-------+---------+-----------+-------------+--------+
| hello | ’hello’ | ""hello"" | ’h’e’l’l’o’ | hel"lo |
+-------+---------+-----------+-------------+--------+
| hello | ’hello’ | ""hello"" | ’h’e’l’l’o’ | hel"lo |
+-------+---------+-----------+-------------+--------+
+-------+-------+-----------+-------+--------+--------+
| hello | hello | ""hello"" | ’ello | e’l’lo | ’hello |
+-------+-------+-----------+-------+--------+--------+
| hello | hello | ""hello"" | ’ello | e’l’lo | ’hello |
+-------+-------+-----------+-------+--------+--------+
+--------------------+
| This
Is
Four
lines |
+--------------------+
| This
30
Is
Four
lines |
+--------------------+
If you want to insert binary data into a blob the following characters must be represented by escape
sequences:
NUMBERS
NULL
When using the text file export formats, NULL may be represented by \N. See section LOAD DATA
INFILE syntax [p 45]
Column types.
The following column types are supported:
31
A small floating point number. Precision can be 4 or 8.
FLOAT(4) is a single precision number and FLOAT(8) is a
double precision number (se the DOUBLE entry). This
FLOAT(Precision) 4
syntax is for ODBC compatibility. Range
-3.402823466E+38F - -1.175494351E-38, 0,
-1.175494351E-38 - 3.402823466E+38F.
A small floating point number. Cannot be unsigned. Range
FLOAT [(max display
-3.402823466E+38F - -1.175494351E-38, 0, 4
size,number of decimals)]
-1.175494351E-38 - 3.402823466E+38F.
A normal floating point number. Cannot be unsigned.
DOUBLE PRECISION [(max
Range -1.7976931348623157E+308 -
display size,number of 8
-2.2250738585072014E-308, 0,
decimals)]
2.2250738585072014E-308 - 1.7976931348623157E+308.
REAL [(length,decimals)] Same as DOUBLE 8
An unpacked floating point number. Cannot be unsigned.
DECIMAL [(max display
Currently the same range maximum range as a double. M+D
size,number of decimals)]
Behaves as a CHAR column
NUMERIC [(length,decimals)] Same as DECIMAL M+D
TIMESTAMP [(display size)] An automatic timestamp. 4
A type to store date information. Uses the
"YYYY-MM-DD" syntax, but may be updated with a
DATE number or a string. Understands at least the following 4
syntaxes: ’YY-MM-DD’, ’YYYY-MM-DD’, ’YYMMDD’,
’YYMM’, ’YY’. Range 0000-00-00 to 9999-12-31.
A type to store time information. Uses the "HH:MM:SS"
syntax, but may be updated with a number or a string.
TIME 3
Understands at least the following syntaxes: ’HH:MM:DD,
’HHMMDD’, ’HHMM’, ’HH’.
A type to store date and time information. Format
DATETIME "YYYY-MM-DD HH:MM:SS". Takes 8 bytes. Range 8
’0000-01-01 00:00:00’ - ’9999-12-31 23:59:59’.
A fixed length string that is always filled up with spaces to
the specified length. Range 1 - 255 characters. All end
CHAR(max_length) [binary] M
space are removed when retrieved. Is sorted and compared
case insensitively unless the binary keyword is given.
A variable length string that is stored with its length.
VARCHAR(max_length)
Maximum range 1 - 255 characters. Is sorted and compared L + 1
[binary]
case insensitively unless the binary keyword is given.
TINYTEXT and TINYBLOB A TEXT/BLOB with max length of 255 characters. L+1
TEXT and BLOB A TEXT/BLOB with max length of 65535 characters. L+2
32
MEDIUMTEXT and
A TEXT/BLOB with max length of 1677216 characters. L+3
MEDIUMBLOB
A TEXT/BLOB with max length of 4294967295
LONGTEXT and LONGBLOB L+4
characters.
A string object that can have only one set of allowed 1 or
ENUM(’value’,’value2’,...)
values. See section More about data types [p 33] . 2
A string object that can have one or many values of a set of
SET(’value’,’value2’,....) 1-8
allowed values. See section More about data types [p 33] .
If you use any data type with a L in the length field you will get a variable length record format.
Also for all integer columns the optional argument ZEROFILL means that the column will be padded
with zeroes upto the maximum length.
Max display size and decimals are for formating and calculation of max column width.
TIMESTAMP type
Has a range of 1 Dec 1970 time 0.00 to sometime in the year 2106 and a resolution of one second.
Will be automatically updated if not used in a statement that updates a row or if set to NULL. Can be a
(part of) a key. Note that if you have many timestamp fields in a row, then only the first timestamp
field will be automatically updated. Any timestamp field will be set to the current time if set to NULL.
Depending on the display size one gets one of the following formats: "YYYY-MM-DD HH:MM:SS",
"YY-MM-DD HH:MM:SS", "YYYY-MM-DD" or "YY-MM-DD".
A BLOB is a binary large object which can hold any amount of data :) There are 4 kinds of blobs See
section Column types. [p 31] . Normally one can regard a BLOB as a VARCHAR without a specified
limit.
33
TEXT is a BLOB that is sorted and compared case insensitively.
There are some constraints because of the message buffer used. The default size of the buffer is 64K
for the server and 512K for the clients. To change the buffer length for the server, use mysqld -O
max_allowed_packet=max_blob_length. This allows the message buffer to grow up to this
limit when needed.
ENUM type
A string object that can have only one set of allowed values. The value to be stored may be given case
independently. If one tries to store a non existing value, "" is stored. If used in a number context this
object returns/stores the value index. If there is less than 255 possible values this object occupies 1
byte, else two bytes (with a maximum of 65535 different values). Note that if a integer is put in the
ENUM you get the corresponding string with the first counting as number zero. Sorting on ENUM types
are done after the order of the strings in the enum.
For example the column test ENUM("one","two", "three") can have any off these values:
"one"
"two"
"three"
SET type
A string object that can have one or many values of a set of allowed values. Each value is separated by
a ’,’. If used in a number context this object returns/stores the bit positions of the used values. This
object occupies (number_of_different_values-1)/8+1 bytes, rounded up to 1,2,3,4 or 8. One can’t have
more than 64 different values. Note that if a integer is put in the SET you get the corresponding string
with the first bit corresponding to the first string.Sorting on SET types are done numericaly.
For example the column test SET("one","two") can have any off these values:
""
"one"
"two"
"one,two"
34
Column indexes
You can have indexes on all MysQL column types except BLOB and TEXT. Using indexes on the
relevant columns is the most important thing is getting you selects to run fast.
For CHAR and VARCHAR columns you can have a index on a prefix. The example below show how
to create a index for the first 10 characters of a column. This is much faster and requires less disk
space than having a index on the whole field.
CREATE TABLE test (
name CHAR(200),
KEY name (last_name(10));
A multiple column key can be considered as a sorted array where the columns are concatenated.
SELECT * FROM test WHERE last_name="Widenius" and first_name >="M" and first_name < "N";
35
binary(num) char(num) binary
char varying varchar
float4 float
float8 double
int1 tinyint
int2 smallint
int3 mediumint
int4 int
int8 bigint
long varbinary blob
long varchar text
middleint mediumint
varbinary(num) varchar(num) binary
create_definition:
column_name type [DEFAULT default_value] [NOT NULL | NULL] [ PRIMARY KEY ]
[reference_definition]
or PRIMARY KEY ( key_column_name,... )
or KEY [key_name] KEY( key_column_name,...)
or INDEX [key_name] ( key_column_name,...)
or UNIQUE [key_name] ( key_column_name,...)
or FOREIGN KEY key_name ( key_column_name,...) [reference_definition]
or CHECK (expr)
key_column_name:
column_name [ (length) ]
reference_definition:
REFERENCES table_name [( key_coulmn_name,...)]
[ MATCH FULL | MATCH PARTIAL]
[ ON DELETE reference_option]
[ ON UPDATE reference_option]
reference_option:
RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT
The FOREIGN KEY, CHECK and REFERENCE syntax are only for compatibility. They don’t
actually do anything.
If a column doesn’t have a DEFAULT value and is not declared as NOT NULL, the default value is
NULL.
36
ZEROFILL means that number is pre-zeroed to maximal length. With INT(5) ZEROFILL a
value of 5 is retrieved as 00005.
BINARY means that the column will be compared case sensitive. The default is that all strings
are compared case insensitive. BINARY is ’sticky’ which means that if a column marked
’binary’ is used in a expression, the whole expression is compared ’binary’.
INDEX is only a synonym for KEY.
If one doesn’t assign a name to a key, the key will get the same name as the first key_column
with an optional _# to make it unique.
Key columns and timestamp columns can’t be NULL. For these columns the NULL attribute is
silently removed.
With column_name(length) syntax one can specify a key which is only a part of a string
column. This can make the index file much smaller.
A number column may have the additional attribute AUTO_INCREMENT to automatically get
the largest value+1 for each insert where column value is NULL or 0. See section How can I get
the unique ID for the last row? [p 83]
One can insert NULL for timestamp and auto_increment columns. This results in the current time
/ the next number.
Blob columns can’t be keys.
When one groups on a blob only the first ’max_sort_length’ bytes are used See section
Limitations of BLOB and TEXT types [p 21] .
Deleted records are in a linked list and subsequent inserts will reuse old positions. To get smaller
files one can use the isamchk utility to reorganise tables.
Each null column takes 1 bit extra, rounded up to the nearest byte.
The maximum record length can be calculated as follows: 1+ sum_of_column_lengths +
null_columns/8 + number of variable length columns.
In some cases an attribute may silently change after creation: VARCHAR columns with a length of
1 or 2 are changed to CHAR. When using one VARCHAR column all CHAR columns longer than 2
are changed to VARCHAR’s.
On INSERT/UPDATE all strings (CHAR and VARCHAR) are silently chopped/padded to the
maximal length given by CREATE. All end spaces are also automatically removed. For example
VARCHAR(10) means that the column can contain strings with a length up to 10 characters.
Something/0 gives a NULL value.
The regular expression function (REGEXP and RLIKE) uses ISO8859-1 (Latin1) when deciding
the type of a character.
alter_specification:
ADD [COLUMN] create_definition
or CHANGE [COLUMN] old_column_name create_definition
or ALTER [COLUMN] column_name { SET DEFAULT literal | DROP DEFAULT }
or DROP [COLUMN] column_name
or DROP PRIMARY KEY
DROP INDEX key_name
ALTER TABLE works by creating a temporary table and copying all information to it and then
the old table is deleted and the new one is renamed. This is done in such a way that all updates
are automatically redirect to the new table without any failed updates. While the ALTER TABLE
is working, the old table is readable for other clients. Table updates/writes to the table are stalled
37
and only executed after the new table is ready.
If IGNORE isn’t specified then the copy will be aborted and rolled back if there exists any
duplicated unique keys in the new table. This is a MySQL extension.
The CHANGE column_name, DROP column_name and DROP INDEX are MySQL
extensions to ANSI SQL92.
The optional word COLUMN is a pure noise word and can be omitted.
The ADD and CHANGE takes the same create_definition as CREATE TABLE. See section
CREATE TABLE syntax. [p 36] .
ALTER COLUMN sets a new default value or removes the old default value for a column.
DROP INDEX removes an index. This is an MySQL extension.
The FOREIGN KEY syntax in MySQL exists only for compatibility with other SQL vendors
CREATE TABLE commands: It doesn’t do anything. See section How standards compatible are
MySQL [p 19]
If one drops a column_name which is part of some key, this key part is removed. If all key parts
are removed then the key is removed.
DROP PRIMARY KEY drops the first UNIQUE key in the table.
CHANGE tries to convert data to the new format as good as possible.
With mysql_info(MYSQL*) one can retrieve how many records were copied and how many
records were deleted because of multiple keys.
To use ALTER TABLE one has to have select, insert, delete, update, create and drop privileges
on the table.
Removes one or more tables. All the data and the definition is removed so take it easy with this
command!
DELETE syntax.
DELETE FROM table_name WHERE where_definition
If one does a delete without a where clause then the table is recreated which is much faster than doing
a delete for each row. In these cases, the SQL command returns zero as affected records.
Using DELETE FROM table_name will work even if the data files do not exist as only
information from the table definition file, table_name.frm, is used.
All string comparisons are case independent with case according to ISO-8859-1 Latin1.
LIKE is allowed on numerical columns.
Compare with explicit NULL (column == NULL) is the same as if IS NULL was used (column
IS NULL). This is is done to be consistent with mSQL.
38
SELECT syntax
SELECT [STRAIGHT_JOIN] [DISTINCT | ALL] select_expression,... [INTO
OUTFILE ’file_name’ ...] [ FROM tables... [WHERE where_definition ]
[GROUP BY column,...] [ ORDER BY column [ASC | DESC] ,..] HAVING
where_definition [LIMIT [offset,] rows] [PROCEDURE procedure_name]]
Strings are automatically converted to numbers and numbers to strings when needed (ala perl). If in a
compare operation ((=, <>, <= ,<, >=, >)) either if the arguments are numerical the
arguments are compared as numbers, else the arguments are compared as strings. All string
comparisons are by default done case-independent by ISO8859-1 (The Scandinavian letter set which
also works excellent with English).
select 1 > "6x"; -> 0
A column name does not have to have a table prefix if the given column name is unique.
A select expression may be given an alias which will be column name and can be used when
sorting and grouping or in the HAVING clause.
select concat(last_name,’ ’,first_name) as name from table order by name
In LIKE expressions % and _ may be preceded with ’\’ to skip the wild-card meaning.
A DATE is a string with one of the following syntaxes:
YYMMDD (Year is assumed to be 2000 if YY < 70.)
YYYYMMDD
YY.MM.DD Where ’.’ may be any non numerical separator.
YYYY.MM.DD Where ’.’ may be any non numerical separator.
IFNULL() and IF() returns number or string value according to use.
ORDER and GROUP columns may be given as column names, column alias or column numbers in
SELECT clauses.
The HAVING clause can take any columns or alias in the select_expressions. It is applied last,
just before items are sent to the client, without any optimisation. Don’t use it for items that
should be in the WHERE clause. You can’t write (yet):
SELECT user,MAX(salary) FROM users GROUP BY users HAVING max(salary)>10
Change it to:
SELECT user,MAX(salary) AS sum FROM users GROUP BY users HAVING sum > 10
STRAIGHT_JOIN forces the optimiser to join the tables in the same order that the tables are
given in the FROM clause. One can use this to get a query to be done more quickly if the
optimiser joins the tables in not optimal order. See section EXPLAIN syntax. Get information
about a SELECT. [p 47]
LIMIT takes one or two numerical arguments.
If one argument, the argument indicates the maximum number of rows in a result.
If two arguments, the first argument says the offset to the first row to return, the second is
39
the maximum number of rows.
INTO OUTFILE ’filename’ writes the given set to a file. The file can not exist from before. See
section LOAD DATA INFILE syntax [p 45] .
Functions
A select_expression or where_definition can consist of any expression using the
following functions:
Group functions.
(
) Parenthesis
+
-
*
/ A division by zero results in a NULL.
Bit functions. These have a range of maximum 64 bits because MySQL uses longlong arithmetic.
|
&
BIT_COUNT()
Number of set bits in an argument.
NOT
!
OR
AND
Comparison operators. Returns TRUE (1) or FALSE (0). These functions work for both numbers and
strings.
= Equal
<> Not equal. Synonym: !=
<= Smaller or equal.
< Smaller.
>= Bigger or equal
> Bigger
ISNULL(A)
Returns 1 if A is NULL else 0. Same as ’( A == NULL ’).
A BETWEEN B AND C
A is bigger or equal as B and A is smaller or equal to C. Is the same as (A >= B AND A <= C).
40
String comparison functions.
expr IN (value,...)
Returns 1 if expr is any of the values in the IN list, else it returns 0. If all values are constants,
then all values are evaluated according to the type of expr and sorted. The search for them item is
then done by using a binary search. This means IN is very quick when used with constants in the
IN part.
expr LIKE expr
SQL simple regular expression comparison. Returns TRUE (1) or FALSE (0). With LIKE you
have two wild characters. ’%’ stands for any number of characters, even zero characters. ’_’
stands exactly one character. If you want to search after a ’%’ or a ’_’ you must precede it with
a ’\’ For example the string "Monty was here" is matched by "Monty%", "%Monty ___ h%"
and "%was%".
expr NOT LIKE expr
Returns TRUE (1) or FALSE (0).
expr REGEXP expr
Checks string against extended regular expr.
expr NOT REGEXP expr
Checks string against extended regular expr.
STRCMP()
Returns 0 if the strings are the same. Otherwise return -1 if first argument is smaller according to
sort-order, otherwise it returns 1.
IFNULL(A,B)
If A is not null it returns A, else B.
IF(A,B,C)
If A is true (<> 0 and <> NULL) then return B, else return C.
- Sign
ABS()
SIGN()
Sign of argument. Returns -1, 0 or 1.
MOD()
% Module (like in C). Equivalent with MOD().
FLOOR()
CEILING()
ROUND()
EXP()
LOG()
LOG10()
POW()
SQRT()
PI()
COS()
SIN()
41
TAN()
TAN2()
ACOS()
ASIN()
ATAN()
RAND([integer_expr])
Returns a random float, 0 <= x <= 1.0, using integer_expr as the option seed value.
MIN()
Min value of arguments. Must have 2 or more arguments, else these are GROUP BY functions.
The arguments are compared as numbers.
MAX()
Max value of arguments. Must have 2 or more arguments, else these are GROUP BY functions.
The arguments are compared as numbers.
String functions.
ASCII(string_exp)
Returns the ASCII code value of the leftmost character of string_exp. If string_exp is NULL, it
then returns NULL.
CHAR(num,...)
Returns a string that consist of the characters given by the ASCII code values of the arguments.
NULLS are skipped.
CONCAT()
Concatenates strings. May have more than 2 arguments.
LENGTH()
Length of string. Synomyes: CHAR_LENGTH(), OCTET_LENGTH()
LOCATE(A,B)
Returns position of B substring in A. The first position is 1. Returns 9 if b is not in A.
LOCATE(A,B,C)
Returns position of B substring in A starting at C. Synonym: POSITION(B IN A)
LEFT(str,length)
Gets length characters from beginning of string.
RIGHT(str,right)
Gets length characters from end of string. Synonym: SUBSTRING(A FROM B)
LTRIM(str)
Removes space characters from the beginning of string.
RTRIM(str)
Removes space characters from the end of string.
TRIM([[ BOTH | LEADING | TRAILING] [ A ] FROM ] B)
Returns a character string with all A prefixes and/or suffixes removed from B. If BOTH,
LEADING and TRAILING isn’t used BOTH are assumed. If A is not given, then spaces are
removed.
SOUNDEX(str)
Gets a soundex string from str. Two strings that sound ’about the same’ should have identical
soundex strings. A ’standard’ soundex string is 4 long, but this function returns an arbitrary long
string. One can use SUBSTRING on the result to get a ’standard’ soundex string. All non alpha
characters are ignored in the given string. All characters outside the A-Z range are treated as
vocals.
SUBSTRING(A,B,C)
Returns substring from A starting at B with C chars.
42
SUBSTRING(A FROM B FOR C)
Same as SUBSTRING(A,B,C). This is ANSI SQL 92.
SUBSTRING(A FROM B)
Same as RIGHT(A,B). This is ANSI SQL 92.
SUBSTRING_INDEX(string,delimiter,count)
Returns the substring from ’string’ after ’count’ delimiters. If count is positive the strings are
searched from left else if count is negative the substrings are searched and returned from right.
substring("www.tcx.se",".",2) would return "www.tcx" and
substring("www.tcx.se",".",-2) would return "tcx.se".
REPLACE(A,B,C)
Replaces all occurrences of B in A with C.
REPEAT(string,count)
Repeats string count times. If count <= 0 returns a empty string. If string or count is NULL or
LENGTH(string)*count > max_allowed_size returns NULL.
INSERT(org,start,length,new)
Replaces substring org[start...length] with new. First position in string=1.
LCASE(A)
Changes A to lower case. Synonym: LOWER()
UCASE(A)
Changes a to upper case. Synonym: UPPER()
ENUM(A,a,b,c,d)
Returns 1 if A == a, 2 if A == b. If no match 0 is returned. A,a,b,c,d... are strings.
ELT(N,a,b,c,d,...)
Returns a if N == 1, b if N == 2. a,b,c,d are strings.
FIELD(A,a,b,c,d,...)
Returns index of A in the a,b,c... list. The complement of ELT().
PERIOD_ADD(P:N)
Adds N months to period P (of type YYMM or YYYYMM). Returns YYYYMM.
PERIOD_DIFF(A,B)
Returns months between periods A,B. A and B should be of format YYMM or YYYYMM.
Example: PERIOD_DIFF(9612,199712).
TO_DAYS(DATE)
Changes a DATE to a daynumber. DATE may be a date string, a datetime string, a timestamp([6 |
8 | 14]) or a number of format YYMMDD or YYYYMMDD.
FROM_DAYS()
Changes a daynumber to a DATE.
WEEKDAY(DATE)
Gets weekday for date (0 = Monday, 1 = Tuesday). DATE may be a date string, a datetime string,
a timestamp([6 | 8 | 14]) or a number of format YYMMDD or YYYYMMDD.
CURDATE()
Returns date of today. In form YYYYMMDD or "YYYY-MM-DD" depending on whether
CURDATE() is used in a number or string context. Synonymes: CURRENT_DATE().
CURTIME()
Returns current time in form HHMMSS or "HH:MM:SS", depending on whether CURTIME() is
used in a number or string context. Synonymes: CURRENT_TIME().
43
NOW()
Returns current time. In format YYYYMMDDHHMMSS or "YYYY-MM-DD HH:MM:SS"
depending on whether NOW() is used in a number or string context. Synonymes:
CURENT_TIMESTAMP(), SYSDATE().
UNIX_TIMESTAMP([DATE])
If called without any arguments a unix timestamp (seconds in GMT since 1970.01.01 00:00:00)
is returned. Normally it is called with a timestamp column as an argument in which case it
returns the timestamp. DATE may also be a date string, a datetime string, or a number of format
YYMMDD or YYYMMDD in local time.
FROM_UNIXTIME(unix_timestamp)
Returns a string of the timestamp in YYYY-MM-DD HH:MM:SS or YYYYMMDDHHMMSS
format depending on context.
SEC_TO_TIME(seconds)
Returns the hours, minutes and seconds of the argument in H:MM:SS or HMMSS format
depending on context.
Miscellaneous functions.
DATABASE()
Returns current database name.
USER()
Returns current user name. Synonymes: SESSION_USER() and SYSTEM_USER().
PASSWORD()
Calculates a password string. This must be used to store a password in the ’user’ grant table.
ENCRYPT(string[,salt])
Crypt messsage with the unix crypt() command. The salt should be a string with 2 characters.
LAST_INSERT_ID()
Returns the last automaticly generated value that was set in a auto_increment column. See section
How can I get the unique ID for the last row? [p 83]
FORMAT(nr,NUM)
Formats number to a format like ’#,###,###.##’ with NUM decimals.
count(expr)
Number of rows. count(*) is optimised to return very quickly if no other column is used in the
SELECT.
avg(expr)
Average value of expr.
min(expr)
max(expr)
Minimum/Maximum value of expr. min() and max() may take a string argument and will then
return the minimum/maximum string value.
sum(expr)
Sum of expr.
std(expr)
Standard derivation of expression. This is a extension to ANSI SQL.
bit_or(expr)
The logical OR of all bits in expr. Caclulation done with 64 bits precision.
44
bit_and(expr)
The logical AND of all bits in expr. Caclulation done with 64 bits precision.
MySQL has extended the use of GROUP BY. You can use columns or calculations in the SELECT
expressions which doesn’t appear in the GROUP BY part. This stands for ’any possible value for this
group’. By using this, one can get a higher performance by avoiding sorting and grouping on
unnecessary items. For example, in the following query one doesn’t need to sort on b.name:
SELECT a.id,b.name,COUNT(*) from a,b WHERE a.id=b.id GROUP BY a.id
INSERT syntax
INSERT INTO table [ (column_name,...) ] VALUES (expression,...)
or INSERT INTO table [ (column_name,...) ] SELECT ....
An expression may use any previous column in column_name list (or table if no column name list is
given).
This is used to read rows from a text file, located on the server, at a very high speed. The server-client
protocol doesn’t yet support files over a connection. If you only have the file on the client, use rcp or
ftp to copy it, possibly compressed, to the server before using LOAD DATA INFILE.
To write data to a text file, use the SELECT ... INTO OUTFILE ’interval.txt’ fields
terminated by ’,’ enclosed by ’"’ escaped by ’\\’ lines terminated
by ’\n’ FROM .... syntax.
Normally you don’t have to specify any of the text file type options. The default is a compact text file
with columns separated with tab characters and all rows end with a newline. Tabs, newlines and \
inside fields are prefixed with a \. NULL’s are read and written as \N.
45
FIELDS TERMINATED BY has the default value of \t.
If LINES TERMINATED BY is an empty string and FIELDS TERMINATED BY is not empty then
lines are also terminated with FIELDS TERMINATED BY.
If FIELDS TERMINATED BY and FIELDS ENCLOSED BY both are empty strings (") then this
gives a fixed row format ("not delimited" import format). With a fixed row size NULL values are
outputed as a blank string. If you specify OPTIONALLY in ENCLOSED BY, then only strings are
enclosed in ENCLOSED BY by the SELECT ... INTO statement.
Duplicated ENCLOSED BY chars are removed from strings that start with ENCLOSED BY. For
example: With ENCLOSED BY ’"’:
"The ""BIG"" boss" -> The "BIG" boss
The "BIG" boss -> The "BIG" boss
If ESCAPED BY is not empty then the following characters will be prefixed with the escape
character: ESCAPED BY, ASCII 0, and the first character in any of FIELDS TERMINATED BY,
FIELDS ENCLOSED BY and LINES TERMINATED BY.
If FIELDS ENCLOSED BY is not empty then NULL is read as a NULL value. If FIELDS ESCAPED
BY is not empty then \N is also read as a NULL value.
If REPLACE is used, then the new row will replace all rows which have the same unique key. If
IGNORE is used, the row will then be skipped if there already exist a record with an identical unique
key. If none of the above options are used an error will be issued. The rest of the text file will be
ignored if one gets a duplicate key error.
Fixed size rows (FIELDS TERMINATED BY and FIELDS ENCLOSED BY both are empty)
and BLOB fields.
If some of the separators are a prefix of another.
FIELDS ESCAPED BY is empty and the data contains LINES TERMINATED BY or FIELDS
ENCLOSED BY followed by FIELDS TERMINATED BY.
All rows are read into the table. If a row has too few fields the rest of the fields are set to default
values.
For security reasons the text file must either reside in the database directory or be readable by all.
For more information about the escaped syntax See section Literals. How do you write strings and
numbers? [p 30] .
46
When the LOAD DATA query is done, one can get the following info string with the C API function
mysql_info().
Warnings are incremented for each column which can’t be stored without loss of precision, for each
column which didn’t get a value from the read text line (happens if the line is too short) and for each
line which has more data than can fit into the given columns.
UPDATE syntax
UPDATE table SET column=expression,... WHERE where_definition
All updates are done from left to right. If one accesses a column in the expression update will then use
the current value (a given value or the default value) of the column.
UPDATE persondata SET count=count+1
Gives information about databases, tables or columns. The wild is a LIKE string. FIELDS may be
used as an alias for COLUMNS.
Gives information about how and in which order tables are joined. With the help of EXPLAIN one can
see when one has to add more keys to tables to get a faster select that uses keys to find the records.
You can also see if the optimiser joins the tables in an optimal order. One can force the optimiser to
use a specific join order with the STRAIGHT_JOIN option to select.
system
The table has only 1 record (= system table)
const
The table has at most 1 matching record which will be read at the start of the query. All columns
in this table will be regarded as constants by the rest of the optimiser.
eq_ref
One record will be read from this table for each combination of the previous tables.
47
ref
All records with matching keys will be read from this table for each combination of the previous
tables.
all
A full table scan will be done for each combination of the previous tables.
Gives information about columns. This command is for Oracle compatibility. See section SHOW
syntax. Get information about names of columns. [p 47] Column may be a column name or a string.
Strings may contain wild cards.
Locks tables for this thread. Many threads may have a READ lock on the same table, but one can use
a table with a WRITE lock. One can’t update a table on which one has a read LOCK. When one uses
LOCK TABLES one must lock all tables one is going to use!
LOCK TABLES t READ, t as t2 READ
SELECT * from t,t2;
All tables are automaticly unlocked when one issues another LOCK TABLES or if the connection to
the server is closed.
The used options remain in effect for the whole current session.
SQL_SELECT_LIMIT=value
The maximum number of records to return in any select. If a select has a limit clause it overrides
this statement. The default value for a new connection is ’unlimited’.
SQL_BIG_TABLES= 0 | 1
If set to 1 then all temporary tables are stored on disk based. This will be a little slower, but one
will not get the error The table ### is full anymore for big selects that require big
temporary tables. The default value for a new connection is 0 (use in memory temporary tables).
SQL_BIG_SELECTS= 0 | 1
If set to 1 then MySQL will aborts if one will try to make a select with probably will take a very
long time. This is nice to SELECTS with a wrong WHERE statement. A big query is defined as a
SELECT that will probably have to examine more than max_join_size rows. The default
value for a new connection is 0 (allow all SELECT’s).
48
GRANT syntax. (Compatibility function).
GRANT (ALL PRIVILEGES | (SELECT, INSERT, UPDATE, DELETE,
REFERENCES (column list), USAGE))
ON table TO user,... [WITH GRANT OPTION]
This command doesn’t do anything. It is only in MySQL for compatibility reasons. Privileges in
MySQL is handled with the mysql grant tables. See section How does the privilege system work? [p
26]
This function doesn’t do anything. It is only in MySQL for compatibility reasons. You can create new
index with ALTER TABLE. See section ALTER TABLE syntax [p 37]
This always succeeds. You can drop an index with ALTER TABLE. See section ALTER TABLE
syntax [p 37]
Functions don’t clash with table or column names. (For example ABS is an allowed column name).
The only restriction is that space is not allowed between a function name and the ’(’ when using
functions.
The following are reserved words in MySQL. Most of them (for example) group, are forbidden by
ANSI SQL92 as column and/or table names. A few are because MySQL needs them and is (currently)
using a Yacc parser:
49
action add all alter and
as asc auto_increment between bigint
bit binary blob both by
cascade char character change check
column columns create data databases
date datetime dec decimal default
delete desc describe distinct double
drop escaped enclosed enum explain
fields float float4 float8 foreign
from for full grant group
having ignore in index infile
insert int integer interval int1
int2 int3 int4 int8 into
is key keys leading like
lines limit lock load long
longblob longtext match mediumblob mediumtext
mediumint middleint numeric no not
null on option optionally or
order outfile partial precision primary
procedure privileges read real references
regexp repeat replace restrict rlike
select set show smallint sql_big_tables
sql_big_selects sql_select_limit straight_join table tables
terminated text time timestamp tinyblob
tinytext tinyint trailing to unique
unlock unsigned update usage values
varchar varying with write where
zerofill
The following symbols (from the table above) are disallowed by ANSI SQL but allowed by MySQL
as column/table names. This is because some of theese names are very natural names so a lot of
people has already used them.
ACTION
BIT
DATE
50
ENUM
NO
TEXT
TIME
TIMESTAMP
Go to the first [p 5] , previous [p 26] , next [p 52] , last [p 87] section, table of contents [p 1] .
51
Go to the first [p 5] , previous [p 30] , next [p 57] , last [p 87] section, table of contents [p 1] .
Each release of MySQL has been usable and there has only been problems when users start to use
code from ’the gray zones’. Naturally, outdoor users can’t know what the gray zones are and I hope
this section will clarify those currently known.
We will here try to answer some of the more important questions that seems to concern a lot of people
and clarify some issues. This section has been put together from the information that has come
forward in the mailing list which is very active in reporting bugs.
This is about the 3.21.x version of MySQL. All known and reported bugs are fixed in the latest
version with the exception of the bugs listed in the BUGS file which are things that are ’design’
related.
MySQL is written in multiple layers and different independent modules. Here is a list of the different
modules and how tested each of them are.
52
Query optimiser. Gamma
Some changes in 3.21.
Range optimiser. Alpha
Totally rewritten for 3.21.x
Join optimiser. Gamma
Small changes for 3.21.
GROUP BY, ORDER BY and related function COUNT(). Beta
Rewritten for 3.21 and throughly tested.
Locking. Gamma
This is very system dependent. One some system there is big problems to use standard OS
locking (fcntl). In these case one should run the MySQL demon with the --skip-locking flag.
Known problems are some Linux systems and SUNOS when using NFS mounted file systems.
Linux threads. Gamma
The only found problem is with the fcntl() call, which is fixed by using --skip-locking. Some
people have reported lockup problems with the 0.5 release.
Solaris 2.5+ pthreads. Stable
We use this for all our production work.
MIT threads (Other systems). Beta
No reported bugs since 3.20.15 and no known bugs since 3.20.16. On some system there is
’misfeature’ where some operations are quote slow (a 1/20 second sleep is done between each
query).
Other thread implementions. Alpha
The ports to other systems is very new and may still have bugs, either in MySQL or most often
in the thread implementation itself.
LOAD DATA..., INSERT ... SELECT. Stable
Some people have thought they have found bugs in this but has turned up being
misunderstandings. So check the manual before reporting bugs!
ALTER TABLE. Gamma
Partly rewritten for 3.21.
mysqlperl. Stable
No bugs reported except a lot of compiling and linking problems.
DBD. Beta
Now maintained by Jochen Wiedmann . Thanks!
mysqlaccess. Beta
Written and maintained by Yves.Carlier@rug.ac.be. Thanks!
The Technical Documentation. Beta
It is improving.
MyODBC (uses ODBC SDK 2.5). Beta
It seams to work well with some programs. There is some known problems with Office97.
PowerBuilder doesn’t work yet. Error messages aren’t returned right when using a Microsoft
New ODBC 3.0 driver but this may well be a bug in the Microsoft ODBC 3.0 driver. It isn’t fully
up to ODBC level 2 yet in every regard. (My personal opinion is that the ODBC levels are
defined in such a way that it’s almost impossible to make a simple ODBC driver that works with
all products). Sometimes the MyODBC code must be ported to ODBC 3.0.
TcX provides email support for paying customers, but the MySQL mailing list usually provides
answers to all common questions. Bugs are usually fixed right away with a patch that usually works
and for serious bugs there is almost always a new release.
53
Why are there is so many release of MySQL? Is it because
there are so many bugs?
Well, MySQL is evolving quite rapidly here at TcX and we want to share this with other MySQL
users. We try to make a release when we have a very useful feature that others seem to have a need
for.
We also try to help out users who request features that are easy to implement. We also take note on
what our licensed users want to have and we especially take notes on what our extended email
supported customers want and try to help them out.
No one has to download a new release. The NEWS file will tell you if the new release has something
you really want.
If there is, by any chance, a fatal bug in a release we will make a new release as soon as possible, that
fixes the problem. We would like other companies to do this too :)
The 3.21.x version has had many big changes for portability to a lot of different systems. When the
3.21 release is stable we will remove the alpha/beta suffix and move active development to the 3.22.
Bugs will still be fixed in the stable version. We don’t believe in a complete freeze, as this also leaves
out bug fixes and things that ’must be done’. ’Somewhat freezed’ means that we will maybe add small
things that ’almost surely will not affect anything thats already working’.
isamchk table_name
This finds 99.99 % of all errors. What it can’t find is when only the data file has been corrupted.
isamchk -e table_name
This goes through all data and does a complete check.
isamchk -ei table_name
As the above but it also prints some statistics.
We at TcX run a cron job on all our important tables once a week.
35 0 * * 0 /path/to/isamchk -s /path/to/dbs/*/*.ISM
This prints out any crashed tables so we can go and examine and repair them when needed.
As we haven’t had any unexpected crashed (without hardware trouble) tables for a couple of years
now (this is really true), once a week is more than enough of us.
Of course, whenever the machine has done a reboot in the middle of a update one usually has to check
all the tables that could have been affected. (This is a ’expected crashed table’)
We recommend that to start with one should do a isamchk -s on all updated tables each night until
one gets to trust MySQL as much as we trust it.
54
Naturally, one could add a check to safe_mysql that, if there is an old pid file left after a reboot, it
should check all tables that have been modified the last 24 hours.
The sign of a corrupted table is usually when queries abort unexpectedly and one gets errors like:
In thess cases you have to repair your tables. The isamchk extern utility can usually detect and fix
most things that can go wrong. See section The MySQL table check, optimize and repair program [p
66] .
If you are going to use isamchk on very large files, you should first decide how much memory you
want to give to isamchk. More memory gives more speed. For example, if you have more than 32M
ram, try:
isamchk -O sortbuffer=16M -O keybuffer=16M -O readbuffer=1M
-O writebuffer=1M .....
Part 1; Checking
Check the permissions of the table files. Make them readable for the user running mysqld.
cd to the database directory.
Run ’isamchk *.ISM’ or (’isamchk -e *.ISM’ if you have more time).
You only have to repair those tables that your isamchk gives an error. Use option -s to avoid
unnecessary information.
Part 2; Easy safe repair.
If you get weird errors when checking or repairing, like out of memory or if isamchk
crashes, go to part 3.
Try first ’isamchk -rq table’. This will try to repair the .ISM file without touching the
important data table (.ISD). If the data file (.ISD) contains everything and the delete links
point at the right places in the data file, this should work and the table is fixed. Start
repairing next table.
Make a backup of the data file (table.ISD) before continuing.
Use ’isamchk -r table’. This will remove wrong records and deleted records from the data
file and reconstruct the index (.ISM) file.
If the above fails, use ’isamchk -ro table’. This is a little slower but a crash-safer version of
the above.
Part 3; Hard repair.
This should only happen if the first 16K block in the .ISM file is destroyed, contains wrong
information or if the .ISM is missing.
In this case we have to create a new .ISM file. Do as follows:
55
Move the data file .ISD file to some safe place.
Recreate the .ISM file from the .frm file:
shell> mysql database
mysql> delete from table_name;
mysql> quite
Copy (don’t move) the data file (.ISD) back on the newly created .ISD file
Go back to Part 2. (This shouldn’t be a endless loop). isamchk -rq should now work.
Part 4; Very hard repair.
This can only happen if the descriptor file (.frm) also has crashed. This should never happen,
because the .frm file isn’t written to after the table is created.
Restore the .frm file from a backup and go back to Part 3. You can also restore the .ISM file
and go back to Part 2. In the latter case you should start with ’isamchk -r’.
If you don’t have a backup but know exactly how the table was created, create a copy of the
table in another database and copy the .frm and .ISM file from there to your crashed
database and go back to Part 2;
Go to the first [p 5] , previous [p 30] , next [p 57] , last [p 87] section, table of contents [p 1] .
56
Go to the first [p 5] , previous [p 52] , next [p 65] , last [p 87] section, table of contents [p 1] .
This should result in a list of all mysqld options and configurable variables like the following. See
section How can I change the buffer sizes of mysqld ? [p 61] .
Possibly variables to option --set-variable (-O) are:
back_log current value: 5
join_buffer current value: 131072
key_buffer current value: 1048568
max_allowed_packet current value: 65536
max_connections current value: 90
max_join_size current value: 4294967295
max_sort_length current value: 1024
net_buffer current value: 8192
record_buffer current value: 131072
table_cache current value: 64
tmp_table_size current value: 131072
sort_buffer current value: 2097144
57
Each index file is opened once and the data file is opened once for each concurrently running
thread. For each concurrent thread a table structure, column structures for each column and a
buffer that has the size of 3 * (maximum row length not counting BLOBS) is allocated. A BLOB
uses 5 to 8 bytes +length of blob data.
For each table having BLOBS, a buffer is enlarged dynamically to read in larger BLOB’s. If one
scans a table there will be a allocated buffer as large as the largest BLOB.
All used tables are saved in a cache and used by FIFO. Normally the cache is 64 tables. If a table
has been used by 2 running threads at the same time, there will be 2 entries of the table in the
cache.
A MySQLadmin refresh closes all tables that are not used and marks all used tables to be
closed when the running thread finishes. This will effectively free most used memory.
When running mysqld ps, other programs may report that is takes a lot of memory. This may be
caused by thread-stacks on different memory addresses. For example, the Solaris ps calculates the
unused memory between stacks as used memory. You can verify this by checking available swap with
’swap -s’. We have tested mysqld with commercial memory-leakage detectors so there should not be
any memory leaks.
INDEX(col1, col2) creates a multiple index over the two columns. The key can be seen like a
concatenation of the given columns. If you use INDEX(col1), INDEX(col2) instead of
INDEX(col1,col2) you get two separate keys instead.
SELECT * FROM table WHERE col1=# AND col2=#
In a case of INDEX(col1,col2) the right row(s) can be fetched directly. In a case of INDEX(col1),
INDEX(col2) the optimiser decides which index will find fewer rows and this index will be used to
fetch the rows.
If the table has an index INDEX(col1,col2,col3....) the prefix of this can be used by the optimiser to
find the rows. This means that the above gives you search capabilities on: INDEX(col1) and
INDEX(col1,col2) and INDEX(col1,col2,col3)...
MySQL can’t use a sub part of a key to locate rows through a key.
58
How does MySQL open & close tables?
The cache of open tables can grow to a maximum of table-cache (default 64, changeable with -O
table_cache=#). A table is never closed, except when the cache is full and another thread tries to open
a table or if one uses ’mysqladmin refresh’.
When the limit is reached, MySQL closes as many tables as possible, until the cache size has been
reached or there are no more unused tables. This means that if all tables are in use by some threads,
there will be more open tables than the cache limit, but the extra tables will be closed eventually.
Tables are closed according to last-used order.
A table is opened (again) for each concurrent access. This means that if one has two threads running
on the same table or access the table twice in the same query (with AS) the table needs to be opened
twice. The first open of any table takes 2 file descriptors, each following use of the table takes only
one file descriptor.
59
section LOAD DATA INFILE syntax [p 45] .
When doing many inserts/updates in a row, you can get more speed by using LOCK TABLES on
the tables. ...FROM INFILE... and ...INTO OUTFILE... are atomic so you don’t have
to use LOCK TABLES when using these. See section Lock tables syntax [p 48] .
To check how you are doing, run isamchk -evi on the .ISM file.
Connect: (3)
Sending query to server: (2)
Parsing query: (2)
Inserting record: (1 x size of record)
Inserting keys: (1 x keys)
Close: (1)
Where (number) is proportional time. This does not take into calculation the initial overhead to open
tables (which is done once for each simultaneous running query).
The size of the table slows down the insert of keys with N log N (B-trees).
Brace removal (all unnecessary braces are removed). ((a AND b) AND c OR (((a AND
b) AND (c AND d)))) -> (a AND b) OR (a AND b AND c AND d)
Constant folding. (a<b AND b=c) AND a=5 -> b>5 AND b=c A=5
Constant condition removal (needed because of constant folding). (b>=5 AND b=5) OR
(b=6 and 5=5) or (B=7 and 5=6) -> B=5 or B=6
All constant expressions used by keys are evaluated only once.
Return zero rows if impossible select.
HAVING is merged with WHERE if one doesn’t use GROUP BY or group functions.
For each sub join a simpler WHERE is constructed to get a fast WHERE evaluation for each sub
join and also to skip records as soon as possible.
Find all keys that may be used. Use the key which finds least records. A key is used for the
following cases: =, >, >=, <, <=, BETWEEN and a LIKE with a character prefix like
’something%’.
Remove keys that don’t span all AND levels.
have all preceding key_parts specified.
key = 1 or A = 10 -> NULL (can’t use key.)
60
key = 1 or A = 10 and key=2 -> key = 1 OR key = 2
key_part_1 = const and key_part_3 = const -> key_part_1 = const
Read all constant tables. A constant table is:
1. A table with 0 or 1 record.
2. A table which uses only other const tables and constants on a full unique key.
const_table.key = constant const_table.key_part_1 =
const_table2.column and const_table.key_part_2 = constant
Find the best join combination to join the tables, by trying all possibilities :(. If all columns in
ORDER BY and in GROUP comes from the same table, then this table is preferred first when
joining.
If there is a order clause and a different group clause or if the order or group contains columns
from other tables than the first table in the join cue, a temporary table is created.
For each table use a ranged key, if possible, to read records. Each table index is queried and if
there exists a key range that spans < 30% of the records then a key is used. If no such key can be
found a quick table scan is used.
Before each record is output-ed, skip those that match the HAVING clause.
61
--socket=... Socket file to use for connection
-V, --version output version information and exit
The key_buffer is shared by all threads, the rest are allocated when needed.
mysqld demon starts with a cd to ’mysql-data-dir’. After this, mysqld-data-dir is changed to ’./’
(current dir). All paths (databases, pid file, and log file) are prefixed with ’./’.
--skip-locking disables file locking between SQL requests. If this is used then the following can
happen:
If mysqld or the machine crashes a table has a higher risk of being corrupted. Tables should at
least be checked with isamchk *.ISM after a crash.
One MUST flush all tables with mysqladmin refresh before one tries to check/repair tables
with isamchk. (isamchk -d table_name is always allowed).
The --skip-locking is default when compiling with MIT threads. This is because flock() isn’t
fully support by MIT threads on all platforms.
62
For example, for 200 open connections one should have a table cache of at least 200 * (max_number
of tables in join).
Of course MIT threads may slow down everything a bit, but for key based selects a select is usually
down in one time frame so there shouldn’t be a mutex locking/thread juggling.
If updates are a problem, updates can be delayed and then do many updates in a row later. Many
updates done in a row are much quicker than one at a time.
If the problem is with MIT threads and one is using FreeBSD x.x. upgrading to FreeBSD 3.0.(or
higher:) should help. This gives a possibility to use sockets (quicker than the current TCP/IP with MIT
threads) and the thread package is much more integrated.
You can check the format used in a table with isamchk -d.
63
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 isamchk -ed. All links
may be removed with isamchk -r.
3. Compressed tables (this is only with UNIREG/pack_isam)
Read only tables.
Takes very little disk space. Minimises disk usage.
Each record is compressed separately (very little access overhead).
Can handle fixed or dynamic length records, but no BLOBs.
Can be uncompressed with isamchk.
As MySQL is multithreaded it may have many queries on the same table at once. To minimise the
problem with two threads having different states on the same file, I open the table again for each
concurrent thread. This takes some memory and one extra file descriptor for the data file. The index
file descriptor is shared all threads.
Go to the first [p 5] , previous [p 52] , next [p 65] , last [p 87] section, table of contents [p 1] .
64
Go to the first [p 5] , previous [p 57] , next [p 75] , last [p 87] section, table of contents [p 1] .
MySQL Utilites
Overview of the different MySQL programs
All MySQL client that communicates with the server uses the following environment variables:
Name Description
MYSQL_UNIX_PORT The default socket. Used with ’localhost’.
MYSQL_TCP_PORT The default TCP port.
MYSQL_PWD The default password.
mysql
A SQL shell (with gnu readline). Supports interactive use or as a non interactive query tool.
When used interactively result is given in a ascii-table format, but when used as a filter the result
is a tab-separated output.
mysqlaccess
Script to check the privileges for a host, user and database combination.
mysqladmin
Administration utility. Create/Drop of databases, reload (read new users) and refresh (flush tables
to disk, reopen log files). Also gives version and process info.
mysqld
The SQL daemon. This should always be running.
mysqldump
Dump a MySQL database into a file with SQL statements or tab separated text files. Enchanted
freeware originally by Igor Romanenko.
mysqlimport
Imports text-file(s) into respective table(s). Can use all formats supported by LOAD DATA
INFILE. See section LOAD DATA INFILE syntax [p 45]
mysqlshow
Shows information about database, tables, fields and keys.
mysqlbug
This script should always be used when filing a bug report to the MySQL list.
mysql_install_db
Creates the MySQL grant tables with default privileges. This is usually only executed when
installing the first MySQL release on a new system.
isamchk
Check, optimise and repair MySQL tables.
make_binary_release
Makes a binary release of a compiled MySQL. This could be sent by ftp to
www.tcx.se/pub/mysql/Incoming for the convenience of other MySQL users.
msql2mysql
A shell script to convert a mSQL program to MySQL. Doesn’t handle all cases but gives a good
start when converting.
65
replace
Binary used for msql2mysql. Utility program to change strings in place in files or on stdin. Uses
a finite state machine to match longer strings first. Can be used to swap strings, for example
’replace a b b a -- files’ swaps ’a’ and ’b’ in the given files.
safe_mysqld
Starts the mysqld demon with some safety features. Restarts on error and has logging of runtime
information to a log file.
isamchk -d table_name
isamchk in ’describe mode’. If one uses ’--skip-locking’ isamchk may report an error for a table
that is updated while isamchk runs, but there isn’t any risk of destroying data. A short form.
ISAM file: company.ISM
Data records: 1403698 Deleted blocks: 0
Recordlength: 226
Record format: Fixed length
table description:
Key Start Len Index Type
1 2 8 unique double
2 15 10 multip. text packed stripped
3 219 8 multip. double
4 63 10 multip. text packed stripped
5 167 2 multip. unsigned short
6 177 4 multip. unsigned long
7 155 4 multip. text
8 138 4 multip. unsigned long
9 177 4 multip. unsigned long
193 1 text
66
Key Start Len Index Type Root Blocksize Rec/key
1 2 8 unique double 15845376 1024 1
2 15 10 multip. text packed stripped 25062400 1024 2
3 219 8 multip. double 40907776 1024 73
4 63 10 multip. text packed stripped 48097280 1024 5
5 167 2 multip. unsigned short 55200768 1024 4840
6 177 4 multip. unsigned long 65145856 1024 1346
7 155 4 multip. text 75090944 1024 4995
8 138 4 multip. unsigned long 85036032 1024 87
9 177 4 multip. unsigned long 96481280 1024 178
193 1 text
ISAM file
Name of isam file.
Isam-version
Version of isam format. Currently always 2.
Creation time
When was the data file created.
Recover time
When was the index/data file last reconstructed.
Data records
How many records/rows.
Deleted blocks
How many deleted blocks still have reserved space. See section How to repair tables. [p 55]
.
Datafile: Parts
For dynamic record format this shows how many data blocks there are. For a optimised table
without splits this is the same as Data records.
Deleted data
How many bytes of non reclaimed deleted data.
Datafile pointer
How many bytes the datafile pointer has. It is usually 2, 3 or 4 bytes. Most tables manage
with 2 bytes but this cannot be controlled from MySQL yet. For fixed tables this is a record
address. For dynamic tables this is a byte address.
Keyfile pointer
How many bytes has the datafile pointer. It is usually 1, 2 or 3 bytes. Most tables manage
with 2 bytes but this is calculated automatically by MySQL. It is always a block address.
Max datafile length
How long (in bytes) can the table’s data file (.ISD) get.
Max keyfile length
How long (in bytes) can the table’s key file (.ISM) get.
Recordlength
How much space does each record/row take.
Record format
Which format does each record/row have. This example uses Fixed length.
table description
A list of all keys in the table. For each key some low level information is presented.
Key
This key’s number.
Start
Where in the record/row does this index-part start.
67
Len
How long is this index-part. For packed numbers this should always be the full length
of the field. For strings it may be shorter than the full length.
Index
unique or multip.. If one value can exist multiple times in this index.
Type
What data-type does this index part have. This is a C data-type with the options packed,
stripped or empty.
Root
Address of the root index block.
Blocksize
The size of each index block. This is by default 1024 but may be changed a compile
time.
Rec/key
This is a statistical value used by the optimiser. It tells how many records there are per
value for this key. A unique key always has a value of 1. This may be updated after a
table is loaded (or greatly changed) with isamchk -a. If this is not updated at all, a
default value of 30 is given.
The 9th key is a multiple part key with two parts.
isamchk -eis table_name
Shows only the most important information from a table. Slow since it must read the whole table.
Checking ISAM file: company.ISM
Key: 1: Keyblocks used: 97% Packed: 0% Max levels: 4
Key: 2: Keyblocks used: 98% Packed: 50% Max levels: 4
Key: 3: Keyblocks used: 97% Packed: 0% Max levels: 4
Key: 4: Keyblocks used: 99% Packed: 60% Max levels: 3
Key: 5: Keyblocks used: 99% Packed: 0% Max levels: 3
Key: 6: Keyblocks used: 99% Packed: 0% Max levels: 3
Key: 7: Keyblocks used: 99% Packed: 0% Max levels: 3
Key: 8: Keyblocks used: 99% Packed: 0% Max levels: 3
Key: 9: Keyblocks used: 98% Packed: 0% Max levels: 4
Total: Keyblocks used: 98% Packed: 17%
Keyblocks used
How many percent of the keyblocks are used. Since this table has just been reorganised with
isamchk the values are very high (very near theoretical maximum).
Packed
MySQL tries to pack keys with a common suffix. This can only be used for
CHAR/VARCHAR/DECIMAL keys. For long strings like names, this can significantly reduce
the space used. In the above example the 4 key is 10 characters long and gets a 60%
reduction in space.
68
Max levels
How deep is the btree for this key. Large tables with long keys get high values.
Records
How many rows does the table have.
M.recordlength
Average recordlength. For fixed tables this is the recordlength.
Packed
MySQL strips spaces from the end of strings. How many percent did we save by doing this.
Recordspace used
How many percent of the datafile is used.
Empty space
How many percent of the datafile is unused.
Blocks/Record
How many blocks are there per record. This is always 1 for fixed format tables. This value
should stay as close to 1.0 as possible. If it gets to great you can reorganise the table with
isamchk. See section How to repair tables. [p 55] .
Recordblocks
How many blocks are used. For fixed format, this is the same as the number of records.
Deleteblocks
How many blocks are deleted.
Recorddata
How many bytes of actual user data there are in the datafile.
Deleted data
How many bytes of deleted data there are in the datafile.
Lost space
If a record is updated to a shorter length some space is lost. This is the sum of all such
losses.
Linkdata
When the dynamic format is used, blocks are linked with pointers (length 4-7 bytes). This is
the sum of all such pointers.
isamchk -eiv table_name
Same as above but tells you what it is being done.
Checking ISAM file: company.ISM
Data records: 1403698 Deleted blocks: 0
- check file-size
- check delete-chain
index 1:
index 2:
index 3:
index 4:
index 5:
index 6:
index 7:
index 8:
index 9:
No recordlinks
- check index reference
- check data record references index: 1
Key: 1: Keyblocks used: 97% Packed: 0% Max levels: 4
- check data record references index: 2
Key: 2: Keyblocks used: 98% Packed: 50% Max levels: 4
- check data record references index: 3
Key: 3: Keyblocks used: 97% Packed: 0% Max levels: 4
- check data record references index: 4
69
Key: 4: Keyblocks used: 99% Packed: 60% Max levels: 3
- check data record references index: 5
Key: 5: Keyblocks used: 99% Packed: 0% Max levels: 3
- check data record references index: 6
Key: 6: Keyblocks used: 99% Packed: 0% Max levels: 3
- check data record references index: 7
Key: 7: Keyblocks used: 99% Packed: 0% Max levels: 3
- check data record references index: 8
Key: 8: Keyblocks used: 99% Packed: 0% Max levels: 3
- check data record references index: 9
Key: 9: Keyblocks used: 98% Packed: 0% Max levels: 4
Total: Keyblocks used: 9% Packed: 17%
Of course, all future updates to pack_isam is included in the price. pack_isam may at some time
be included as standard when we get some kind of turnover for MySQL.
pack_isam works by compressing each column in the table separately. The information needed to
decompress is read into memory when the table is opened. This gives a much better performance
when accessing individual records as one only has to uncompress exactly one record, not a much
larger disk block like when using stacker on MSDOS.
MySQL uses memory mapping (mmap) on compressed tables and falls back to normal read/write file
usage if mmap did not work.
70
Fixing these limitations is on our TODO but with low priority.
pack_isam options:
> pack_isam --help
pack_isam Ver 5.0 for SOLARIS 2.5 on SPARCstation
Copyright (C) 1994-1997 TcX AB & Monty Program KB & Detron HB.
This is not free software. You must have a license to use this program
This software comes with ABSOLUTELY NO WARRANTY
Typical run:
(/my/monty/tmp) ls -l station.*
-rw-rw-r-- 1 monty my 994128 Apr 17 19:00 station.ISD
-rw-rw-r-- 1 monty my 53248 Apr 17 19:00 station.ISM
-rw-rw-r-- 1 monty my 5767 Apr 17 19:00 station.frm
table description:
Key Start Len Index Type Root Blocksize Rec/key
1 2 4 unique unsigned long 1024 1024 1
2 32 30 multip. text 10240 1024 1
71
7 32 30
8 62 35
9 97 35
10 132 35
11 167 4
12 171 16
13 187 35
14 222 4
15 226 16
16 242 20
17 262 20
18 282 20
19 302 30
20 332 4
21 336 4
22 340 1
23 341 8
24 349 8
25 357 8
26 365 2
27 367 2
28 369 4
29 373 4
30 377 1
31 378 2
32 380 8
33 388 4
34 392 4
35 396 4
36 400 4
37 404 1
38 405 4
39 409 4
40 413 4
41 417 4
42 421 4
43 425 4
44 429 20
45 449 30
46 479 1
47 480 1
48 481 79
49 560 79
50 639 79
51 718 79
52 797 8
53 805 1
54 806 1
55 807 20
56 827 4
57 831 4
(/my/monty/tmp) ls -l station.*
72
-rw-rw-r-- 1 monty my 127874 Apr 17 19:00 station.ISD
-rw-rw-r-- 1 monty my 55296 Apr 17 19:04 station.ISM
-rw-rw-r-- 1 monty my 5767 Apr 17 19:00 station.frm
table description:
Key Start Len Index Type Root Blocksize Rec/key
1 2 4 unique unsigned long 10240 1024 1
2 32 30 multip. text 54272 1024 1
73
40 413 4 no zeros 2 9
41 417 4 allways zero 2 9
42 421 4 no zeros 2 9
43 425 4 allways zero 2 9
44 429 20 no empty 3 9
45 449 30 no empty 3 9
46 479 1 14 4
47 480 1 14 4
48 481 79 no endspace, no empty 15 9
49 560 79 no empty 2 9
50 639 79 no empty 2 9
51 718 79 no endspace 16 9
52 797 8 no empty 2 9
53 805 1 17 1
54 806 1 3 9
55 807 20 no empty 3 9
56 827 4 no zeros, zerofill(2) 2 9
57 831 4 no zeros, zerofill(1) 2 9
Go to the first [p 5] , previous [p 57] , next [p 75] , last [p 87] section, table of contents [p 1] .
74
Go to the first [p 5] , previous [p 65] , next [p 76] , last [p 87] section, table of contents [p 1] .
1. Add one line in sql_lex.cc defining the function name in the sql_functions array.
2. Add two lines in sql_yacc.y. On defines the preprocessor symbol yacc can define (this should be
added at the beginning of the file). Then define the function parameters and create an ’item’ with
these parameters. Check, for example, all occurrences of SOUNDEX in sql_yacc.y
3. In item_func.h declare a class inheriting from Item_num_func or Item_str_func depending on
whether your function returns a number or a string.
4. In ‘item_func.cc’ add: double *Item_func_newname::val() If you are defining
a number function or String *Item_func_newname::Str(String *str) If you are
defining a string function.
5. You should probably also define the following function: void
Item_func_newname::fix_length_and_dec() This should at least calcutate
max_length based on the given arguments. max_length is the maximal number of chars the
function may return. If the function can’t return a NULL, one should set maybe_null = 0.
1. For string functions the ’String *str’ argument provides a string buffer that may be used to hold
the result.
2. A string function should return the string that holds the result.
3. All current string functions tries to avoid to alloc any memory unless absolutely necessary!
Go to the first [p 5] , previous [p 65] , next [p 76] , last [p 87] section, table of contents [p 1] .
75
Go to the first [p 5] , previous [p 75] , next [p 78] , last [p 87] section, table of contents [p 1] .
ODBC
Which operating systems does MySQL ODBC support?
MySQL ODBC is a 32 bit ODBC (2.50) level 0 for Windows95 and NT. We hope somebody will port
it to Windows 3.x.
To give some light about any problem we would like to have the log file from the ODBC manager (the
log you get when requesting logs from ODBCADMIN) and a MYODBC log.
Program Comment
Wants a primary key and a timestamp in each record to allow updates. Fails if
Access
comparing with single floats.
Excel Works.
odbcadmin Test program for ODBC.
Delphi One must use DBE 3.2 or newer.
Tested with BDE 3.0. The only known problem is that when the table schema changes,
C++Builder query fields are not updated. BDE however does not seem to recognise primary keys,
only the index PRIMARY, though this has not been a problem.
76
1. Use the IP.
2. Add a file lmhosts with the following info: ip hostname For example: 194.216.84.21 my
3. Configure the PC to use DNS.
These are default values to be given when prompting for a Driver connect. You don’t have to give
’server’, ’user’ or ’password’ in this screen. If port is not given the default port (3333) is used.
When connection to a ODBC source you have the option to change the server, user, password and
port.
Go to the first [p 5] , previous [p 75] , next [p 78] , last [p 87] section, table of contents [p 1] .
77
Go to the first [p 5] , previous [p 76] , next [p 81] , last [p 87] section, table of contents [p 1] .
Problems
Why do I get ’Access denied’?
Have you installed the MySQL grant tables with the script ’mysql_install_db’? Test by executing
’mysql -u root test’. This should not give an error. You can also check if you have a file
’user.ISD’ in the mysql database directory (ordinary install_dir/var/mysql/user.ISD).
Remember that you have to do ’mysqladmin reload’ each time you change the grant tables.
Otherwise the old tables are still used!
For testing, you should start the mysqld demon with the --without-grant-tables option.
Now you can change the MySQL grant tables and use the script mysqlaccess to check if your
grants works. mysqladmin reload tells the mysqld demon to start using the new grant
tables.
Even if you have access problems with perl, python, or ODBC, always test your privilege
problems with mysql -u user database or mysql -uuser -ppassword
database.
If you get the error ’Access denied’ when trying to connect to the database with mysql -u
user database then you have a problem with the ’user’ table. Check this by doing mysql
-u root mysql and select * from user. You should get an entry with ’hostname’ and
’user’ matching your computers hostname and your username. If the client and the server is
running on the same host and you haven’t used the --host option to mysql and you are not
using MIT threads, ’localhost’ is a synonym for your hostname.
The ’Access denied’ error message will tell you who you are trying to log in as, from which host
you are trying to log in from and if you was using a password or not. You should normally have
one entry in the user table that exactly matches your host and user, exactly as given in the error
message.
If mysql -u root test works but mysql -h your_hostname -u root test
gives ’Access denied’ then you don’t have the right name for your host in the user table. For
example if you have an entry with host ’tcx’ in the ’user’ table, but your DNS tells MySQL that
your hostname is ’tcx.subnet.se’ then the entry will not work. Test by adding a record with the IP
of your host in the ’user’ table. You can, natuarally, also add a host with a wildcard (for example
’tcx%’) in the ’user table’ (but using hostnames ending with % is pretty insecure).
When using MIT threads, localhost is never used. All connections to the mysqld demon is done
by TCP IP and you must have your real hostname in ’user’ even if you are running the client on
the same host as the server.
If you get the error ’Access to database denied’ then you have a problem with the db table. If the
used entry in the db table has an empty hostname, check also the corresponding entry in the
’host’ table.
If mysql -u user database works on the server machine, but mysql -u host -u
user database doesn’t work on another client machine, then you don’t have the client
machine in the ’user’ or the ’db’ table.
If you can’t get password to work, remember that passwords must be inserted with the
PASSWORD function. See section A example of permission setup. [p 29]
If mysql -u user test works but mysql -u user other_database doesn’t work,
you don’t have the other_database in the ’db’ table.
78
If you get ’Access to database denied’ when using the SELECT ... INTO OUTFILE or
LOAD DATA SQL commands then you probably don’t have the file_priv privilege set for you in
the user table.
If everything else fails, start the mysqld demon with: --debug=d,general,query. This
will print info about the host and user that tries to connect and also information about each
command issued. See section How to debug MySQL [p 25] .
If you have any other problems with the MySQL grant tables and feel you must post the problem
to the list, always add a dump of the MySQL grant tables. You can dump the tables with the
’mysqldump mysql’ command. Post your problem with the mysqlbug script.
See section How does the privilege system work? [p 26]
At this point, your mysqld process would be running fine and dandy as user ’USER’. One thing hasn’t
changed though - the access permissions. By default (right after running the permissions table install
script), only user ’root’ has access permission to the database. Unless you have changed that, it’s still
true. This shouldn’t stop you from accessing MySQL when you’re logged in under a user other than
root, just specify -u root to the client program. Note that accessing MySQL as root, by supplying -u
root in the command line, doesn’t have ANYTHING to do with MySQL running as root, as a user or
as anyone else. The access permissions and userbase of MySQL are completely separate from the
UNIX users. The only connection to the UNIX users us if you don’t use the -u option to clients. In this
case the client will try to login into MySQL with your UNIX login name. If your UNIX box itself
isn’t secured, you should probably at least put a password on the root users in the MySQL access
tables, since any johndoe user can run ’mysql -u root dbname’ and do whatever he likes.
79
Problems using DATE fields.
The format of DATE is ’YYYY-MM-DD’. Actually nothing else is allowed (ANSI SQL). One should
use this format to update or in the WHERE clause, ie select * from table_1 where idate >=
’1997-05-05’;
As a convenience, MySQL automatically converts the date to a number if used in a number context. It
is also smart enough to allow a ’relaxed’ string form when updating and in a WHERE with a compare
to a TIMSTAMP, DATE or a DATETIME field.
Go to the first [p 5] , previous [p 76] , next [p 81] , last [p 87] section, table of contents [p 1] .
80
Go to the first [p 5] , previous [p 78] , next [p 87] , last [p 87] section, table of contents [p 1] .
81
Returns ID generated for
int mysql_insert_id(MYSQL *mysql)
AUTO_INCREMENT field.
MYSQL_RES *mysql_list_dbs(MYSQL *mysql, const
Return maching database names.
char *wild)
MYSQL_RES *mysql_list_fields(MYSQL *mysql,
Return maching field names.
const char *table, const char *wild)
MYSQL_RES *mysql_list_processes(MYSQL *mysql) Get a list of the current server threads.
MYSQL_RES *mysql_list_tables(MYSQL *mysql,
Return maching table names.
const char *wild)
Return the number of columns in a result
int mysql_num_fields(MYSQL_RES *result)
set.
int mysql_num_rows(MYSQL_RES *result) Returns the number of rows in result set.
int mysql_query(MYSQL *mysql, const char *query) Executes a SQL query.
int mysql_real_query(MYSQL *mysql, const char Executes a SQL query with length
*query, uint length) information.
Reload the user permissions table in the
int mysql_reload(MYSQL *mysql)
server.
int mysql_select_db(MYSQL *mysql, const char *db) Connect to a database.
int mysql_shutdown(MYSQL *mysql) Shut down the database server.
char *mysql_stat(MYSQL *mysql) Return server status in a string.
MYSQL_RES *mysql_store_result(MYSQL *mysql) Reads a result set to the client.
MYSQL_RES *mysql_use_result(MYSQL *mysql) Initiate a dynamic result set for each row.
1. Malloc failure.
2. The data couldn’t be read (Error on connection).
3. The statement was a statement which never returns data (INSERT or UPDATE or DELETE).
You can always check if the statement should have given a result by checking that
mysql_num_columns(MYSQL *) isn’t 0. If this is 0 the last query was a statement that does not
return values INSERT, DELETE....
82
What results can I get from a query?
mysql_affected_rows(MYSQL *) returns the number of affected rows in the last query when
doing an INSERT, UPDATE or DELETE. Except, if DELETE is used without a where clause then the
table is truncated which is much faster!. In this case it returns records affected as zero.
mysql_insert_id(MYSQL *) returns the given ID of the last query when inserting a row into a
table with a AUTO_INCREMENT key. See section How can I get the unique ID for the last row? [p 83]
Some queries, LOAD DATA INFILE... and INSERT INTO ... SELECT ..., return
additional info. The result is returned in mysql_info(MYSQL *). mysql_info() returns a null
pointer if there is no additional information.
The last value is also stored in the server and can be retrieved with the LAST_INSERT_ID()
function.
You can check if an auto_increment key is used by the following code. This also checks if the query
was a insert with a auto_increment key.
if (mysql_error(MYSQL)[0] == 0 &&
mysql_num_fields(MYSQL_RESULT) == 0 &&
mysql_insert_id(MYSQL) != 0)
used_id = mysql_insert_id(MYSQL);
or even
83
mysql_use_results reads the result directly from the server without storing it in a local differ.
This is somewhat faster and uses much less memory. One shouldn’t use mysql_use_results if
there is a lot of processing being done for each row at the client side, or if the output is sent to a screen
on which the user may do a ^S (stop scroll). Doing this would tie up the server and then other threads
can’t update the used tables. One can’t use mysql_data_seek when using
mysql_use_result.
This means that on your system you have to include the math library (-lm) last in the compile/link
line.
The standard client libraries are not compiled with the thread options.
To get a thread safe client use the -lmysys, -lstring and -ldbug libraries and net_serv.o that the server
uses.
When using a threaded client I think one can have great use of the thr_alarm.c routine. If you are using
the mysys routines, the only thing one has to remember is to call my_init() first!
You may get some errors because of undefined symbols when linking the standard client as the
pthread libraries are not included by default.
Two treads can’t use the same handle (returned by mysql_connect()) at the same time, even if two
threads can use different MYSQL_RES handles that was created with mysql_store_result().
84
When using a threaded client one can have great use of the thr_alarm.c routine. If you are using the
mysys routines, the only thing one has to remember is to call my_init() first!
User threads in a single process; Thread switching is managed with alarms and the threads library
manages all not thread- safe functions with locks. Read, write and select are usually managed
with a thread-specific select that switches to another thread if the running threads have to wait for
data. If the user thread packages are integrated in the standard libs (FreeBSD and BSDI threads)
the thread package requires less overhead than thread packages that have to map all unsafe calls
(MIT-threads, FSU-threads and RTS threads). In some environments (for example SCO), all
system calls are thread- safe so the mapping can be done very easily (FSU-threads on SCO).
Downside: All mapped calls take a little time and it’s quite tricky to be able to handle all
situations. There are usually also some system calls that are not handled by the thread package
(like MIT-threads and sockets). Thread scheduling isn’t always optimal.
User threads in separate processes; Thread switching is done by the kernel and all data is shared
between threads. The thread package manages the standard thread calls to allow sharing data
between threads. Linuxthreads is using this method. Downside: Lots of processes. Thread
creating is slow. If one thread dies the rest are usually left hanging and one has to kill them all
before restarting. Thread switching is somewhat expensive.
Kernel threads; Thread switching is handled by the thread library or the kernel and is very fast.
Everything is done in one process but ’ps’ may on some systems show the different threads. If
one thread aborts the whole process aborts. Most system calls are threadsafe and should require
very little overhead. Solaris, HPUX, AIX and OSF1 has kernel threads.
In some systems kernel threads are managed by integrating user level threads in the system libraries.
In such cases, the thread switching can only be done by the thread library and the kernel isn’t really
’thread aware’.
DBD::mysql
85
MySQL Python API’s
Go to the first [p 5] , previous [p 78] , next [p 87] , last [p 87] section, table of contents [p 1] .
86
Go to the first [p 5] , previous [p 81] , next, last section, table of contents [p 1] .
Performance.
For a true comparison of speed so the growing MySQL benchmarks suite. It is meant to be a
benchmark that will tell any user which SQL is good at what. Because of no thread creation
overhead, small parser, few features and simple security mSQL should be quicker at:
Test that do a lot of connect/disconnect with a very simple query.
Inserts into very simple tables with few fields and keys.
CREATE TABLE and DROP TABLE.
SELECT one something that isn’t a key. (A table scan is very easy)
As these operations are so simple, it is hard to be better at them when you have a higher start
overhead. After the connection is established MySQL should perform much better. MySQL on
the other hand is much faster than mSQL and most other SQL implementions on the following:
Retrieving large results (MySQL has a better, faster and safer protocol)
Tables with variable length strings since MySQL has more efficent handling and can have
keys on varchars.
Handling tables with many fields (columns).
Handling tables with large record lengths.
SELECT with many expressions.
SELECT on large tables.
Handle many connections at the same time. MySQL handles with multiple threads. mSQL
will take care of one connection at a time. This problem only exists on MySQL if you make
long update statements (like updating the whole table) and even in those cases other threads
can continue to work with other tables.
Joins (I have seen speed differences of 50 times on this one).
ORDER BY and GROUP BY.
DISTINCT.
Using TEXT or BLOB columns.
Disk space efficiency
That is, how small can you make your tables. MySQL has very precise types so that use can
create tables that take very little space. An example of a useful MySQL datatype is the
mediumint that is 3 bytes long. If you have 10.000.0000 records even saving one byte per record
is very important. Since mSQL2 only has 4 types (char,text,int,real) it is hard to get small tables.
Stability
This is harder to judge objectively. For MySQL stability see See section How stable is MySQL?
[p 52] . We have no experience with mSQL stability so we can not say anything about that.
Price
Another important issue is of course the license. MySQL has a more flexible license than mSQL
and is also cheaper than mSQL. Remember to at least consider paying for a license or email
support for whatever product you choose to use. If you sell a product with MySQL you are of
87
course required to get a license for this.
Perl interfaces
MySQL has basically the same interfaces to perl as mSQL with some added features.
JDBC (Java)
MySQL has a java interface by GWE technologies that has been improved by Xiaokun Kelvin
ZHU. We know that mSQL has one but we have too little experience with it to compare.
Rate of development
MySQL has a very small team of developers, but we are quite use to coding C and C++ very
rapidly. Since threads, functions, group by and so on are still not implemented in mSQL, it has a
lot of catching up to do. To get some perspective on this you can view the mSQL HISTORY file
for the last year and compare it with MySQL NEWS file. It should be pretty obvious which one
has developed most rapidly.
Utility programs
Both mSQL and MySQL has a lot of interesting third party tools. Since it is very easy to port
upwars (mSQL -> MySQL) MySQL has almost all interesting mSQL applications. MySQL
comes with a simple msql2mysql program that fixes the different spelling of the most used
functions. A conversion of a client program from mSQL to mySQL usually takes a couple of
minutes.
The procedure:
1. Run the shell script msql2mysql on the source. This needs the binary program replace, which is
distributed with MySQL.
2. Compile
3. Fix all compiler errors:
88
There are enough differences that it is impossible (at least not easy) to support both.
We don’t think it makes sense to give a full specification of the connection protocol as we have plans
to optimize this in the near future.
89
SELECT COUNT(*) FROM table_name
mSQL
Does not support GROUP BY yet.
How do I search independent of character case?
MySQL
LIKE is always case independent. If possible MySQL uses indexes if the like argument
doesn’t start with a wild-card.
mSQL
Use CLIKE.
How do I search with regular expressions?
MySQL
Use REGEXP or RLIKE. The syntax should be basically POSIX.
mSQL
Use RLIKE.
What are the differences in the WHERE statement?
MySQL
MySQL does everything according to mathematical priorities (AND is evaluated before
OR). To get mSQL behaviour in MySQL, use brackets: select * from table
where a=1 and b=2 or a=3 and b=4 -> select * from table where
(a=1 and (b=2 or (a=3 and (b=4)))).
mSQL
Evaluates everything from left to right. That means that some logical calculation with more
that 3 arguments can not be expressed.
Qualifying column names
MySQL
If a column name is unique you do not have to use the full qualifier.
mSQL
When using more than one table in a select you must use full table qualifiers.
Aliasing
MySQL
Has table and column aliasing.
mSQL
Has table aliasing.
Insert/update with calculations.
MySQL
Full calculation support. In a insert you may use values of preceding columns.
mSQL
Only insert update with constants.
Which formulas may be used in the select statement
MySQL
Too many to print here. See section SELECT syntax [p 39] .
mSQL
No functions are supported yet.
SQL HAVING clause.
MySQL
Supported, but can only use calculation on the selected columns. To select on a calculated
value one must use a column alias. Ex: SELECT COUNT(*) AS id_count,id FROM
groups GROUP BY id HAVING id_count > 10.
90
mSQL
Not supported.
Access Control
MySQL
Has tables to store grant options per user, host and db. See section How does the privilege
system work? [p 26]
mSQL
Has a file ‘mSQL.acl’ where you can grant read/write privileges for users.
Threads
MySQL
Is multi-threaded. Each connection has it is own thread, which means that none of them has
to wait for the other (unless a data-modifying query is executed).
mSQL
All other connections have to wait until the first, doesn’t matter whether the query is long or
short, is executed and finished. After that the next connection can be served, while the others
wait again, etc.
Speed
MySQL is significantly quicker on complex selects than mSQL.
This will make it easier to see what goes wrong. Distinct may also be a lot slower than a normal select.
91