MySQL is an open-source Relational Database Management System (RDBMS) that is developed and supported by Oracle Corporation.
MySQL is supported on a large number of platforms, including Linux variants, OS X, and Windows. It also has APIs for a large number of languages, including C, C++, Java, Lua, .Net, Perl, PHP, Python, and Ruby.
MariaDB is a fork of MySQL with a slightly different feature set. It is entirely compatible with MySQL for most applications.
"Limit" could mean "Max number of rows in a table".
"Offset" mean pick from row
number (not to be confused by primary key value or any field data value)
The output of a mysqldump
operation is a lightly commented file containing sequential SQL statements that are compatible with the version of MySQL utilities that was used to generate it (with attention paid to compatibility with previous versions, but no guarantee for future ones). Thus, the restoration of a mysqldump
ed database comprises execution of those statements. Generally, this file
DROP
s the first specified table or viewCREATE
s that table or view--no-data
option)
LOCK
s the tableINSERT
s all of the rows from the original table in one statementUNLOCK TABLES
DROP
s the first included routineCREATE
s that routineThe presence of the DROP
before CREATE
for each table means that if the schema is present, whether or not it is empty, using a mysqldump
file for its restoration will populate or overwrite the data therein.
The CREATE TABLE
statement should end with an ENGINE
specification:
CREATE TABLE table_name ( column_definitions ) ENGINE=engine;
Some options are:
InnoDB
: (Default since version 5.5.5) It's a transation-safe (ACID compliant) engine. It has transaction commit and roll-back, and crash-recovery capabilities and row-level locking.MyISAM
: (Default before version 5.5.5) It's a plain-fast engine. It doesn't support transactions, nor foreign keys, but it's useful for data-warehousing.Memory
: Stores all data in RAM for extremely fast operations but table date will be lost on database restart.More engine options here.
A stored routine is either a procedure or a function.
A procedure is invoked using a CALL statement and can only pass back values using output variables.
A function can be called from inside a statement just like any other function and can return a scalar value.
Listed below are all reserved words (from the official documentation):
Views are virtual tables and do not contain the data that is returned. They can save you from writing complex queries again and again.
SELECT
statement. The SELECT
statement cannot contain a sub-query in the FROM clause.SELECT
ed from just like a table.You have to create views, when you want to restrict few columns of your table, from the other user.
Performance. VIEWs
are syntactic sugar. However there performance may or may not be worse than the equivalent query with the view's select folded in. The Optimizer attempts to do this "fold in" for you, but is not always successful. MySQL 5.7.6 provides some more enhancements in the Optimizer. But, regardless, using a VIEW
will not generate a faster query.
An index in a MySQL table works like an index in a book.
Let's say you have a book about databases and you want to find some information about, say, storage. Without an index (assuming no other aid, such as a table of contents) you'd have to go through the pages one by one, until you found the topic (that's a "full table scan"). On the other hand, an index has a list of keywords, so you'd consult the index and see that storage is mentioned on pages 113-120, 231, and 354. Then you could flip to those pages directly, without searching (that's a search with an index, somewhat faster).
Of course, the usefulness of the index depends on many things - a few examples, using the simile above:
The --
style of comment, which requires a trailing space, differs in behavior from the SQL standard, which does not require the space.
alter_specification: table_options
| ADD [COLUMN] col_name column_definition [FIRST | AFTER col_name ]
| ADD [COLUMN] (col_name column_definition,...)
| ADD {INDEX|KEY} [index_name] [index_type] (index_col_name,...) [index_option] ...
| ADD [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,...) [index_option] ...
| ADD [CONSTRAINT [symbol]] UNIQUE [INDEX|KEY] [index_name] [index_type] (index_col_name,...) [index_option] ...
| ADD FULLTEXT [INDEX|KEY] [index_name] (index_col_name,...) [index_option] ...
| ADD SPATIAL [INDEX|KEY] [index_name] (index_col_name,...) [index_option] ...
| ADD [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name,...) reference_definition
| ALGORITHM [=] {DEFAULT|INPLACE|COPY}
| ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}
| CHANGE [COLUMN] old_col_name new_col_name column_definition [FIRST|AFTER col_name]
| LOCK [=] {DEFAULT|NONE|SHARED|EXCLUSIVE}
| MODIFY [COLUMN] col_name column_definition [FIRST | AFTER col_name]
| DROP [COLUMN] col_name
| DROP PRIMARY KEY
| DROP {INDEX|KEY} index_name
| DROP FOREIGN KEY fk_symbol
| DISABLE KEYS
| ENABLE KEYS
| RENAME [TO|AS] new_tbl_name
| RENAME {INDEX|KEY} old_index_name TO new_index_name
| ORDER BY col_name [, col_name] ...
| CONVERT TO CHARACTER SET charset_name [COLLATE collation_name]
| [DEFAULT] CHARACTER SET [=] charset_name [COLLATE [=] collation_name]
| DISCARD TABLESPACE
| IMPORT TABLESPACE
| FORCE
| {WITHOUT|WITH} VALIDATION
| ADD PARTITION (partition_definition)
| DROP PARTITION partition_names
| DISCARD PARTITION {partition_names | ALL} TABLESPACE
| IMPORT PARTITION {partition_names | ALL} TABLESPACE
| TRUNCATE PARTITION {partition_names | ALL}
| COALESCE PARTITION number
| REORGANIZE PARTITION partition_names INTO (partition_definitions)
| EXCHANGE PARTITION partition_name WITH TABLE tbl_name [{WITH|WITHOUT} VALIDATION]
| ANALYZE PARTITION {partition_names | ALL}
| CHECK PARTITION {partition_names | ALL}
| OPTIMIZE PARTITION {partition_names | ALL}
| REBUILD PARTITION {partition_names | ALL}
| REPAIR PARTITION {partition_names | ALL}
| REMOVE PARTITIONING
| UPGRADE PARTITIONING
index_col_name: col_name [(length)] [ASC | DESC]
index_type: USING {BTREE | HASH}
index_option: KEY_BLOCK_SIZE [=] value
| index_type
| WITH PARSER parser_name
| COMMENT 'string'
table_options: table_option [[,] table_option] ... (see
CREATE TABLE options)
partition_options: (see
CREATE TABLE options)
Ref: MySQL 5.7 Reference Manual / ... / ALTER TABLE Syntax / 14.1.8 ALTER TABLE Syntax
Starting from MySQL 5.7.8, MySQL ships with a JSON type. Lots of devs have been saving JSON data in text columns for a log time but the JSON type is different, the data is saved in binary format after validation. That avoids the overhead of parsing the text on each read.
Two points need to draw your attention if you already use triggers on others DB :
FOR EACH ROW
is a mandatory part of the syntax
You can't make a statement trigger (once by query) like Oracle do. It's more a performance related issue than a real missing feature
The CREATE OR REPLACE
is not supported by MySQL
MySQL don't allow this syntax, you have instead to use the following :
DELIMITER $$
DROP TRIGGER IF EXISTS myTrigger;
$$
CREATE TRIGGER myTrigger
-- ...
$$
DELIMITER ;
Be careful, this is not an atomic transaction :
CREATE
failDROP
and the CREATE
, use a LOCK TABLES myTable WRITE;
first to avoid data inconsistency and UNLOCK TABLES;
after the CREATE
to release the tablePivot query creation in MySQL relies upon the GROUP_CONCAT()
function. If the result of the expression that creates the columns of the pivot query is expected to be large, the value of the group_concat_max_len
variable must be increased:
set session group_concat_max_len = 1024 * 1024; -- This should be enough for most cases
Configuration happens in one of 3 ways:
my.cnf
configuration fileCommand Line options takes the form mysqld --long-parameter-name=value --another-parameter
. The same parameters can be placed in the my.conf
configuration file. Some parameters are configurable using system variables from within MySQL. Check the official documentation for a complete list of parameters.
Variables can have dash -
or underscore _
. Spaces may exist around the =
. Large numbers can be suffixed by K
, M
, G
for kilo-, mega-, and giga-. One setting per line.
Flags: Usually ON
and 1
are synonymous, ditto for OFF
and 0
. Some flags have nothing after them.
When placing the settings in my.cnf
, all settings for the server must be in the [mysqld]
section, so don't blindly add settings to the end of the file. (Note: For tools that allow multiple mysql instances to share one my.cnf, the section names may be different.)
For more information on MySQL's SELECT
statement, refer MySQL Docs.
To view a List of MySQL Users, we use the following command :
SELECT User,Host FROM mysql.user;
The MySQL GROUP BY clause is used in a SELECT statement to collect data across multiple records and group the results by one or more columns.
Its behavior is governed in part by the value of the ONLY_FULL_GROUP_BY
variable. When this is enabled, SELECT
statements that group by any column not in the output return an error. (This is the default as of 5.7.5.) Both setting and not setting this variable can cause problems for naive users or users accustomed to other DBMSs.
UNION does not use multiple CPUs.
UNION always* involves a temp table to collect the results. *As of 5.7.3 / MariaDB 10.1, some forms of UNION deliver the results without using a tmp table (hence, faster).
See also discussions about ORDER BY, LIKE, REGEXP, etc. Note: this needs editing with links and more Topics.
MySQL, on most machines, uses 64-bit IEEE 754 floating point arithmetic for its calculations.
In integer contexts it uses integer arithmetic.
RAND()
is not a perfect random number generator. It is mainly used to quickly generate pseudorandom numbersOver the years, InnoDB has improved to the point where it is almost always better than MyISAM, at least the currently supported versions. Bottom line: Don't use MyISAM, except maybe for tables that are truly temporary.
One advantage of MyISAM over InnoDB remains: It is 2x-3x smaller in space required on disk.
When InnoDB first came out, MyISAM was still a viable Engine. But with the advent of XtraDB and 5.6, InnoDB became "better" than MyISAM in most benchmarks.
Rumor has it that the next major version will eliminate the need for MyISAM by making truly temporary InnoDB tables and by moving the system tables into InnoDB.
AUTO_INCREMENT
id for this table -- The PK given is the
'natural' PK; there is no good reason for a surrogate.MEDIUMINT
--
This is a reminder that all INTs
should be made as small as is safe
(smaller ⇒ faster). Of course the declaration here must match the
definition in the table being linked to.UNSIGNED
-- Nearly all
INTs may as well be declared non-negativeNOT NULL
-- Well, that's
true, isn't it?InnoDB
-- More effecient than MyISAM because of the
way the PRIMARY KEY
is clustered with the data in InnoDB.INDEX(y_id, x_id)
-- The PRIMARY KEY
makes it efficient to go one
direction; the makes the other direction efficient. No need to say
UNIQUE
; that would be extra effort on INSERTs
.INDEX(y_id)
would work because it would implicit
include x_id
. But I would rather make it more obvious that I am
hoping for a 'covering' index.You may want to add more columns to the table; this is rare. The extra columns could provide information about the relationship that the table represents.
You may want to add FOREIGN KEY
constraints.
RANGE partitioning. This type of partitioning assigns rows to partitions based on column values falling within a given range.
LIST partitioning. Similar to partitioning by RANGE, except that the partition is selected based on columns matching one of a set of discrete values.
HASH partitioning. With this type of partitioning, a partition is selected based on the value returned by a user-defined expression that operates on column values in rows to be inserted into the table. The function may consist of any expression valid in MySQL that yields a nonnegative integer value. An extension to this type, LINEAR HASH
, is also available.
KEY partitioning. This type of partitioning is similar to partitioning by HASH, except that only one or more columns to be evaluated are supplied, and the MySQL server provides its own hashing function. These columns can contain other than integer values, since the hashing function supplied by MySQL guarantees an integer result regardless of the column data type. An extension to this type, LINEAR KEY
, is also available.
mysqlimport
will use the name of the imported file, after stripping the extension, to determine the destination table.
Locking is used to solve concurrency problems.Locking is required only when running a transaction, that first read a value from a database and later write that value in to the database. Locks are never required for self-contained insert, update, or delete operations.
There are two kinds of locks available
READ LOCK - when a user is only reading from a table.
WRITE LOCK - when a user is doing both reading and writing to a table.
When a user holds a WRITE LOCK
on a table, no other users can read or write to that table. When a user holds a READ LOCK
on a table, other users can also read or hold a READ LOCK
, but no user can write or hold a WRITE LOCK
on that table.
If default storage engine is InnoDB, MySQL automatically uses row level locking so that multiple transactions can use same table simultaneously for read and write, without making each other wait.
For all storage engines other than InnoDB, MySQL uses table locking.
For more details about table lock See here
UNION DISTINCT
is the same as UNION
; it is slower than UNION ALL
because of a de-duplicating pass. A good practice is to always spell out DISTINCT
or ALL
, thereby signaling that you thought about which to do.
Replication is used to copy[Backup] data from one MySQL database server to one or more MySQL database servers.
Master -- The MySQL database server, which is serving data to be copied
Slave -- The MySQL database server, copies data which is served by Master
With MySQL, replication is asynchronous by default. This means slaves do not need to be connected permanently to receive updates from the master. For example, if your slave is switched OFF or not connected with master and you are switching slave ON or connect with Master at a later time, then it will automatically synchronize with the Master.
Depending on the configuration, you can replicate all databases, selected databases, or even selected tables within a database.
Replication Formats
There are two core types of replication formats
Statement Based Replication (SBR) -- which replicates entire SQL statements. In this, the master writes SQL statements to the binary log. Replication of the master to the slave works by executing that SQL statements on the slave.
Row Based Replication (RBR) -- which replicates only the changed rows. In this, the master writes events to the binary log that indicate how individual table rows are changed. Replication of the master to the slave works by copying the events representing the changes to the table rows to the slave.
You can also use a third variety, Mixed Based Replication (MBR). In this, both statement-based and row-based logging is used. Log will be created depending on which is most appropriate for the change.
Statement-based format was the default in MySQL versions older than 5.7.7. In MySQL 5.7.7 and later, row-based format is the default.
When you need to handle time information for a worldwide user base in MySQL, use the TIMESTAMP data type in your tables.
For each user, store a user-preference timezone column. VARCHAR(64) is a good data type for that column. When a user registers to use your system, ask for the time zone value. Mine is Atlantic Time, America/Edmonton
. Yours might or might not be Asia/Kolkata
or Australia/NSW
. For a user interface for this user-preference setting, the WordPress.org software has a good example.
Finally, whenever you establish a connection from your host program (Java, php, whatever) to your DBMS on behalf of a user, issue the SQL command
SET SESSION time_zone='(whatever tz string the user gave you)'
before you handle any user data involving times. Then all the TIMESTAMP
times you have install will render in the user's local time.
This will cause all times going in to your tables to be converted to UTC, and all times coming out to be translated to local. It works properly for NOW() and CURDATE(). Again, you must use TIMESTAMP and not DATETIME or DATE data types for this.
Make sure your server OS and default MySQL time zones are set to UTC. If you don't do this before you start loading information into your database, it will be almost impossible to fix. If you use a vendor to run MySQL, insist they get this right.
You need to be at MySQL version 5.6.4 or later to declare columns with fractional-second time datatypes.
For example, DATETIME(3)
will give you millisecond resolution in your timestamps, and TIMESTAMP(6)
will give you microsecond resolution on a *nix-style timestamp.
Read this: http://dev.mysql.com/doc/refman/5.7/en/fractional-seconds.html
NOW(3)
will give you the present time from your MySQL server's operating system with millisecond precision.
(Notice that MySQL internal fractional arithmetic, like * 0.001, is always handled as IEEE754 double precision floating point, so it's unlikely you'll lose precision before the Sun becomes a white dwarf star.)
For a long time now, MySQL has contained a notorious nonstandard extension to GROUP BY
, which allows oddball behavior in the name of efficiency. This extension has allowed countless developers around the world to use GROUP BY
in production code without completely understanding what they were doing.
In particular, it's a bad idea to use SELECT *
in a GROUP BY
query, because a standard GROUP BY
clause requires enumerating the columns. Many developers have, unfortunately, done that.
Read this. https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html
The MySQL team has been trying to fix this misfeature without messing up production code. They added a sql_mode
flag in 5.7.5 named ONLY_FULL_GROUP_BY
to compel standard behavior. In a recent release, they turned on that flag by default. When you upgraded your local MySQL to 5.7.14, the flag got switched on and your production code, dependent on the old extension, stopped working.
If you've recently started getting 1055 errors, what are your choices?
sql_mode
to get rid of the newly set ONLY_FULL_GROUP_BY
mode.You can change the mode by doing a SET
command.
SET sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
should do the trick if you do it right after your application connects to MySQL.
Or, you can find the init file in your MySQL installation, locate the sql_mode=
line, and change it to omit ONLY_FULL_GROUP_BY
, and restart your server.
FULLTEXT
searching works strangely on tables containing small numbers of rows. So, when you're experimenting with it, you may find it helpful to obtain a medium-sized table online. Here's a table of book items, with titles and authors. You can download it, unzip it, and load it into MySQL.
FULLTEXT
search is intended for use with human assistance. It's designed to yield more matches than an ordinary WHERE column LIKE 'text%'
filtering operation.
FULLTEXT
search is available for MyISAM
tables. It is also available for InnoDB
tables in MySQL version 5.6.4 or later.
Mentioned in MySQL 5.7 Reference Manual
If it is possible that those arguments could return multiple values, the matched values are autowrapped as an array, in the order corresponding to the paths that produced them. Otherwise, the return value is the single matched value.
NULL
Result when:
Returns NULL if any argument is NULL or no paths locate a value in the document.
Recovering and resetting the default root password using this method is applicable only for MySQL 5.7+
For most cases, working with a 1:M relationship requires us to understand Primary Keys and Foreign Keys.
A Primary key is a column in a table where any single row of that column represents a single entity, or, selecting a value in a primary key column results in exactly one row. Using the above examples, an EMP_ID represents a single employee. If you query for any single EMP_ID, you will see a single row representing the corresponding employee.
A Foreign Key is a column in a table that corresponds to the primary key of another different table. From our example above, the MGR_ID in the EMPLOYEES table is a foreign key. Generally to join two tables, you'll join them based on the primary key of one table and the foreign key in another.