0% found this document useful (0 votes)
105 views

MySQL Tutorial 2

This tutorial discusses various ways to modify data in MySQL tables using INSERT, UPDATE, DELETE, and other statements. It covers inserting single and multiple rows, updating existing rows, deleting rows, and more advanced topics like cascading deletes and prepared statements.

Uploaded by

xy za
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
105 views

MySQL Tutorial 2

This tutorial discusses various ways to modify data in MySQL tables using INSERT, UPDATE, DELETE, and other statements. It covers inserting single and multiple rows, updating existing rows, deleting rows, and more advanced topics like cascading deletes and prepared statements.

Uploaded by

xy za
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 161

Section 9.

Modifying data in MySQL


In this section, you will learn how to insert, update, and delete data from tables using various MySQL
statements.

 INSERT – learn how to use various forms of the INSERT statement to insert data into database
tables.

 INSERT IGNORE – explain you the INSERT IGNORE statement that inserts rows into a table and
ignore rows that cause errors or exceptions.

 UPDATE – learn how to use UPDATE statement and its options to update data in database tables.

 UPDATE JOIN – show you how to perform cross table update using UPDATE JOIN statement
with INNER JOIN and LEFT JOIN .

 DELETE – show you how to use the DELETE statement to remove data from one or more tables.

 ON DELETE CASCADE – learn how to use ON DELETE CASCADE referential action for a foreign key
to delete data from a child table automatically when you delete data from a parent table.

 DELETE JOIN – show you how to delete data from multiple tables.

 REPLACE – learn how to insert or update data depends on whether data exists in the table or not.

 Prepared Statement – show you how to use the prepared statement to execute a query.

Inserting Data into A Table Using MySQL INSERT


Statement
Summary: in this tutorial, you will learn how to use MySQL INSERT statement to insert data into the
database tables.

Simple MySQL INSERT statement


The MySQL INSERT statement allows you to insert one or more rows into a table. The following illustrates
the syntax of the INSERT statement:

1 INSERT INTO table(column1,column2...)


2 VALUES (value1,value2,...);

First, you specify the table name and a list of comma-separated columns inside parentheses after
the INSERT INTO clause.

Then, you put a comma-separated values of the corresponding columns inside the parentheses followed
the VALUES keyword.
You need to have an INSERT privilege to use the INSERT statement.

Let’s create a new table named tasks for practicing the INSERT statement.

1 CREATE TABLE IF NOT EXISTS tasks (


2 task_id INT(11) AUTO_INCREMENT,
3 subject VARCHAR(45) DEFAULT NULL,
4 start_date DATE DEFAULT NULL,
5 end_date DATE DEFAULT NULL,
6 description VARCHAR(200) DEFAULT NULL,
7 PRIMARY KEY (task_id)
8 );

For example, if you want to insert a new task into the tasks table, you use the INSERT statement
as follows:

1 INSERT INTO tasks(subject,start_date,end_date,description)


2 VALUES('Learn MySQL INSERT','2010-01-01','2010-01-02','Start learning..');

After executing the statement, MySQL returns a message to inform the number of rows affected. In this
case, one row were affected.

1 SELECT
2 *
3 FROM
4 tasks;

MySQL INSERT – insert multiple rows


In order to insert multiple rows into a table, you use the INSERT statement with the following syntax:

1 INSERT INTO table(column1,column2...)


2 VALUES (value1,value2,...),
3 (value1,value2,...),
4 ...;

In this form, the value list of each row is separated by a comma. For example, to insert multiple rows into
the tasks table, you use the following statement:

1 INSERT INTO tasks(subject,start_date,end_date,description)


2 VALUES ('Task 1','2010-01-01','2010-01-02','Description 1'),
3 ('Task 2','2010-01-01','2010-01-02','Description 2'),
4 ('Task 3','2010-01-01','2010-01-02','Description 3');
3 rows affected. Great!

If you specify the value of the corresponding column for all columns in the table, you can ignore the
column list in the INSERT statement as follows:

1 INSERT INTO table


2 VALUES (value1,value2,...);

and

1 INSERT INTO table


2 VALUES (value1,value2,...),
3 (value1,value2,...),
4 ...;

Notice that you don’t have to specify the value for auto-increment column e.g., taskid column because
MySQL generates value for the auto-increment column automatically.

MySQL INSERT with SELECT clause


In MySQL, you can specify the values for the INSERT statement from a SELECT statement. This feature
is very handy because you can copy a table fully or partially using the INSERT and SELECT clauses as
follows:

1 INSERT INTO table_1


2 SELECT c1, c2, FROM table_2;

Let’s copy the tasks table to the task_1 table.

First, create a new table named tasks_1 by copying the structure of the tasks table as follows:

1 CREATE TABLE tasks_1 LIKE tasks;

Second, insert data from the tasks table into the tasks_1 table using the following INSERT statement:

1 INSERT INTO tasks_1


2 SELECT * FROM tasks;

Third, check the tasks_1 table to see if we actually copy it from the tasks table.

1 SELECT
2 *
3 FROM
4 tasks_1;

MySQL INSERT with ON DUPLICATE KEY UPDATE


If the new row violates the PRIMARY KEY or UNIQUE constraint, MySQL issues an error. For example, if
you execute the following statement:

1 INSERT INTO tasks(task_id,subject,start_date,end_date,description)


2 VALUES (4,'Test ON DUPLICATE KEY UPDATE','2010-01-01','2010-01-02','Next Priority');

MySQL issues an error message:

1 Error Code: 1062. Duplicate entry '4' for key 'PRIMARY' 0.016 sec

Because the row with the primary key task_id 4 already exists in the tasks table, the statement violates
the PRIMARY KEY constraint.

However, if you specify the ON DUPLICATE KEY UPDATE option in the INSERT statement, MySQL
will insert a new row or update the existing row with the new values.

For example, the following statement updates the existing row whose task_id is 4 with the new task_id
and subject.

1 INSERT INTO tasks(task_id,subject,start_date,end_date,description)


2 VALUES (4,'Test ON DUPLICATE KEY UPDATE','2010-01-01','2010-01-02','Next Priority')
3 ON DUPLICATE KEY UPDATE
4 task_id = task_id + 1,
5 subject = 'Test ON DUPLICATE KEY UPDATE';

MySQL issues a message saying that 2 rows affected .


L
et’s check the tasks table:

1 SELECT
2 *
3 FROM
4 tasks;
The new row was not inserted. But the existing row with the task_id 4 was updated.

The INSERT ON DUPLICATE KEY UPDATE statement above is equivalent to the


following UPDATEstatement:

1 UPDATE tasks
2 SET
3 task_id = task_id + 1,
4 subject = 'Test ON DUPLICATE KEY UPDATE'
5 WHERE
6 task_id = 4;

For more information on the INSERT ON DUPLICATE KEY UPDATE statement, please check it out
the MySQL insert or update tutorial.

In this tutorial, we have shown you how to use various forms of the MySQL INSERT statement to insert
data into a table.

MySQL INSERT IGNORE Statement Explained


Summary: in this tutorial, you will learn how to use the MySQL INSERT IGNORE statement to insert data
into a table.

Introduction to MySQL INSERT IGNORE statement


When you use the INSERT statement to add some rows to a table and if an error occurs during the
processing, the INSERT statement is aborted and an error message is returned. As the result, no rows are
inserted into the table.

However, if you use the INSERT INGORE statement, the rows that cause the errors are ignored and the
remaining rows are inserted into the table.

The syntax of the INSERT INGORE statement is as follows:

1 INSERT IGNORE INTO table(column_list)


2 VALUES( value_list),
3 ( value_list),
4 ...

Note that the INGORE clause is an extension of MySQL to the SQL standard.
MySQL INSERT IGNORE example
We will create a new table called subscribers for the demonstration.

1 CREATE TABLE subscribers (


2 id INT PRIMARY KEY AUTO_INCREMENT,
3 email VARCHAR(50) NOT NULL UNIQUE
4 );

The UNIQUE constraint ensures that no duplicate email exists in the email column.
The following statement inserts a new row into the subscribers table:

1 INSERT INTO subscribers(email)

2 VALUES('[email protected]');

It worked as expected.

Let’s execute another statement that inserts two rows into the subscribers table:

1 INSERT INTO subscribers(email)


2 VALUES('[email protected]'),
3 ('[email protected]');

It returns an error.

1 Error Code: 1062. Duplicate entry '[email protected]' for key 'email'

As indicated in the error message, the email [email protected] causes a violation of


the UNIQUE constraint.

However, if you use the INSERT IGNORE statement instead.

1 INSERT IGNORE INTO subscribers(email)


2 VALUES('[email protected]'),
3 ('[email protected]');

The server returned a message showing that one row is inserted and the other row is ignored.

1 1 row(s) affected, 1 warning(s): 1062 Duplicate entry '[email protected]' for key 'email' Records: 2 Duplicates: 1 Warnings: 1

If you use the SHOW WARNINGS statement, you will find the detail of the warning:

1 SHOW WARNINGS;
So when you use the INSERT INGORE statement, instead of issuing an error, MySQL issued a warning in
case an error occurs.

Querying data from subscribers table, you will find that only one row actually inserted and the rows
that cause an error was ignored.

MySQL INSERT IGNORE and STRICT Mode


When the STRICT mode is on, MySQL returns an error and aborts the INSERT statement if you try to
insert invalid values into a table.

However, if you use the INSERT INGORE statement, MySQL will issue a warning instead of an error. In
addition, it will try to adjust the values to make them valid before inserting.
Consider the following example.

First, we create a new table named tokens :

1 CREATE TABLE tokens (


2 s VARCHAR(6)
3 );

In this table, the column s accepts only strings whose lengths are less than or equal 6.

Second, insert a string whose length is 7 into the tokens table.

1 INSERT INTO tokens VALUES('abcdefg');

MySQL issued the following error because the STRICT mode is on.

1 Error Code: 1406. Data too long for column 's' at row 1

Third, use the INSERT IGNORE statement to insert the same string.

1 INSERT IGNORE INTO tokens VALUES('abcdefg');

MySQL truncated data before inserting it into the tokens table. In addition, it issues a warning.

In this tutorial, you have learned how to use the MySQL INSERT IGNORE statement to insert rows into a
table and ignore error for rows that cause errors.
MySQL UPDATE
Summary: updating data is one of the most important tasks when you work with the database. In this
tutorial, you will learn how to use the MySQL UPDATE statement to update data in a table.

Introduction to MySQL UPDATE statement


We use the UPDATE statement to update existing data in a table. We can use the UPDATE statement to
change column values of a single row, a group of rows, or all rows in a table.

The following illustrates the syntax of the MySQL UPDATE statement:

1 UPDATE [LOW_PRIORITY] [IGNORE] table_name


2 SET
3 column_name1 = expr1,
4 column_name2 = expr2,
5 ...
6 WHERE
7 condition;

In the UPDATE statement:

 First, specify the table name that you want to update data after the UPDATE keyword.

 Second, the SET clause specifies which column that you want to modify and the new values. To
update multiple columns, you use a list comma-separated assignments. You supply the value in
each column’s assignment in the form of a literal value, an expression, or a subquery.

 Third, specify which rows to be updated using a condition in the WHERE clause.
The WHERE clause is optional. If you omit the WHERE clause, the UPDATE statement will update all
rows in the table.

Notice that the WHERE clause is so important that you should not forget. Sometimes, you may want to
change just one row; However, you may forget the WHERE clause and accidentally updates all the rows in
the table.

MySQL supports two modifiers in the UPDATE statement.

1. The LOW_PRIORITY modifier instructs the UPDATE statement to delay the update until there is no
connection reading data from the table. The LOW_PRIORITY takes effect for the storage enginesthat
use table-level locking only, for example, MyISAM, MERGE, MEMORY.

2. The IGNORE modifier enables the UPDATE statement to continue updating rows even if errors
occurred. The rows that cause errors such as duplicate-key conflicts are not updated.

MySQL UPDATE examples

Let’s practice the UPDATE statement with some tables in the MySQL sample database.
MySQL UPDATE a single column example
In this example, we are going to update the email of Mary Patterson to the new
email [email protected] .

First, to make sure that we update the email successfully, we query Mary’s email from
the employees table using the following SELECT statement:

1 SELECT
2 firstname, lastname, email
3 FROM
4 employees
5 WHERE
6 employeeNumber = 1056;

Second, we can update Mary’s email to the new email [email protected] using
the UPDATE statement as the following query:

1 UPDATE employees
2 SET
3 email = '[email protected]'
4 WHERE
5 employeeNumber = 1056;

Because we just want to update one row, we use the WHERE clause to specify the row using the employee
number 1056 . The SET clause sets the value of the email column to the new email.

Third, we execute the SELECT statement again to verify the change.

1 SELECT
2 firstname, lastname, email
3 FROM
4 employees
5 WHERE
6 employeeNumber = 1056;

MySQL UPDATE multiple columns


To update values in the multiple columns, you need to specify the assignments in the SET clause. For
example, the following statement updates both last name and email columns of employee number 1056:

1 UPDATE employees
2 SET
3 lastname = 'Hill',
4 email = '[email protected]'
5 WHERE
6 employeeNumber = 1056;

Let’s check the changes.

1 SELECT
2 firstname, lastname, email
3 FROM
4 employees
5 WHERE
6 employeeNumber = 1056;

MySQL UPDATE from SELECT statement example


You can supply the values for the SET clause from a SELECT statement that queries data from other
tables.

For example, in the customers table, some customers do not have any sale representative. The value of
the column saleRepEmployeeNumber is NULL as follows:

1 SELECT
2 customername, salesRepEmployeeNumber
3 FROM
4 customers
5 WHERE
6 salesRepEmployeeNumber IS NULL;

We can take a sale representative and update for those customers.

To do this, we can select a random employee whose job title is Sales Rep from the employees table and
update it for the employees table.

This query selects a random employee from the employees table whose job title is the Sales Rep .
1 SELECT
2 employeeNumber
3 FROM
4 employees
5 WHERE
6 jobtitle = 'Sales Rep'
7 ORDER BY RAND()
8 LIMIT 1;

To update the sales representative employee number column in the customers table, we put the query
above in the SET clause of the UPDATE statement as follows:

1 UPDATE customers
2 SET
3 salesRepEmployeeNumber = (SELECT
4 employeeNumber
5 FROM
6 employees
7 WHERE
8 jobtitle = 'Sales Rep'
9 LIMIT 1)
10 WHERE
11 salesRepEmployeeNumber IS NULL;

If you query data from the employees table, you will see that every customer has a sales representative.
In other words, the following query returns no row.

1 SELECT
2 salesRepEmployeeNumber
3 FROM
4 customers
5 WHERE
6 salesRepEmployeeNumber IS NOT NULL;

In this tutorial, you have learned how to use MySQL UPDATE statement to update data in a database table.

MySQL UPDATE JOIN


Summary: in this tutorial, you will learn how to use the MySQL UPDATE JOIN statement to perform the
cross-table update. We will show you step by step how to use INNER JOIN clause and LEFT
JOIN clause with the UPDATE statement.

MySQL UPDATE JOIN syntax


We often use join clauses to query rows in a table that have (in the case of INNER JOIN) or may not have
(in the case of LEFT JOIN) corresponding rows in another table. In MySQL, we can use the JOIN clauses
in the UPDATE statement to perform the cross-table update.

The syntax of the MySQL UPDATE JOIN is as follows:

1 UPDATE T1, T2,


2 [INNER JOIN | LEFT JOIN] T1 ON T1.C1 = T2. C1
3 SET T1.C2 = T2.C2,
4 T2.C3 = expr
5 WHERE condition

Let’s examine the MySQL UPDATE JOIN syntax in greater detail:

 First, you specify the main table ( T1 ) and the table that you want the main table to join to ( T2 )
after the UPDATE clause. Notice that you must specify at least one table after the UPDATE clause.
The data in the table that is not specified after the UPDATE clause is not updated.

 Second, you specify a kind of join you want to use i.e., either INNER JOIN or LEFT JOIN and a join
condition. The JOIN clause must appear right after the UPDATE clause.

 Third, you assign new values to the columns in T1 and/or T2 tables that you want to update.

 Fourth, the condition in the WHERE clause allows you to specify which rows to update.

If you follow the UPDATE statement tutorial, you notice that there is another way to update data cross-
table using the following syntax:

1 UPDATE T1, T2
2 SET T1.c2 = T2.c2,
3 T2.c3 = expr
4 WHERE T1.c1 = T2.c1 AND condition

This UPDATE statement works the same as UPDATE JOIN with implicit INNER JOIN clause. It means you
can rewrite the above statement as follows:

1 UPDATE T1,T2
2 INNER JOIN T2 ON T1.C1 = T2.C1
3 SET T1.C2 = T2.C2,
4 T2.C3 = expr
5 WHERE condition

Let’s take a look at some examples of using the UPDATE JOIN statement to having a better
understanding.

MySQL UPDATE JOIN examples


We are going to use a new sample database in these examples. The sample database contains 2 tables:

 The employees table stores employee data with employee id, name, performance, and salary.

 The merits table stores employee performance and merit’s percentage.

The following statements create and load data in the empdb sample database:
1 CREATE DATABASE IF NOT EXISTS empdb;
2
3 USE empdb;
4
5 -- create tables
6 CREATE TABLE merits (
7 performance INT(11) NOT NULL,
8 percentage FLOAT NOT NULL,
9 PRIMARY KEY (performance)
10 );
11
12 CREATE TABLE employees (
13 emp_id INT(11) NOT NULL AUTO_INCREMENT,
14 emp_name VARCHAR(255) NOT NULL,
15 performance INT(11) DEFAULT NULL,
16 salary FLOAT DEFAULT NULL,
17 PRIMARY KEY (emp_id),
18 CONSTRAINT fk_performance FOREIGN KEY (performance)
19 REFERENCES merits (performance)
20 );
21 -- insert data for merits table
22 INSERT INTO merits(performance,percentage)
23 VALUES(1,0),
24 (2,0.01),
25 (3,0.03),
26 (4,0.05),
27 (5,0.08);
28 -- insert data for employees table
29 INSERT INTO employees(emp_name,performance,salary)
30 VALUES('Mary Doe', 1, 50000),
31 ('Cindy Smith', 3, 65000),
32 ('Sue Greenspan', 4, 75000),
33 ('Grace Dell', 5, 125000),
34 ('Nancy Johnson', 3, 85000),
35 ('John Doe', 2, 45000),
36 ('Lily Bush', 3, 55000);

MySQL UPDATE JOIN example with INNER JOIN clause


Suppose you want to adjust the salary of employees based on their performance.

The merit’s percentages are stored in the merits table therefore, you have to use the UPDATE INNER
JOIN statement to adjust the salary of employees in the employees table based on
the percentage stored in the merits table.

The link between the employees and merit tables is the performance field. See the following query:

1 UPDATE employees
2 INNER JOIN
3 merits ON employees.performance = merits.performance
4 SET
5 salary = salary + salary * percentage;
How the query works.

We specify only the employees table after UPDATE clause because we want to update data in
the employees table only.

For each row in the employees table, the query checks the value in the performance column against the
value in the performance column in the merits table. If it finds a match, it gets the percentage in
the merits table and updates the salary column in the employees table.

Because we omit the WHERE clause in the UPDATE statement, all the records in the employees table get
updated.

MySQL UPDATE JOIN example with LEFT JOIN


Suppose the company hires two more employees:

1 INSERT INTO employees(emp_name,performance,salary)


2 VALUES('Jack William',NULL,43000),
3 ('Ricky Bond',NULL,52000);

Because these employees are new hires so their performance data is not available or NULL .

To increase the salary for new hires, you cannot use the UPDATE INNER JOIN statement because their
performance data is not available in the merit table. This is why the UPDATE LEFT JOIN comes to
the rescue.
The UPDATE LEFT JOIN statement basically updates a row in a table when it does not have a
corresponding row in another table.

For example, you can increase the salary for a new hire by 1.5% using the following statement:

1 UPDATE employees
2 LEFT JOIN
3 merits ON employees.performance = merits.performance
4 SET
5 salary = salary + salary * 0.015
6 WHERE
7 merits.percentage IS NULL;

In this tutorial, we have shown you how to use the MySQL UPDATE JOIN with the INNER JOIN and LEFT
JOIN clauses to perform the cross-table update.

MySQL DELETE
Summary: in this tutorial, you will learn how to use the MySQL DELETE statement to delete data from a
single table.

Introduction to MySQL DELETE statement


To delete data from a table, you use the MySQL DELETE statement. The following illustrates the syntax of
the DELETE statement:

1 DELETE FROM table_name


2 WHERE condition;

In this statement:

 First, specify the table from which you delete data.


 Second, use a condition to specify which rows to delete in the WHERE clause. If the row matches the
condition, it will be deleted.

Notice that the WHERE clause is optional. If you omit the WHERE clause, the DELETE statement will delete all
rows in the table.

Besides deleting data from a table, the DELETE statement returns the number of rows deleted.

To delete data from multiple tables using a single DELETE statement, you use the DELETE JOIN
statement which we will cover in the next tutorial.

To delete all rows in a table without the need of knowing how many rows deleted, you should use
the TRUNCATE TABLE statement to get a better performance.

For a table that has a foreign key constraint, when you delete rows from the parent table, the rows in the
child table will be deleted automatically by using the ON DELETE CASCADE option.

MySQL DELETE examples

We will use the employees table in the sample database for the demonstration.

Note that once you delete data, it is gone. Therefore, you should backup your database before performing
the DELETE statements in the next section.

Suppose you want to delete employees whose officeNumber is 4, you use the DELETE statement with
the WHERE clause as the following query:

1 DELETE FROM employees


2 WHERE
3 officeCode = 4;

To delete all rows from the employees table, you use the DELETE statement without the WHERE clause as
follows:

1 DELETE FROM employees;

All rows in the employees table deleted.


MySQL DELETE and LIMIT clause
If you want to limit the number of rows to be deleted, you use the LIMIT clause as follows:

1 DELETE FROM table


2 LIMIT row_count;

Note that the order of rows in a table is unspecified, therefore, when you use the LIMIT clause, you
should always use the ORDER BY clause.

1 DELETE FROM table_name


2 ORDER BY c1, c2, ...
3 LIMIT row_count;

Consider the following customers table in the sample database:

For example, the following statement sorts customers by customer’s names alphabetically and deletes the
first 10 customers:

1 DELETE FROM customers


2 ORDER BY customerName
3 LIMIT 10;

Similarly, the following DELETE statement selects customers in France , sorts them by credit limit in
ascending order, and deletes the first 5 customers:

1 DELETE FROM customers


2 WHERE country = 'France'
3 ORDER BY creditLimit
4 LIMIT 5;

In this tutorial, you have learned how to use the MySQL DELETE statement to delete data from a table.
MySQL ON DELETE CASCADE: Deleting Data From
Multiple Related Tables
Summary: in this tutorial, you will learn how to use MySQL ON DELETE CASCADE referential action for
a foreign key to delete data from multiple related tables.

In the previous tutorial, you learned how to delete data from multiple related tables using a
single DELETE statement. However, MySQL provides a more effective way called ON DELETE
CASCADE referential action for a foreign key that allows you to delete data from child tables automatically
when you delete the data from the parent table.

MySQL ON DELETE CASCADE example


Let’s take a look at an example of using MySQL ON DELETE CASCADE .

Suppose we have two tables: buildings and rooms . In this database model, each building has one or
more rooms. However, each room belongs to one only one building. A room would not exist without a
building.

The relationship between the buildings and rooms tables is one-to-many (1:N) as illustrated in the
following database diagram:

When we delete a row from the buildings table, we also want to delete the rows in the rooms table that
references to the rows in the buildings table. For example, when we delete a row with building no. 2 in
the buildings table as the following query:

1 DELETE FROM buildings


2 WHERE
3 building_no = 2;

We want the rows in the rooms table that refers to building number 2 will be also removed.

The following are steps that demonstrate how MySQL ON DELETE CASCADE referential action works.

Step 1. Create the buildings table:

1 CREATE TABLE buildings (


2 building_no INT PRIMARY KEY AUTO_INCREMENT,
3 building_name VARCHAR(255) NOT NULL,
4 address VARCHAR(255) NOT NULL
5 );

Step 2. Create the rooms table:

1 CREATE TABLE rooms (


2 room_no INT PRIMARY KEY AUTO_INCREMENT,
3 room_name VARCHAR(255) NOT NULL,
4 building_no INT NOT NULL,
5 FOREIGN KEY (building_no)
6 REFERENCES buildings (building_no)
7 ON DELETE CASCADE
8 );

Notice that we add the ON DELETE CASCADE clause at the end of the foreign key constraint definition.

Step 3. Insert data into the buildings table:

1 INSERT INTO buildings(building_name,address)


2 VALUES('ACME Headquaters','3950 North 1st Street CA 95134'),
3 ('ACME Sales','5000 North 1st Street CA 95134');

Step 4. Query data from the buildings table:

1 SELECT * FROM buildings;

We have two rows in the buildings table.

Step 5. Insert data into the rooms table:

1 INSERT INTO rooms(room_name,building_no)


2 VALUES('Amazon',1),
3 ('War Room',1),
4 ('Office of CEO',1),
5 ('Marketing',2),
6 ('Showroom',2);

Step 6. Query data from the rooms table:

1 SELECT * FROM rooms;


We have 3 rooms that belong to building 1 and 2 rooms that belong to the building 2.

Step 7. Delete the building with building no. 2:

1 DELETE FROM buildings


2 WHERE
3 building_no = 2;

Step 8. Query data from rooms table:

1 SELECT * FROM rooms;

As you can see, all the rows that reference to building_no 2 were deleted.
Notice that ON DELETE CASCADE works only with tables with the storage engines support foreign keys
e.g., InnoDB. Some table types do not support foreign keys such as MyISAM so you should choose
appropriate storage engines for the tables that you plan to use the MySQL ON DELETE
CASCADE referential action.

Tips to find tables affected by MySQL ON DELETE CASCADE


action
Sometimes, it is useful to know which table is affected by the MySQL ON DELETE CASCADE referential
action when you delete data from a table. You can query this data from
the referential_constraints in the information_schema database as follows:

1 USE information_schema;
2
3 SELECT
4 table_name
5 FROM
6 referential_constraints
7 WHERE
8 constraint_schema = 'database_name'
9 AND referenced_table_name = 'parent_table'
10 AND delete_rule = 'CASCADE'
For example, to find tables that associated with the buildings table with the CASCADE deletion rule in
the classicmodels database, you use the following query:

1 USE information_schema;
2
3 SELECT
4 table_name
5 FROM
6 referential_constraints
7 WHERE
8 constraint_schema = 'classicmodels'
9 AND referenced_table_name = 'buildings'
10 AND delete_rule = 'CASCADE'

In this tutorial, we have shown you step by step how to use the MySQL ON DELETE CASCADE referential
action for a foreign key to delete data automatically from the child tables when you delete data from the
parent table.

MySQL DELETE JOIN


Summary: in this tutorial, we will show you how to delete data from multiple tables by
using MySQL DELETE JOIN statement.

In the previous tutorial, you learned how to delete rows of multiple tables by using:

 A single DELETE statement on multiple tables.


 A single DELETE statement on multiple related tables which the child table have an ON DELETE
CASCADE referential action for the foreign key.

This tutorial introduces to you a more flexible way to delete data from multiple tables using INNER
JOIN or LEFT JOIN clause with the DELETE statement.

MySQL DELETE JOIN with INNER JOIN


MySQL also allows you to use the INNER JOIN clause in the DELETE statement to delete rows from a
table and the matching rows in another table.

For example, to delete rows from both T1 and T2 tables that meet a specified condition, you use the
following statement:
1 DELETE T1, T2
2 FROM T1
3 INNER JOIN T2 ON T1.key = T2.key
4 WHERE condition;

Notice that you put table names T1 and T2 between the DELETE and FROM keywords. If you omit T1 table,
the DELETE statement only deletes rows in T2 table. Similarly, if you omit T2 table, the DELETE statement
will delete only rows in T1 table.

The expression T1.key = T2.key specifies the condition for matching rows between T1 and T2 tables
that will be deleted.

The condition in the WHERE clause determine rows in the T1 and T2 that will be deleted.

MySQL DELETE JOIN with INNER JOIN example

Suppose, we have two tables t1 and t2 with the following structures and data:

1 DROP TABLE IF EXISTS t1, t2;


2
3 CREATE TABLE t1 (
4 id INT PRIMARY KEY AUTO_INCREMENT
5 );
6
7 CREATE TABLE t2 (
8 id VARCHAR(20) PRIMARY KEY,
9 ref INT NOT NULL
10 );
11
12 INSERT INTO t1 VALUES (1),(2),(3);
13
14 INSERT INTO t2(id,ref) VALUES('A',1),('B',2),('C',3);
The following statement deletes the row with id 1 in the t1 table and also row with ref 1 in the t2 table
using DELETE...INNER JOIN statement:

1 DELETE t1,t2 FROM t1


2 INNER JOIN
3 t2 ON t2.ref = t1.id
4 WHERE
5 t1.id = 1;

The statement returned the following message:

1 2 row(s) affected

It indicated that two rows have been deleted.

MySQL DELETE JOIN with LEFT JOIN


We often use the LEFT JOIN clause in the SELECT statement to find rows in the left table that have or
don’t have matching rows in the right table.

We can also use the LEFT JOIN clause in the DELETE statement to delete rows in a table (left table) that
does not have matching rows in another table (right table).

The following syntax illustrates how to use DELETE statement with LEFT JOIN clause to delete rows
from T1 table that does not have corresponding rows in the T2 table:

1 DELETE T1
2
FROM T1
3
LEFT JOIN
4
T2 ON T1.key = T2.key
5
WHERE
6
T2.key IS NULL;

Note that we only put T1 table after the DELETE keyword, not both T1 and T2 tables like we did with
the INNER JOIN clause.

MySQL DELETE JOIN with LEFT JOIN example


See the following customers and orders tables in the sample database:

Each customer has zero or more orders. However, each order belongs to one and only one customer.

We can use DELETE statement with LEFT JOIN clause to clean up our customers master data. The
following statement removes customers who have not placed any order:

1 DELETE customers
2 FROM customers
3 LEFT JOIN
4 orders ON customers.customerNumber = orders.customerNumber
5 WHERE
6 orderNumber IS NULL;

We can verify the delete by finding whether customers who do not have any order exists using the
following query:
1 SELECT
2 c.customerNumber,
3 c.customerName,
4 orderNumber
5 FROM
6 customers c
7 LEFT JOIN
8 orders o ON c.customerNumber = o.customerNumber
9 WHERE
10 orderNumber IS NULL;

The query returned an empty result set which is what we expected.

In this tutorial, you have learned how to use the MySQL DELETE JOIN statement to delete data from two
or more tables.

MySQL REPLACE
Summary: in this tutorial, you will learn how to use the MySQL REPLACE statement to insert or update
data in database tables.

Introduction to MySQL REPLACE statement


The MySQL REPLACE statement is a MySQL extension to the standard SQL. The
MySQL REPLACE statement works as follows:

 If the new row already does not exist, the MySQL REPLACE statement inserts a new row.

 If the new row already exist, the REPLACE statement deletes the old row first and then inserts a new
row. In some cases, the REPLACE statement updates the existing row only.

To determine whether the new row already exists in the table, MySQL uses PRIMARY KEY or UNIQUE
KEY index. If the table does not have one of these indexes, the REPLACE statement is equivalent to
the INSERT statement.

To use the MySQL REPLACE statement, you need to have at least both INSERT and DELETE privileges.
Notice that there is a REPLACE string function which is not the REPLACE statement covered in this
tutorial.

MySQL REPLACE statement example


Let’s take a look at an example of using the REPLACE statement to have a better understanding of how it
works.
First, create a new table named cities as follows:

1 CREATE TABLE cities (


2 id INT AUTO_INCREMENT PRIMARY KEY,
3 name VARCHAR(50),
4 population INT NOT NULL
5 );

Next, insert some rows into the cities table:

1 INSERT INTO cities(name,population)


2 VALUES('New York',8008278),
3 ('Los Angeles',3694825),
4 ('San Diego',1223405);

We query data from the cities table to verify the insert operation.

1 SELECT
2 *
3 FROM
4 cities;

We have three cities in the cities table.

Then, suppose we want to update the population of the New York city to 1008256. We can use
the UPDATE statement as follows:

1 UPDATE cities
2 SET
3 population = 1008256
4 WHERE
5 id = 1;

We query the data from the cities table again to verify the update.

1 SELECT
2 *
3 FROM
4 cities;

The UPDATE statement updated the data as expected.


After that, use the REPLACE statement to update the population of the Los Angeles city to 3696820 .

1 REPLACE INTO cities(id,population)


2 VALUES(2,3696820);

Finally, query the data of the cities table again to verify the replacement.

1 SELECT
2 *
3 FROM
4 cities;

The name column is NULL now. You may expect that the value of the name column remains intact.
However, the REPLACE statement does not behave this way. In this case, the REPLACE statement works
as follows:

1. The REPLACE statement first inserts the new row into the cities table with the information provided
by the column list. The insertion fails because the row with id 2 already exists in the cities table,
therefore, MySQL raises a duplicate-key error.

2. The REPLACE statement then updates the row that has the key specified in the value of the id
column. In the normal process, it would delete the old row with conflict id first and then inserts a new
row.

We know that the REPLACE statement did not delete the old row and inserted the new row because the
value of the id column is 2 instead of 4.

MySQL REPLACE and INSERT


The first form of the REPLACE statement is similar to the INSERT statement except the keyword INSERT is
replaced by the REPLACE keyword as follows:

1 REPLACE INTO table_name(column_list)


2 VALUES(value_list);

For example, if you want to insert a new row into the cities table, you use the following query:

1 REPLACE INTO cities(name,population)


2 VALUES('Phoenix',1321523);

Notice that the default values of the columns that do not appear in the REPLACE statement will be inserted
into the corresponding columns. In case the column that has the NOT NULL attribute and does not have a
default value, and you don’t specify the value in the REPLACE statement, MySQL will raise an error. This is
a difference between the REPLACE and INSERT statements.
For example, in the following statement, we specify only the value for the name column, not
the population column. MySQL raises an error message. Because the population column does not
accept a NULL value and we did not specify a default value for it when we defined the cities table.

1 REPLACE INTO cities(name)


2 VALUES('Houston');

This is the error message that MySQL issued:

1 Error Code: 1364. Field 'population' doesn't have a default value

MySQL REPLACE and UPDATE


The second form of REPLACE statement is similar to the UPDATE statement as follows:

1 REPLACE INTO table


2 SET column1 = value1,
3 column2 = value2;

Notice that there is no WHERE clause in the REPLACE statement.

For example, if you want to update the population of the Phoenix city to 1768980 , you use
the REPLACE statement as follows:

1 REPLACE INTO cities


2 SET id = 4,
3 name = 'Phoenix',
4 population = 1768980;

Unlike the UPDATE statement, if you don’t specify the value for the column in the SET clause,
the REPLACE statement will use the default value of that column.

1 SELECT
2 *
3 FROM
4 cities;

MySQL REPLACE INTO and SELECT


The third form of REPLACE statement is similar to INSERT INTO SELECT statement:

1 REPLACE INTO table_1(column_list)


2 SELECT column_list
3 FROM table_2
4 WHERE where_condition;

Suppose, you want to copy the city with id value 1, you use the REPLACE INTO SELECT statement as the
following query:

1 REPLACE INTO cities(name,population)


2 SELECT name,population FROM cities
3 WHERE id = 1;

MySQL REPLACE statement usages


There are several important points you need to know when you use the REPLACE statement:

 If you develop an application that supports not only MySQL database but also other relational
database management systems (RDBMS), you should avoid using the REPLACE statement because
other RDBMS may not support it. Instead, you can use the combination of
the DELETE and INSERT statements within a transaction.

 If you are using the REPLACE statement in the table that has triggers and the deletion of duplicate-
key error occurs, the triggers will be fired in the following sequence: BEFORE INSERT BEFORE
DELETE , AFTER DELETE , AFTER INSERT in case the REPLACE statement deletes current row and
inserts the new row. In case the REPLACE statement updates the current row, the BEFORE
UPDATE and AFTER UPDATE triggers are fired.

In this tutorial, you’ve learned different forms of REPLACE statement to insert or update data in tables.

MySQL Prepared Statement


Summary: in this tutorial, you will learn how to use MySQL prepared statement to make your queries
execute faster and more secure.

Introduction to MySQL Prepared Statement


Prior MySQL version 4.1, the query is sent to the MySQL server in the textual format. In turn, MySQL
returns the data to the client using textual protocol. MySQL has to fully parse the query and transforms the
result set into a string before returning it to the client.

The textual protocol has serious performance implication. To resolve this problem, MySQL added a new
feature called prepared statement since version 4.1.

The prepared statement takes advantage of client/server binary protocol. It passes query that contains
placeholders (?) to the MySQL server as the following example:
1 SELECT *
2 FROM products
3 WHERE productCode = ?;

When MySQL executes this query with different productcode values, it does not have to parse the query
fully. As a result, this helps MySQL execute the query faster, especially when MySQL executes the query
multiple times. Because the prepared statement uses placeholders (?), this helps avoid many variants of
SQL injection hence make your application more secure.

MySQL prepared statement usage


In order to use MySQL prepared statement, you need to use other three MySQL statements as follows:

 PREPARE – Prepares statement for execution.


 EXECUTE – Executes a prepared statement preparing by a PREPARE statement.
 DEALLOCATE PREPARE – Releases a prepared statement.

The following diagram illustrates how to use the prepared statement:

MySQL prepared statement example


Let’s take a look at an example of using the MySQL prepared statement.

1 PREPARE stmt1 FROM 'SELECT productCode, productName


2 FROM products
3 WHERE productCode = ?';
4
5 SET @pc = 'S10_1678';
6 EXECUTE stmt1 USING @pc;
7
8 DEALLOCATE PREPARE stmt1;

First, we used the PREPARE statement to prepare a statement for execution. We used
the SELECT statement to query product data from the products table based on a specified product
code. We used a question mark (?) as a placeholder for the product code.

Next, we declared a product code variable @pc and set it values to S10_1678 .
Then, we used the EXECUTE statement to execute the prepared statement with the product code
variable @pc .

Finally, we used the DEALLOCATE PREPARE to release the prepared statement.


In this tutorial, we have shown you how to use MySQL prepared statement to execute a query with
placeholders to improve the speed of the query and make your query more secure.

Section 10. MySQL transaction


 MySQL transaction – learn about MySQL transactions, and how to use COMMIT and ROLLBACK to
manage transactions in MySQL.

 MySQL table locking – learn how to use MySQL locking for cooperating table access between
sessions.

MySQL Transaction
Summary: in this tutorial, you will learn about MySQL transaction and how to use MySQL COMMIT
statement and MySQL ROLLBACK statement to manage transactions in MySQL.

Introducing to MySQL Transaction


To understand what a transaction in MySQL is, let’s take a look at an example of adding a new sales
order in our sample database. The steps of adding a sales order are as described as follows:

 Query the latest sales order number from the orders table, and use the next sales order number as
the new sales order number.

 Insert a new sales order into the orders table for a given customer.

 Insert new sales order items into the orderdetails table.

 Get data from both table orders and orderdetails tables to confirm the changes

Now imagine what would happen to your data if one or more steps above fail because of database failure
such as table lock security? If the step of adding order items into orderdetails table failed, you would
have an empty sales order in your system without knowing it. Your data may not be integrity and the effort
you have to spend to fix it is tremendous.

How do you solve this problem? That’s why the transaction processing comes to the rescue. MySQL
transaction enables you to execute a set of MySQL operations to ensure that the database never contains
the result of partial operations. In a set of operations, if one of them fails, the rollback occurs to restore the
database. If no error occurred, the entire set of statements is committed to the database.

Using MySQL Transaction


Let’s review the most important MySQL transaction statements before we are using them for the adding
sales order in the example above.
To start a transaction, you use the START TRANSACTION statement. To undo MySQL statements you use
the ROLLBACK statement.

Notice that there are some SQL statements, mostly data definition statements, that you cannot use within
a transaction:

1 CREATE / ALTER / DROP DATABASE


2 CREATE /ALTER / DROP / RENAME / TRUNCATE TABLE
3 CREATE / DROP INDEX
4 CREATE / DROP EVENT
5 CREATE / DROP FUNCTION
6 CREATE / DROP PROCEDURE
7…

To write the changes into the database within a transaction, you use the COMMIT statement. It is important
to note that MySQL automatically commits the changes to the database by default.

To force MySQL not to commit changes automatically, you use the following statement:

1 SET autocommit = 0;

MySQL transaction example


In order to use MySQL transaction, you first have to break your MySQL statements into logical portions
and determine when data should be committed or rolled back.

Let’s take a look an example of using MySQL transaction to add new sales order into our sample
database above and add the transaction processing steps:

 Start a transaction using START TRANSACTION statement.


 Get latest sales order number from the orders table, and use the next sales order number as the
new sales order number.
 Insert a new sales order into the orders table for a given customer.
 Insert new sales order items into the orderdetails table.
 Commit changes using COMMIT statement.
 Get data from both table orders and orderdetails tables to confirm the changes

The following is the script that performs the above steps:

1 -- start a new transaction


2 start transaction;
3
4 -- get latest order number
5 select @orderNumber := max(orderNUmber)
6 from orders;
7 -- set new order number
8 set @orderNumber = @orderNumber + 1;
9
10 -- insert a new order for customer 145
11 insert into orders(orderNumber,
12 orderDate,
13 requiredDate,
14 shippedDate,
15 status,
16 customerNumber)
17 values(@orderNumber,
18 now(),
19 date_add(now(), INTERVAL 5 DAY),
20 date_add(now(), INTERVAL 2 DAY),
21 'In Process',
22 145);
23 -- insert 2 order line items
24 insert into orderdetails(orderNumber,
25 productCode,
26 quantityOrdered,
27 priceEach,
28 orderLineNumber)
29 values(@orderNumber,'S18_1749', 30, '136', 1),
30 (@orderNumber,'S18_2248', 50, '55.09', 2);
31 -- commit changes
32 commit;
33
34 -- get the new inserted order
35 select * from orders a
36 inner join orderdetails b on a.ordernumber = b.ordernumber
37 where a.ordernumber = @ordernumber;

In this tutorial, you’ve learned how to use MySQL transaction statements that include START
TRANSACTION COMMI, and ROLLBACK to manage transactions in MySQL to protect data integrity.

MySQL Table Locking


In this tutorial, you will learn how to use MySQL locking for cooperating table access between sessions.

MySQL allows a client session to acquire a table lock explicitly for preventing other sessions from
accessing the table during a specific period. A client session can acquire or release table locks only for
itself. It cannot acquire or release table locks for other sessions.

Before going into detail, we will create a sample database named sampledb that includes a simple table
named tbl to practice the table locking statements.

1 CREATE DATABASE sampledb;

1 CREATE TABLE tbl (


2 id int(11) NOT NULL AUTO_INCREMENT,
3 col int(11) NOT NULL,
4 PRIMARY KEY (id)
5 );

LOCK and UNLOCK TABLES syntax


The simple form of acquiring a lock for a table is as follows:

1 LOCK TABLES table_name [READ | WRITE]

You put the name of the table after the LOCK TABLES keywords and followed by a lock type. MySQL
provides two lock types: READ and WRITE . We will go into detail of each lock type in the next section.

To release a lock for a table, you use the following statement:

1 UNLOCK TABLES;

Table locking for READ


A READ lock for a table has the following features:

 A READ lock for a table can be acquired by multiple sessions at the same time. In addition, other
sessions can read data from the table without acquiring the lock.

 The session that holds the READ lock can only read data from the table, but not write. In addition,
other sessions cannot write data into the table until the READ lock is released. The write operations
from another session will be put into the waiting states until the READ lock is released.

 If the session is terminated normally or abnormally, MySQL will release all the locks implicitly. This
is also relevant for the WRITE lock.

Let’s take a look at how the READ lock works in the following scenario.

First, connect to the sampledb database. To find out the current connection id, you use
the CONNECTION_ID() function as follows:

1 SELECT CONNECTION_ID();

Then, insert a new row into the tbl table.


1 INSERT INTO tbl(col) VALUES(10);

Next, retrieve all rows from the same table.

1 SELECT * FROM tbl;

After that, to acquire a lock, you use the LOCK TABLE statement.

1 LOCK TABLE tbl READ;

Finally, in the same session, if you try to insert a new row into the tbl table, you will get an error
message.

1 INSERT INTO tbl(col) VALUES(11);

1 Error Code: 1099. Table 'tbl' was locked with a READ lock and can't be updated.

So the once READ lock is acquired, you cannot write data into the table within the same session. Let’s
check the READ lock from a different session.

First, connect to the sampledb and check the connection id:

1 SELECT CONNECTION_ID();

Then, retrieve data from the tbl .

1 SELECT * FROM tbl;

Next, insert a new row into the tbl table from the second session.

1 INSERT INTO tbl(col) VALUES(20);


The insert operation from the second session is in the waiting state because a READ lock already
acquired on the tbl table by the first session and it has not released yet.

You can see the detailed information from the SHOW PROCESSLIST statement.

1 SHOW PROCESSLIST;

After that, go back to the first session and release the lock by using the UNLOCK TABLES statement.
After you release the READ lock from the first session, the INSERT operation in the second session
executed.

Finally, check it the data of the tbl table to see if the INSERT operation from the second session really
executed.

1 SELECT * FROM tbl;

MySQL table locking for WRITE


The table lock for WRITE has the following features:

 Only session that holds the lock of a table can read and write data from the table.
 Other sessions cannot read and write from the table until the WRITE lock is released.
Let’s go into detail to see how the WRITE lock works.

First, acquire a WRITE lock from the first session.

1 LOCK TABLE tbl WRITE;

Then, insert a new row into the tbl table.

1 INSERT INTO tbl(col) VALUES(11);


It works.

Next, read data from the tbl table.

1 SELECT * FROM tbl;

It is fine.

After that, from the second session, try to write and read data:

1 INSERT INTO tbl(col) VALUES(21);


2
3 SELECT * FROM tbl;

MySQL puts those operations into a waiting state. You can check it using the SHOW
PROCESSLIST statement.

1 SHOW PROCESSLIST

Finally, release the lock from the first session.

1 UNLOCK TABLES;

You will see all pending operations from the second session executed.
In this tutorial, we have shown you how to lock and unlock tables for READ and WRITE to cooperate table
access between sessions.

Section 11. Managing MySQL databases and


tables
This section shows you how to manage the most important database objects in MySQL including
database and tables.

 Managing database in MySQL – you will learn various statements to manage MySQL databases
including creating a new database, removing an existing database, selecting a database, and listing
all databases.

 Understanding MySQL Table Types – it is essential to understand the features of each table type so
that you can use them effectively to maximize the performance of your databases.

 CREATE TABLE – show you how to create new tables in a database using CREATE
TABLE statement.

 MySQL sequence – show you how to use a sequence to generate unique numbers automatically for
the primary key column of a table.

 ALTER TABLE – learn how to use the ALTER TABLE statement to change existing table’s structure.

 Renaming table – show you how to rename a table using RENAME TABLE statement.

 Removing a column from a table – show you how to use the ALTER TABLE DROP COLUMN statement
to remove one or more columns from a table.

 Adding a new column to a table – show you how to add one or more columns to an existing table
using ALTER TABLE ADD COLUMN statement.

 DROP TABLE – show you how to remove existing tables using DROP TABLE statement.

 MySQL temporary table – discuss MySQL temporary table and show you how to manage temporary
tables.

 TRUNCATE TABLE – show you how to use the TRUNCATE TABLE statement to delete all data in a
table fast.

Manage Database in MySQL


Summary: in this tutorial, you will learn how to manage databases in MySQL. You will learn how to create
new databases, remove existing databases, and display all databases in the MySQL database server.

Let’s start creating a new database in MySQL.


Creating Database
Before doing anything else with the data, you need to create a database. A database is a container of
data. It stores contacts, vendors, customers or any kind of data that you can think of. In MySQL, a
database is a collection of objects that are used to store and manipulate data such as tables, database
views, triggers, stored procedures, etc.

To create a database in MySQL, you use the CREATE DATABASE statement as follows:

1 CREATE DATABASE [IF NOT EXISTS] database_name;

Let’s examine the CREATE DATABASE statement in greater detail:

 Followed by the CREATE DATABASE statement is database name that you want to create. It is
recommended that the database name should be as meaningful and descriptive as possible.

 The IF NOT EXISTS is an optional clause of the statement. The IF NOT EXISTS clause prevents
you from an error of creating a new database that already exists in the database server. You cannot
have 2 databases with the same name in a MySQL database server.

For example, to create classicmodels database, you can execute the CREATE DATABASE statement as
follows:

1 CREATE DATABASE classicmodels;

After executing this statement, MySQL returns a message to notify that the new database has been
created successfully or not.

Displaying Databases
The SHOW DATABASES statement displays all databases in the MySQL database server. You can use
the SHOW DATABASES statement to check the database that you’ve created or to see all the databases on
the database server before you create a new database, for example:

1 SHOW DATABASES;

We have three databases in the MySQL database server. The information_schema and mysql are the
default databases that are available when we install MySQL, and the classicmodels is the new
database that we have created.

Selecting a database to work with


Before working with a particular database, you must tell MySQL which database you want to work with by
using the USE statement.

1 USE database_name;

You can select the classicmodels sample database using the USE statement as follows:

1 USE classicmodels;

From now all operations such as querying data, create new tables or calling stored procedures which you
perform, will take effects on the current database i.e., classicmodels .

Removing Databases
Removing database means you delete the database physically. All the data and associated objects inside
the database are permanently deleted and this cannot be undone. Therefore, it is very important to
execute this query with extra cautions.

To delete a database, you use the DROP DATABASE statement as follows:

1 DROP DATABASE [IF EXISTS] database_name;

Followed the DROP DATABASE is the database name that you want to remove. Similar to the CREATE
DATABASE statement, the IF EXISTS is an optional part of the statement to prevent you from removing a
database that does not exist in the database server.

If you want to practice with the DROP DATABASE statement, you can create a new database, make sure
that it is created, and remove it. Let’s look at the following queries:

1 CREATE DATABASE IF NOT EXISTS temp_database;


2 SHOW DATABASES;
3 DROP DATABASE IF EXISTS temp_database;

The sequence of three statements is as follows:

1. First, we created a database named temp_database using the CREATE DATABASE statement.

2. Second, we displayed all databases using the SHOW DATABASES statement.

3. Third, we removed the temp_database using the DROP DATABASE statement.

In this tutorial, you’ve learned various statements to manage databases in MySQL including creating a
new database, removing an existing database, selecting a database to work with, and displaying all
databases in a MySQL database server.
Understanding MySQL Table Types, or Storage
Engines
Summary: in this tutorial, you will learn various MySQL table types or storage engines. It is essential to
understand the features of each table type in MySQL so that you can use them effectively to maximize the
performance of your databases.

MySQL provides various storage engines for its tables as below:

 MyISAM

 InnoDB

 MERGE

 MEMORY (HEAP)

 ARCHIVE

 CSV

 FEDERATED

Each storage engine has its own advantages and disadvantages. It is crucial to understand each storage
engine features and choose the most appropriate one for your tables to maximize the performance of the
database. In the following sections, we will discuss each storage engine and its features so that you can
decide which one to use.

MyISAM
MyISAM extends the former ISAM storage engine. The MyISAM tables are optimized for compression and
speed. MyISAM tables are also portable between platforms and operating systems.

The size of MyISAM table can be up to 256TB, which is huge. In addition, MyISAM tables can be
compressed into read-only tables to save spaces. At startup, MySQL checks MyISAM tables for corruption
and even repairs them in a case of errors. The MyISAM tables are not transaction-safe.

Before MySQL version 5.5, MyISAM is the default storage engine when you create a table without
specifying the storage engine explicitly. From version 5.5, MySQL uses InnoDB as the default storage
engine.

InnoDB
The InnoDB tables fully support ACID-compliant and transactions. They are also optimal for performance.
InnoDB table supports foreign keys, commit, rollback, roll-forward operations. The size of an InnoDB table
can be up to 64TB.
Like MyISAM, the InnoDB tables are portable between different platforms and operating systems. MySQL
also checks and repairs InnoDB tables, if necessary, at startup.

MERGE
A MERGE table is a virtual table that combines multiple MyISAM tables that have a similar structure into
one table. The MERGE storage engine is also known as the MRG_MyISAM engine. The MERGE table
does not have its own indexes; it uses indexes of the component tables instead.

Using MERGE table, you can speed up performance when joining multiple tables. MySQL only allows you
to perform SELECT, DELETE, UPDATE and INSERT operations on the MERGE tables. If you use DROP
TABLE statement on a MERGE table, only MERGE specification is removed. The underlying tables will
not be affected.

Memory
The memory tables are stored in memory and use hash indexes so that they are faster than MyISAM
tables. The lifetime of the data of the memory tables depends on the uptime of the database server. The
memory storage engine is formerly known as HEAP.

Archive
The archive storage engine allows you to store a large number of records, which for archiving purpose,
into a compressed format to save disk space. The archive storage engine compresses a record when it is
inserted and decompress it using the zlib library as it is read.

The archive tables only allow INSERT and SELECT statements. The ARCHIVE tables do not support
indexes, so it is required a full table scanning for reading rows.

CSV
The CSV storage engine stores data in comma-separated values (CSV) file format. A CSV table brings a
convenient way to migrate data into non-SQL applications such as spreadsheet software.

CSV table does not support NULL data type. In addition, the read operation requires a full table scan.

FEDERATED
The FEDERATED storage engine allows you to manage data from a remote MySQL server without using
cluster or replication technology. The local federated table stores no data. When you query data from a
local federated table, the data is pulled automatically from the remote federated tables.

Choosing MySQL Table Types


You can download the following checklist to choose the most appropriate storage engine, or table type,
based on various criteria.
MySQL Storage Engine Feature Summary (109.25 kB)17136 downloads

In this tutorial, you have learned various storage engines or table types available in MySQL.

Creating Tables Using MySQL CREATE TABLE


Statement
Summary: in this tutorial, we will show you how to create new tables in a database using MySQL
CREATE TABLE statement.

MySQL CREATE TABLE syntax


In order to create a new table within a database, you use the MySQL CREATE TABLE statement.
The CREATE TABLE statement is one of the most complex statement in MySQL.

The following illustrates the syntax of the CREATE TABLE statement in the simple form:

1 CREATE TABLE [IF NOT EXISTS] table_name(


2 column_list
3 ) engine=table_type

Let’s examine the syntax in greater detail:

 First, you specify the name of the table that you want to create after the CREATE TABLE clause. The
table name must be unique within a database. The IF NOT EXISTS is an optional part of the
statement that allows you to check if the table that you are creating already exists in the database. If
this is the case, MySQL will ignore the whole statement and will not create any new table. It is highly
recommended that you use IF NOT EXISTS in every CREATE TABLE statement for preventing from
an error of creating a new table that already exists.

 Second, you specify a list of columns for the table in the column_list section. Columns are
separated by a comma (,). We will show you how to define columns in more detail in the next
section.

 Third, you need to specify the storage engine for the table in the engine clause. You can use any
storage engine such as InnoDB, MyISAM, HEAP, EXAMPLE, CSV, ARCHIVE, MERGE
FEDERATED or NDBCLUSTER. If you don’t declare the storage engine explicitly, MySQL will use
InnoDB by default.

InnoDB became the default storage engine since MySQL version 5.5. The InnoDB table type brings many
benefits of relational database management system such as ACID transaction, referential integrity, and
crash recovery. In previous versions, MySQL used MyISAM as the default storage engine.

To define a column for the table in the CREATE TABLE statement, you use the following syntax:

1 column_name data_type[size] [NOT NULL|NULL] [DEFAULT value]


2 [AUTO_INCREMENT]
The most important components of the syntax above are:

 The column_name specifies the name of the column. Each column has a specific data type and the
size e.g., VARCHAR(255)

 The NOT NULL or NULL indicates that the column accepts NULL value or not.

 The DEFAULT value is used to specify the default value of the column.

 The AUTO_INCREMENT indicates that the value of the column is increased automatically whenever a
new row is inserted into the table. Each table has one and only one AUTO_INCREMENT column.

If you want to set particular columns of the table as the primary key, you use the following syntax:

1 PRIMARY KEY (col1,col2,...)

Example of MySQL CREATE TABLE statement


Let’s practice with an example of creating a new table named tasks in our sample database as follows:
You can use the CREATE TABLE statement to create the tasks table as follows:

1 CREATE TABLE IF NOT EXISTS tasks (


2 task_id INT(11) NOT NULL AUTO_INCREMENT,
3 subject VARCHAR(45) DEFAULT NULL,
4 start_date DATE DEFAULT NULL,
5 end_date DATE DEFAULT NULL,
6 description VARCHAR(200) DEFAULT NULL,
7 PRIMARY KEY (task_id)
8 ) ENGINE=InnoDB

In this tutorial, you have learned how to use MySQL CREATE TABLE statement to create a new table in a
database.
MySQL Sequence
Summary: in this tutorial, we will show you how to use MySQL sequence to automatically generate
unique numbers for ID columns of tables.

Creating MySQL sequence


In MySQL, a sequence is a list of integers generated in the ascending order i.e., 1,2,3… Many
applications need sequences to generate unique numbers mainly for identification e.g., customer ID in
CRM, employee numbers in HR, equipment numbers in services management system, etc.

To create a sequence in MySQL automatically, you set the AUTO_INCREMENT attribute to a column, which
typically is a primary key column.

The following rules are applied when you use the AUTO_INCREMENT attribute:

 Each table has only one AUTO_INCREMENT column whose data type is typically the integer.

 The AUTO_INCREMENT column must be indexed, which means it can be either PRIMARY
KEY or UNIQUE index.

 The AUTO_INCREMENT column must have a NOT NULL constraint. When you set
the AUTO_INCREMENT attribute to a column, MySQL automatically add the NOT NULL constraint to
the column implicitly.

Creating MySQL sequence example


The following statement creates a table named employees that has the emp_no column is
an AUTO_INCREMENT column:

1 CREATE TABLE employees(


2 emp_no INT(4) AUTO_INCREMENT PRIMARY KEY,
3 first_name VARCHAR(50),
4 last_name VARCHAR(50)
5 );

How MySQL sequence works


The AUTO_INCREMENT column has the following attributes:

 The starting value of an AUTO_INCREMENT column is 1 and it is increased by 1 when you insert
a NULL value into the column or when you omit its value in the INSERT statement.

 To obtain the last generated sequence number, you use the LAST_INSERT_ID() function. We often
use the last insert ID for the subsequent statements e.g., insert data into the tables. The last
generated sequence is unique across sessions. In other words, if another connection generates a
sequence number, from your connection you can obtain it by using the LAST_INSERT_ID() function.
 If you insert a new row into a table and specify a value for the sequence column, MySQL will insert
the sequence number if the sequence number does not exist in the column or issue an error if it
already exists. If you insert a new value that is greater than the next sequence number, MySQL will
use the new value as the starting sequence number and generate a unique sequence number
greater than the current one for the next usage. This creates gaps in the sequence.

 If you use the UPDATE statement to update values in the AUTO_INCREMENT column to a value that
already exists, MySQL will issue a duplicate-key error if the column has a unique index. If you
update an AUTO_INCREMENT column to a value that is greater than the existing values in the column,
MySQL will use the next number of the last insert sequence number for the next row. For example, if
the last insert sequence number is 3, you update it to 10, the sequence number for the new row is 4.

 If you use the DELETE statement to delete the last inserted row, MySQL may or may not reuse the
deleted sequence number depending on the storage engine of the table. A MyISAM table does not
reuse the deleted sequence numbers if you delete a row e.g., the last insert id in the table is 10, if
you remove it, MySQL still generates the next sequence number which is 11 for the new row.
Similar to MyISAM tables, InnoDB tables do not reuse sequence number when rows are deleted.

Once you set the AUTO_INCREMENT attribute for a column, you can reset the auto increment value in
various ways e.g., by using the ALTER TABLE statement.

Let’s take a look at some example to get a better understanding of the MySQL sequence.

First, insert two new rows into the employees table:

1 INSERT INTO employees(first_name,last_name)


2 VALUES('John','Doe'),
3 ('Mary','Jane');

Second, select data from the employees table:

1 SELECT * FROM employees;

Third, delete the second employee whose emp_no is 2:

1 DELETE FROM employees


2 WHERE emp_no = 2;

Fourth, insert a new employee:

1 INSERT INTO employees(first_name,last_name)


2
VALUES('Jack','Lee');

Because the storage engine of the employees table is InnoDB, it does not reuse the deleted sequence
number. The new row has emp_no 3.

Fifth, update an existing employee with emp_no 3 to 1:

1 UPDATE employees
2 SET first_name = 'Joe',
3 emp_no = 1
4 WHERE emp_no = 3;

MySQL issued an error of duplicate entry for the primary key. Let’s fix it.

1 UPDATE employees
2 SET first_name = 'Joe',
3 emp_no = 10
4 WHERE emp_no = 3;

Sixth, insert a new employee after updating the sequence number to 10:

1 INSERT INTO employees(first_name,last_name)


2 VALUES('Wang','Lee');

The next sequence number of the last insert is number 4, therefore, MySQL uses number 4 for the new
row instead of 11.

In this tutorial, you have learned how to use MySQL sequence to generate unique numbers for a primary
key column by assigning the AUTO_INCREMENT attribute to the column.
Using MySQL ALTER TABLE To Change Table
Structure
Summary: in this tutorial, you will learn about the MySQL ALTER TABLE statement that changes
existing table structure such as adding or removing columns, changing column attributes, etc.

Introduction to MySQL ALTER TABLE statement


You use the ALTER TABLE statement to change the structure of existing tables. The ALTER
TABLE statement allows you to add a column, drop a column, change the data type of column,
add primary key, rename table, and many more. The following illustrates the ALTER TABLE statement
syntax:

1 ALTER TABLE table_name action1[,action2,…]

To change the structure an existing table:

 First, you specify the table name, which you want to change, after the ALTER TABLE clause.

 Second, you list a set of actions that you want to apply to the table. An action can be anything such
as adding a new column, adding primary key, renaming table, etc. The ALTER TABLE statement
allows you to apply multiple actions in a single ALTER TABLE statement, each action is separated by
a comma (,).

Let’s create a new table for practicing the ALTER TABLE statement.
We’re going to create a new table named tasks in the sample database. The following is the script for
creating the tasks table.

1 CREATE TABLE tasks (


2 task_id INT NOT NULL,
3 subject VARCHAR(45) NULL,
4 start_date DATE NULL,
5 end_date DATE NULL,
6 description VARCHAR(200) NULL,
7 PRIMARY KEY (task_id),
8 UNIQUE INDEX task_id_unique (task_id ASC)
9 );
Changing columns using MySQL ALTER TABLE statement
Using MySQL ALTER TABLE statement to set auto-increment attribute for a
column
Suppose you want the value of the task_id column to be increased automatically by one whenever
you insert a new row into the tasks table. To do this, you use the ALTER TABLE statement to set the
attribute of the task_id column to AUTO_INCREMENT as follows:

1 ALTER TABLE tasks


2 CHANGE COLUMN task_id task_id INT(11) NOT NULL AUTO_INCREMENT;

You can verify the change by inserting some rows to the tasks table.

1 INSERT INTO tasks(subject,


2 start_date,
3 end_date,
4 description)
5 VALUES('Learn MySQL ALTER TABLE',
6 Now(),
7 Now(),
8 'Practicing MySQL ALTER TABLE statement');
9
10 INSERT INTO tasks(subject,
11 start_date,
12 end_date,
13 description)
14 VALUES('Learn MySQL CREATE TABLE',
15 Now(),
16 Now(),
17 'Practicing MySQL CREATE TABLE statement');

And you can query data to see if the value of the task_id column is increased by 1 each time you
insert a new row:

1 SELECT
2 task_id, description
3 FROM
4 tasks;
Using MySQL ALTER TABLE statement to add a new column into a table
Because of the new business requirements, you need to add a new column called complete to store the
percentage of completion for each task in the tasks table. In this case, you can use the ALTER TABLE to
add a new column to the tasks table as follows:

1 ALTER TABLE tasks


2 ADD COLUMN complete DECIMAL(2,1) NULL
3 AFTER description;

Using MySQL ALTER TABLE to drop a column from a table


Suppose you don’t want to store the description of tasks in the tasks table and you have to remove it.
The following statement allows you to remove the description column of the tasks table:

1 ALTER TABLE tasks


2 DROP COLUMN description;

Renaming table using MySQL ALTER TABLE statement


You can use the ALTER TABLE statement to rename a table. Notice that before renaming a table, you
should take a serious consideration to understand if the change impacts both database and application
layers.

The following statement renames the tasks table to the work_items table:

1 ALTER TABLE tasks


2 RENAME TO work_items;

In this tutorial, you’ve learned how to use the MySQL ALTER TABLE statement to change existing table
structure and to rename the table.

How To Rename Table Using MySQL RENAME


TABLE Statement
Summary: in this tutorial, you will learn how to rename tables using MySQL RENAME TABLE statement
and ALTER TABLE statement.
Introduction to MySQL RENAME TABLE statement
Because business requirements change, we need to rename the current table to a new one to better
reflect the new situation. MySQL provides us with a very useful statement that changes the name of one
or more tables.

To change one or more tables, we use the RENAME TABLE statement as follows:

1 RENAME TABLE old_table_name TO new_table_name;

The old table ( old_table_name ) must exist, and the new table ( new_table_name ) must not. If the new
table new_table_name does exist, the statement will fail.

In addition to the tables, we can use the RENAME TABLE statement to rename views.

Before we execute the RENAME TABLE statement, we must ensure that there is no active transactions
or locked tables.

Note that you cannot use the RENAME TABLE statement to rename a temporary table, but you can use
the ALTER TABLE statement to rename a temporary table.

In terms of security, any existing privileges that we granted to the old table must be manually migrated to
the new table.

Before renaming a table, you should evaluate the impact thoroughly. For example, you should investigate
which applications are using the table. If the name of the table changes, so the application code that
refers to the table name needs to be changed as well. In addition, you must manually adjust other
database objects such as views, stored procedures, triggers, foreign key constraints, etc., that reference
to the table. We will discuss this in more detail in the following examples.

MySQL RENAME TABLE examples


First, we create a new database named hr that consists of two tables: employees and departments for
the demonstration.

1 CREATE DATABASE IF NOT EXISTS hr;

1 CREATE TABLE departments (


2 department_id INT AUTO_INCREMENT PRIMARY KEY,
3 dept_name VARCHAR(100)
4 );
5
6 CREATE TABLE employees (
7 id int AUTO_INCREMENT primary key,
8 first_name varchar(50) not null,
9 last_name varchar(50) not null,
10 department_id int not null,
11 FOREIGN KEY (department_id)
12 REFERENCES departments (department_id)
13 );

Second, we insert sample data into both employees and departments tables:

1 INSERT INTO departments(dept_name)


2 VALUES('Sales'),('Markting'),('Finance'),('Accounting'),('Warehouses'),('Production');

1 INSERT INTO employees(first_name,last_name,department_id)


2 VALUES('John','Doe',1),
3 ('Bush','Lily',2),
4 ('David','Dave',3),
5 ('Mary','Jane',4),
6 ('Jonatha','Josh',5),
7 ('Mateo','More',1);

Third, we review our data in the departments and employees tables:

1 SELECT
2 department_id, dept_name
3 FROM
4 departments;

1 SELECT
2 id, first_name, last_name, department_id
3 FROM
4 employees;
Renaming a table referenced by a view
If the table that you are going to rename is referenced by a view, the view will become invalid if you
rename the table, and you have to adjust the view manually.

For example, we create a view named v_employee_info based on


the employees and departments tables as follows:

1 CREATE VIEW v_employee_info as


2 SELECT
3 id, first_name, last_name, dept_name
4 from
5 employees
6 inner join
7 departments USING (department_id);

The views use the inner join clause to join departments and employees tables.

The following SELECT statement returns all data from the v_employee_info view.

1 SELECT
2 *
3 FROM
4 v_employee_info;

Now we rename the employees to people table and query data from the v_employee_info view again.

1 RENAME TABLE employees TO people;


1 SELECT
2 *
3 FROM
4 v_employee_info;

MySQL returns the following error message:

1 Error Code: 1356. View 'hr.v_employee_info' references invalid table(s) or


2 column(s) or function(s) or definer/invoker of view lack rights to use them

We can use the CHECK TABLE statement to check the status of the v_employee_info view as follows:

1 CHECK TABLE v_employee_info;

We need to manually change the v_employee_info view so that it refers to the people table instead of
the employees table.

Renaming a table that referenced by a stored procedure


In case the table that you are going to rename is referenced by a stored procedure, you have to manually
adjust it like you did with the view.

First, rename the people table back to the employees table.

1 RENAME TABLE people TO employees;

Then, create a new stored procedure named get_employee that refers to the employees table.

1 DELIMITER $$
2
3 CREATE PROCEDURE get_employee(IN p_id INT)
4
5 BEGIN
6 SELECT first_name
7 ,last_name
8 ,dept_name
9 FROM employees
10 INNER JOIN departments using (department_id)
11 WHERE id = p_id;
12 END $$
13
14 DELIMITER;

Next, we execute the get_employee table to get the data of the employee with id 1 as follows:

1 CALL get_employee(1);

After that, we rename the employees to the people table again.

1 RENAME TABLE employees TO people;

Finally, we call the get_employee stored procedure to get the information of employee with id 2:

1 CALL get_employee(2);
MySQL returns the following error message:

1 Error Code: 1146. Table 'hr.employees' doesn't exist

To fix this, we must manually change the employees table in the stored procedure to people table.

Renaming a table that has foreign keys referenced to


The departments table links to the employees table using the department_id column.

The department_i d column in the employees table is the foreign key that references to
the departments table.

If we rename the departments table, all the foreign keys that point to the departments table will not be
automatically updated. In such cases, we must drop and recreate the foreign keys manually.

1 RENAME TABLE departments TO depts;

We delete a department with id 1, because of the foreign key constraint, all rows in the people table
should be also deleted. However, we renamed the departments table to the depts table without
updating the foreign key manually, MySQL returns an error as illustrated below:

1 DELETE FROM depts


2 WHERE
3 department_id = 1;

Error Code: 1451. Cannot delete or update a parent row: a foreign key constraint fails (`hr`.`people`, CONSTRAINT
1
`people_ibfk_1` FOREIGN KEY (`department_id`) REFERENCES `depts` (`department_id`))
Renaming multiple tables
We can also use the RENAME TABLE statement to rename multiple tables at a time. See the following
statement:

1 RENAME TABLE old_table_name_1 TO new_table_name_2,


2 old_table_name_2 TO new_table_name_2,...

The following statement renames the people and depts tables to employees and departments tables:

1 RENAME TABLE depts TO departments,


2 people TO employees;

Note the RENAME TABLE statement is not atomic. It means that if any errors occurred, MySQL does a
rollback all renamed tables to their old names.

Renaming tables using ALTER TABLE statement


We can rename a table using the ALTER TABLE statement as follows:

1 ALTER TABLE old_table_name


2 RENAME TO new_table_name;

The ALTER TABLE statement can rename a temporary table while the RENAME TABLE statement cannot.

Renaming temporary table example


First, we create a temporary table that contains all unique last names which come from
the last_name column of the employees table:

1 CREATE TEMPORARY TABLE lastnames


2 SELECT DISTINCT last_name from employees;

Second, we use the RENAME TABLE to rename the lastnames table:

1 RENAME TABLE lastnames TO unique_lastnames;

MySQL returns the following error message:

1 Error Code: 1017. Can't find file: '.\hr\lastnames.frm' (errno: 2 - No such file or directory)

Third, we use the ALTER TABLE statement to rename the lastnames table.

1 ALTER TABLE lastnames


2 RENAME TO unique_lastnames;

Fourth, we query data from the unique_lastnames temporary table:


1 SELECT
2 last_name
3 FROM
4 unique_lastnames;

In this tutorial, we have shown you how to rename tables using MySQL RENAME TABLE and ALTER
TABLE statements.

MySQL DROP COLUMN


Summary: in this tutorial, we will show you how to drop a column from a table using the MySQL DROP
COLUMN statement.

Introduction to MySQL DROP COLUMN statement


In some situations, you want to remove one or more columns from a table. In such cases, you use
the ALTER TABLE DROP COLUMN statement as follows:

1 ALTER TABLE table


2 DROP COLUMN column;

Let’s examine the statement in more detail:

 First, you specify the table that contains the column you want to remove after the ALTER
TABLE clause.
 Second, you put the name of the column following the DROP COLUMN clause.

Note that the keyword COLUMN is optional so you can use the shorter statement as follows:

1 ALTER TABLE table


2 DROP column;

To remove multiple columns from a table at the same time, you use the following syntax:

1 ALTER TABLE table


2
DROP COLUMN column_1,
3
DROP COLUMN column_2,
4
…;

There are some important points you should remember before you remove a column from a table:

 Removing a column from a table makes all database objects such as stored
procedures, views, triggers, etc., that depend on the column invalid. For example, you may have a
stored procedure that references to a column. When you remove the column, the stored procedure
will become invalid. To fix it, you have to manually change the stored procedure’s code manually.

 The code from other applications that depends on the removed column must be also changed,
which takes time and efforts.

 Removing a column from a large table can impact the performance of the database.

MySQL DROP COLUMN examples


First, we create a table named posts for the demonstration.

1 CREATE TABLE posts (


2 id INT AUTO_INCREMENT PRIMARY KEY,
3 title VARCHAR(255) NOT NULL,
4 excerpt VARCHAR(400),
5 content TEXT,
6 created_at DATETIME,
7 updated_at DATETIME
8 );
Second, to remove the excerpt column, you use the ALTER TABLE statement as follows:

1 ALTER TABLE posts


2 DROP COLUMN excerpt;

Third, to remove both created_at and updated_at columns at the same time, you use the following
statement:

1 ALTER TABLE posts


2 DROP COLUMN created_at,
3 DROP COLUMN updated_at;

MySQL drop a column which is a foreign key example


If you remove the column that is a foreign key, MySQL will issue an error. Let’s demonstrate the idea.

First, create a table named categories :


1 CREATE TABLE categories (
2 id INT AUTO_INCREMENT PRIMARY KEY,
3 name VARCHAR(255)
4 );

Second, add the category_id column to the posts table.

1 ALTER TABLE posts ADD COLUMN category_id INT NOT NULL;

Third, make the category_id column as a foreign key that references to the id column of
the categories table.

1 ALTER TABLE posts


2 ADD CONSTRAINT fk_cat
3 FOREIGN KEY (category_id)
4 REFERENCES categories(id) ON DELETE CASCADE;

Fourth, drop the category_id column from the posts table.

1 ALTER TABLE posts


2 DROP COLUMN category_id;

MySQL issued an error message:

1 Error Code: 1553. Cannot drop index 'fk_cat': needed in a foreign key constraint

To avoid this error, you must remove the foreign key constraint before dropping the column.

In this tutorial, we have shown you how to use MySQL DROP COLUMN statement to remove one or more
columns from a table.

How to Add Columns to a Table Using MySQL ADD


COLUMN Statement
Summary: in this tutorial, we will show you how to add a column to a table using MySQL ADD COLUMN
statement.

Introduction to MySQL ADD COLUMN statement


To add a new column to an existing table, you use the ALTER TABLE ADD COLUMN statement as follows:

1 ALTER TABLE table


2 ADD [COLUMN] column_name column_definition [FIRST|AFTER existing_column];
Let’s examine the statement in more detail.

 First, you specify the table name after the ALTER TABLE clause.

 Second, you put the new column and its definition after the ADD COLUMN clause. Note
that COLUMN keyword is optional so you can omit it.

 Third, MySQL allows you to add the new column as the first column of the table by specifying
the FIRST keyword. It also allows you to add the new column after an existing column using
the AFTER existing_column clause. If you don’t explicitly specify the position of the new column,
MySQL will add it as the last column.

To add two or more columns to a table at the same time, you use the following syntax:

1 ALTER TABLE table


2 ADD [COLUMN] column_name_1 column_1_definition [FIRST|AFTER existing_column],
3 ADD [COLUMN] column_name_2 column_2_definition [FIRST|AFTER existing_column],
4 ...;

Let’s take a look some examples of adding a new column to an existing table.

MySQL ADD COLUMN examples


First, we create a table named vendors for the demonstration purpose using the following statement:

1 CREATE TABLE IF NOT EXISTS vendors (


2 id INT AUTO_INCREMENT PRIMARY KEY,
3 name VARCHAR(255)
4 );

Second, we add a new column named phone to the vendors table. Because we specify the position of
the phone column explicitly after the name column, MySQL will obey this.

1 ALTER TABLE vendors


2 ADD COLUMN phone VARCHAR(15) AFTER name;

Third, we add a new column named vendor_group to the vendors table. At this time, we don’t specify
the new column’s position so MySQL adds the vendor_group column as the last column of
the vendors table.

1 ALTER TABLE vendors


2 ADD COLUMN vendor_group INT NOT NULL;

Let’s insert some rows into the vendors table.

1 INSERT INTO vendors(name,phone,vendor_group)


2 VALUES('IBM','(408)-298-2987',1);
3
4 INSERT INTO vendors(name,phone,vendor_group)
5 VALUES('Microsoft','(408)-298-2988',1);

We can query the data of the vendors table to see the changes.

1 SELECT
2 id, name, phone,vendor_group
3 FROM
4 vendors;

Fourth, add two more columns email and hourly_rate to the vendors table at the same time.

1 ALTER TABLE vendors


2 ADD COLUMN email VARCHAR(100) NOT NULL,
3 ADD COLUMN hourly_rate decimal(10,2) NOT NULL;

Note that both email and hourly_rate columns are assigned to NOT NULL values However,
the vendors table already has data. In such cases, MySQL will use default values for those new columns.

Let’s check the data in the vendors table.

1 SELECT
2 id, name, phone, vendor_group, email, hourly_rate
3 FROM
4 vendors;

The email column is populated with blank values, not the NULL values. And the hourly_rate column is
populated with 0.00 values.

If you accidentally add a column that already exists in the table, MySQL will issue an error. For example, if
you execute the following statement:

1 ALTER TABLE vendors


2 ADD COLUMN vendor_group INT NOT NULL;
MySQL issued an error message:

1 Error Code: 1060. Duplicate column name 'vendor_group'

For the table with a few columns, it is easy to see which columns are already there. However, with a big
table with hundred of columns, it is more difficult.

In some situations, you want to check whether a column already exists in a table before adding it.
However, there is no statement like ADD COLUMN IF NOT EXISTS available. Fortunately, you can get this
information from the columns table of the information_schema database as the following query:

1 SELECT
2 IF(count(*) = 1, 'Exist','Not Exist') AS result
3 FROM
4 information_schema.columns
5 WHERE
6 table_schema = 'classicmodels'
7 AND table_name = 'vendors'
8 AND column_name = 'phone';

In the WHERE clause, we passed three arguments: table schema or database, table name, and column
name. We used IF function to return whether the column exists or not.

In this tutorial, you have learned how to add one or more columns to a table using MySQL ADD COLUMN
statement.

Using MySQL DROP TABLE To Remove Existing


Tables
Summary: in this tutorial, we will show you how to remove existing tables using the MySQL DROP
TABLE statement.

MySQL DROP TABLE statement syntax


To remove existing tables, you use the MySQL DROP TABLE statement. The syntax of the DROP TABLE is
as follows:

1 DROP [TEMPORARY] TABLE [IF EXISTS] table_name [, table_name] ...


2 [RESTRICT | CASCADE]

The DROP TABLE statement removes a table and its data permanently from the database. In MySQL, you
can also remove multiple tables using a single DROP TABLE statement, each table is separated by a
comma (,).
The TEMPORARY flag allows you to remove temporary tables only. It is very convenient to ensure that you
do not accidentally remove non-temporary tables.

The IF EXISTS addition helps you prevent from removing non-existent tables. When you use IF
EXISTS addition, MySQL generates a NOTE, which can be retrieved by using the SHOW
WARNING statement. It is important to note that the DROP TABLE statement removes all existing tables and
issues an error message or a NOTE when you have a non-existent table in the list.

As mentioned above, the DROP TABLE statement only removes table and its data. However, it does not
remove specific user privileges associated with the table. Therefore if a table with the same name is re-
created after that, the existing privileges will apply to the new table, which may pose a security risk.

The RESTRICT and CASCADE flags are reserved for the future versions of MySQL.

Last but not least, you must have DROP privileges for the table that you want to remove.

MySQL DROP TABLE example


We are going to remove the tasks table that we created in the previous tutorial in the creating tables
using CREATE TABLE statement tutorial. In addition, we remove a non-existent table to practice with
the SHOW WARNING statement. The statement to remove the tasks table and a non-existent table with the
name nonexistent_table is as follows:

1 DROP TABLE IF EXISTS tasks, nonexistent_table;


If you check the database, you will see that the tasks table was removed. You can check the NOTE,
which is generated by MySQL because of non-existent table, by using the SHOW WARNING statement as
follows:

1 SHOW WARNINGS;

MySQL DROP TABLE with LIKE


Image you have a lot of tables whose names start with test in your database and you want to save time
by removing all of them using a single DROP TABLE statement. Unfortunately, MySQL does not provide
the DROP TABLE LIKE statement that can remove tables based on pattern matching like the following:

1 DROP TABLE LIKE '%pattern%'

However, there are some workarounds. We will discuss one of them here for your reference.

Let’s start creating test* tables for the sake of demonstration.


1 CREATE TABLE IF NOT EXISTS test1(
2 id int(11) NOT NULL AUTO_INCREMENT,
3 PRIMARY KEY(id)
4 );
5
6 CREATE TABLE IF NOT EXISTS test2 LIKE test1;
7 CREATE TABLE IF NOT EXISTS test3 LIKE test1;
8 CREATE TABLE IF NOT EXISTS test4 LIKE test1;

We’ve created four tables named test1 , test2 , test3 and test4 with the same table structure.

Suppose you want to remove all test* tables at a time, you can follow the steps below:

First, you declare two variables that accept database schema and a pattern that you want to the tables to
match:

1 -- set table schema and pattern matching for tables


2 SET @schema = 'classicmodels';
3 SET @pattern = 'test%';

Next, you need to build a dynamic DROP TABLE statement:

1 -- build dynamic sql (DROP TABLE tbl1, tbl2...;)


2 SELECT CONCAT('DROP TABLE ',GROUP_CONCAT(CONCAT(@schema,'.',table_name)),';')
3 INTO @droplike
4 FROM information_schema.tables
5 WHERE @schema = database()
6 AND table_name LIKE @pattern;

Basically, the query instructs MySQL to go to the information_schema table , which contains data on
all tables in all databases, and to concatenate all tables in the database @schema ( classicmodels ) that
matches the pattern @pattern ( test% ) with the prefix DROP TABLE . The GROUP_CONCAT
functioncreates a comma-separated list of tables.

Then, we can display the dynamic SQL to verify if it works correctly:

1 -- display the dynamic sql statement


2 SELECT @droplike;

We can see that it works as expected.

After that, we can execute the statement using prepared statement in MySQL as follows:

1 -- execute dynamic sql


2 PREPARE stmt FROM @droplike;
3 EXECUTE stmt;
4 DEALLOCATE PREPARE stmt;

For more information on MySQL prepared statement, check it out the MySQL prepared statementtutorial.

Putting it all together.

1 -- set table schema and pattern matching for tables


2 SET @schema = 'classicmodels';
3 SET @pattern = 'test%';
4
5 -- build dynamic sql (DROP TABLE tbl1, tbl2...;)
6 SELECT CONCAT('DROP TABLE ',GROUP_CONCAT(CONCAT(@schema,'.',table_name)),';')
7 INTO @droplike
8 FROM information_schema.tables
9 WHERE @schema = database()
10 AND table_name LIKE @pattern;
11
12 -- display the dynamic sql statement
13 SELECT @droplike;
14
15 -- execute dynamic sql
16 PREPARE stmt FROM @dropcmd;
17 EXECUTE stmt;
18 DEALLOCATE PREPARE stmt;

So if you want to drop multiple tables that have a specific pattern in a database, you just use the script
above to save time. All you need to do is replacing the pattern and the database
schema in @pattern and @schema variables. If you often have to deal with this task, you can always
develop a stored procedure based on the script and reuse this stored procedure.

In this tutorial, we’ve shown you how to use the DROP TABLE statement to remove existing tables in a
particular database. We also discussed about a workaround that allows you to use the DROP
TABLE statement to remove tables based on pattern matching.

MySQL Temporary Table


Summary: in this tutorial, we will discuss MySQL temporary table and show you how to create, use and
drop temporary tables.

Introduction to MySQL temporary table


In MySQL, a temporary table is a special type of table that allows you to store a temporary result set,
which you can reuse several times in a single session.
A temporary table is very handy when it is impossible or expensive to query data that requires a
single SELECT statement with JOIN clauses. In this case, you can use a temporary table to store the
immediate result and use another query to process it.

A MySQL temporary table has the following specialized features:

 A temporary table is created by using CREATE TEMPORARY TABLE statement. Notice that
the TEMPORARY keyword is added between CREATE and TABLE keywords.

 MySQL removes the temporary table automatically when the session ends or the connection is
terminated. Of course, you can use the DROP TABLE statement to remove a temporary table
explicitly when you are no longer use it.

 A temporary table is only available and accessible to the client that creates it. Different clients can
create temporary tables with the same name without causing errors because only the client that
creates the temporary table can see it. However, in the same session, two temporary tables cannot
share the same name.

 A temporary table can have the same name as a normal table in a database. For example, if you
create a temporary table named employees in the sample database, the existing employees table
becomes inaccessible. Every query you issue against the employees table is now referring to the
temporary employees table. When you drop the employees temporary table, the
permanent employees table is available and accessible again.

Even though a temporary table can have the same name as a permanent table, it is not recommended.

Because this may lead to a confusion and potentially cause an unexpected data loss.

For example, in case the connection to the database server is lost and you reconnect to the server
automatically, you cannot differentiate between the temporary table and the permanent one. Then, you
may issue a DROP TABLE statement to remove the permanent table instead of the temporary table, which
is not expected.

Creating a MySQL temporary table


To create a temporary table, you just need to add the TEMPORARY keyword to the CREATE
TABLE statement.

For example, the following statement creates a temporary table that stores the top 10 customers by
revenue:

1 CREATE TEMPORARY TABLE top10customers


2 SELECT p.customerNumber,
3 c.customerName,
4 FORMAT(SUM(p.amount),2) total
5 FROM payments p
6 INNER JOIN customers c ON c.customerNumber = p.customerNumber
7 GROUP BY p.customerNumber
8 ORDER BY total DESC
9 LIMIT 10;

Now, you can query data from the top10customers temporary table like querying from a permanent
table:

1 SELECT * FROM top10customers;

Removing a MySQL temporary table


You can use the DROP TABLE statement to remove temporary tables however it is good practice to add
the TEMPORARY keyword as follows:

1 DROP TEMPORARY TABLE table_name;

The DROP TEMPORARY TABLE statement removes a temporary table only, not a permanent table. It helps
you avoid the mistake of removing a permanent table when you name your temporary table the same as
the name of the permanent table

For example, to remove the top10customers temporary table, you use the following statement:

1 DROP TEMPORARY TABLE top10customers;

Notice that if you try to remove a permanent table with the DROP TEMPORARY TABLE statement, you will
get an error message saying that the table you are trying drop is unknown.

If you develop an application that uses a connection pooling or persistent connections, it is not guaranteed
that the temporary tables are removed automatically when your application is terminated.

Because the database connection that the application used may be still open and placed in a connection
pool for other clients to use. Therefore, it is a good practice to always remove the temporary tables
whenever you are no longer use them.

In this tutorial, you have learned about the MySQL temporary tables and how to manage temporary tables
such as creating and removing a new temporary table.
MySQL TRUNCATE TABLE
Summary: in this tutorial, you will learn how to use the MySQL TRUNCATE TABLE statement to delete
all data in a table.

Introduction to MySQL TRUNCATE TABLE statement


The MySQL TRUNCATE TABLE statement allows you to delete all data in a table. Therefore, in terms of
functionality, The TRUNCATE TABLE statement is like a DELETE statement without a WHERE clause.

However, in some cases, the MySQL TRUNCATE TABLE statement is more efficient than
the DELETE statement.

The syntax of the MySQL TRUNCATE TABLE statement is as follows:

1 TRUNCATE TABLE table_name;

You specify the table name, which you want to remove all data, after the TRUNCATE TABLE clause.
The TABLE keyword is optional. However, you should use it to distinguish between the TRUNCATE
TABLE statement and the TRUNCATE function.

If you are using InnoDB tables, MySQL will check if there are any foreign key constraints available in the
tables before deleting data. The following are cases:

 If the table has any foreign key constraints, the TRUNCATE TABLE statement deletes rows one by
one. If the foreign key constraint has DELETE CASCADE action, the corresponding rows in the child
tables are also deleted.

 If the foreign key constraint does not specify the DELETE CASCADE action, the TRUNCATE
TABLE deletes rows one by one, and it will stop and issue an error when it encounters a row that is
referenced by a row in a child table.

 If the table does not have any foreign key constraint, the TRUNCATE TABLE statement drops the
table and recreates a new empty one with the same structure, which is faster and more efficient
than using the DELETE statement especially for big tables.

If you are using other storage engines, the TRUNCATE TABLE statement just drops and recreates a new
table.

Notice that the TRUNCATE TABLE statement resets auto increment value to zero if the table has
an AUTO_INCREMENT column.

In addition, the TRUNCATE TABLE statement does not use the DELETE statement, therefore, the DELETE
triggers associated with the table will not be invoked.

MySQL TRUNCATE TABLE examples


First, create a new table named books for the demonstration:

1 CREATE DATABASE dbdemo;


2
3 CREATE TABLE books(
4 id int auto_increment primary key,
5 title varchar(255) not null
6 )ENGINE=InnoDB;

Next, populate data for the books table by using the following stored procedure

1 DELIMITER $$
2
3 CREATE PROCEDURE load_book_data(IN num int(4))
4 BEGIN
5 DECLARE counter int(4) default 0;
6 DECLARE book_title varchar(255) default '';
7
8 WHILE counter < num DO
9 SET title = concat('Book title #',counter);
10 SET counter = counter + 1;
11
12 INSERT INTO books
13 Values(book_title);
14 END WHILE;
15 END$$
16
17 DELIMITER ;

Then, load 10,000 rows into the books table. It will take a while.

1 CALL load_book_data(10000);

After that, check the data in the books table:

1 SELECT *
2 FROM books;

Finally, use the TRUNCATE TABLE statement to see how fast it performs in comparison with
the DELETE statement.

1 TRUNCATE TABLE books;

In this tutorial, we have shown you how to use the MySQL TRUNCATE TABLE statement to delete all
data from tables efficiently, especially for large tables.
Section 12. MySQL indexes
 Managing MySQL database indexes – learn how to work with MySQL indexes and how to take
advantages of indexes to speed up the data retrieval.

 UNIQUE index – show you how to use the UNIQUE index to enforce the uniqueness of value in one
or more columns.

MySQL Managing Database Index


Summary: in this tutorial, you will learn how to work with MySQL index and how to take advantages of
the index to speed up the data retrieval. We will introduce you several useful statements that allow you to
manage MySQL indexes.

A database index, or just index, helps speed up the retrieval of data from tables. When you query data
from a table, first MySQL checks if the indexes exist, then MySQL uses the indexes to select exact
physical corresponding rows of the table instead of scanning the whole table.

A database index is similar to an index of a book. If you want to find a topic, you look up in the index first,
and then you open the page that has the topic without scanning the whole book.

It is highly recommended that you create indices on columns of a table from which you often query the
data. Notice that all primary key columns are in the primary index of the table automatically.

If index helps speed up the querying data, why don’t we use indexes for all columns? If you create an
index for every column, MySQL has to build and maintain the index table. Whenever a change is made to
the rows of the table, MySQL has to rebuild the index, which takes time as well as decreases the
performance of the database server.

Creating MySQL Index


You often create indexes when you create tables. MySQL automatically adds any column that is declared
as PRIMARY KEY , KEY , UNIQUE or INDEX to the index. In addition, you can add indexes to the tables that
already have data.

In order to create indexes, you use the CREATE INDEX statement. The following illustrates the syntax of
the CREATE INDEX statement:

1 CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name


2 USING [BTREE | HASH | RTREE]
3 ON table_name (column_name [(length)] [ASC | DESC],...)

First, you specify the index based on the table type or storage engine:
 For the UNIQUE index, MySQL creates a constraint that all values in the index must be unique.
Duplicate NULL values are allowed in all storage engines except for BDB.

 The FULLTEXT index is supported only by MyISAM storage engine and only accepted on a column
whose has data type is CHAR , VARCHAR or TEXT.

 The SPATIAL index supports spatial column and is available on MyISAM storage engine. In
addition, the column value must not be NULL.

Then, you name the index and its type after the USING keyword. The name of the index could
be BTREEHASH or RTREE.Y ou must follow the allowed indices based on the storage engine of the table.
Here are the storage engines of the table with the corresponding allowed index types:

Storage Engine Allowable Index Types

MyISAM BTREE, RTREE

InnoDB BTREE

MEMORY/HEAP HASH, BTREE

NDB HASH

Third, you declare table name and a list columns that you want to add to the index.

Example of creating index in MySQL


In the sample database, you can add officeCode column of the employees table to the index by using
the CREATE INDEX statement as follows:

1 CREATE INDEX officeCode ON employees(officeCode)

Removing Indexes
Besides creating an index, you can also remove index by using the DROP INDEX statement. Interestingly,
the DROP INDEX statement is also mapped to ALTER TABLE statement. The following is the syntax of
removing the index:

1 DROP INDEX index_name ON table_name

For example, if you want to drop index officeCode of the employees table, which we have created
above, you can execute the following query:

1 DROP INDEX officeCode ON employees

In this tutorial, you’ve learned about indexes and how to manage MySQL index including creating and
removing indexes.
Using MySQL UNIQUE Index To Prevent Duplicates
Summary: in this tutorial, you will learn how to use the MySQL UNIQUE index to prevent duplicate values
in one or more column in a table.

Introduction to the MySQL UNIQUE index


To enforce the uniqueness value of one or more columns, you often use the PRIMARY KEY constraint.

However, each table has one and only one primary key. If you want to have a more than one column or a
set of columns with unique values, you cannot use the primary key constraint.

Luckily, MySQL provides another kind of index called UNIQUE index that allows you to enforce the
uniqueness of values in one or more columns. Unlike the PRIMARY KEY index, you can have more than
one UNIQUE index per table.

To create a UNIQUE index, you use the CREATE UNIQUE INDEX statement as follows:

1 CREATE UNIQUE INDEX index_name


2 ON table_name(index_column_1,index_column_2,...);

Another way to enforce the uniqueness of value in a one or more columns is to use the unique constraint.

When you create a unique constraint, MySQL creates a UNIQUE index behind the scenes.

The following statement illustrates how to create a unique constraint when you create a table.

1 CREATE TABLE table_name(


2 ...
3 UNIQUE KEY(index_column_,index_column_2,...)
4 );

You can also use the UNIQUE INDEX instead of the UNIQUE KEY. They are referred to the same thing.

If you want to add a unique constraint to an existing table, you can use the ALTER TABLE statement as
follows:

1 ALTER TABLE table_name


2 ADD CONSTRAINT constraint_name UNIQUE KEY(column_1,column_2,...);

MySQL UNIQUE Index & NULL


Unlike other database systems, MySQL considers NULL values as distinct values. Therefore, you can
have multiple NULL values in the UNIQUE index.
This is how MySQL was designed. This is not a bug even though it was reported as a bug.

Another important point is that the UNIQUE constraint does not apply to NULL values except for the
BDB storage engine.

MySQL UNIQUE index examples


Suppose, you want to manage contacts in an application. You also want that the email column in
the contacts table must be unique.

To enforce this rule, you create a unique constraint in the CREATE TABLE statement as follows

1 CREATE TABLE IF NOT EXISTS contacts (


2 id INT AUTO_INCREMENT PRIMARY KEY,
3 first_name VARCHAR(50) NOT NULL,
4 last_name VARCHAR(50) NOT NULL,
5 phone VARCHAR(15) NOT NULL,
6 email VARCHAR(100) NOT NULL,
7 UNIQUE KEY unique_email (email)
8 );

If you use the SHOW INDEXES statement, you will see that MySQL created a UNIQUE index for email
column.

1 SHOW INDEXES FROM contacts;

Let’s insert a row into the contacts table.

1 INSERT INTO contacts(first_name,last_name,phone,email)


2 VALUES('John','Doe','(408)-999-9765','[email protected]');

Now if you try to insert a row whose email is [email protected] , you will get an error
message.

1 INSERT INTO contacts(first_name,last_name,phone,email)


2 VALUES('Johny','Doe','(408)-999-4321','[email protected]');

1 Error Code: 1062. Duplicate entry '[email protected]' for key 'unique_email'

Suppose you want not only email is unique but also the combination of first_name, last_name, and phone
are also unique. In this case, you use the CREATE INDEX statement to create a UNIQUE index for those
columns as follows:
1 CREATE UNIQUE INDEX idx_name_phone
2 ON contacts(first_name,last_name,phone);

Adding the following row into the contacts table causes an error because the combination of the
first_name, last_name, and phone already exists.

1 INSERT INTO contacts(first_name,last_name,phone,email)


2 VALUES('john','doe','(408)-999-9765','[email protected]');

1 Error Code: 1062. Duplicate entry 'john-doe-(408)-999-9765' for key 'idx_name_phone'

In this tutorial, you have learned how to use the MySQL UNIQUE index to prevent duplicate values in the
database.

Section 13. MySQL data types


 MySQL data types – show you various data types in MySQL so that you can apply them effectively
in designing database tables.

 INT – show you how to use integer data type. We also show you how to use ZEROFILL and display
width attributes of the integer column.

 DECIMAL – show you how to use DECIMAL data type to store exact values in decimal format.

 BIT – introduce you BIT data type and how to store bit values in MySQL.

 BOOLEAN – explain to you how MySQL handles Boolean values by using TINYINT(1) internally.

 CHAR – guide to CHAR data type for storing the fixed-length string.

 VARCHAR – give you the essential guide to VARCHAR data type.

 TEXT – show you how to store text data using TEXT data type.

 DATE – introduce you to the DATE data type and show you some date functions to handle the date
data effectively.

 TIME – walk you through the features of TIME data type and show you how to use some useful
temporal functions to handle time data.

 DATETIME – introduce you to the DATETIME data type and some useful functions to
manipulate DATETIME values.

 TIMESTAMP – introduce you to TIMESTAMP and its features called automatic initialization and
automatic update that allows you to define auto-initialized and auto-updated columns for a table.

 JSON – show you how to use JSON data type to store JSON documents.
 ENUM – learn how to use ENUM data type correctly to store enumeration values.

MySQL Data Types


Summary: in this tutorial, you will learn about MySQL data types and how to use them effectively in
designing database in MySQL.

A database table contains multiple columns with specific data types such as numeric or string. MySQL
provides more data types other than just numeric or string. Each data type in MySQL can be determined
by the following characteristics:

 The kind of values it represents.


 The space that takes up and whether the values is a fixed-length or variable length.
 The values of the data type can be indexed or not.
 How MySQL compares the values of a specific data type.

Common MySQL Data Types (497.68 kB)500525 downloads

MySQL numeric data types


In MySQL, you can find all SQL standard numeric types including exact number data type and
approximate numeric data types including integer, fixed-point and floating point. In addition, MySQL also
has BIT data type for storing bit values. Numeric types can be signed or unsigned except for the BIT type.
The following table shows the summary of numeric types in MySQL:

Numeric Types Description


TINYINT A very small integer
SMALLINT A small integer
MEDIUMINT A medium-sized integer
INT A standard integer
BIGINT A large integer
DECIMAL A fixed-point number
FLOAT A single-precision floating point number
DOUBLE A double-precision floating point number
BIT A bit field

MySQL Boolean data type


MySQL does not have the built-in BOOLEAN or BOOL data type. To represent Boolean values, MySQL uses
the smallest integer type which is TINYINT(1) . In other words, BOOLEAN and BOOL are synonyms
for TINYINT(1).

MySQL String data types


In MySQL, a string can hold anything from plain text to binary data such as images or files. Strings can be
compared and searched based on pattern matching by using the LIKE operator, regular expression,
and full-text search.

The following table shows the string data types in MySQL:

String Types Description


CHAR A fixed-length nonbinary (character) string
VARCHAR A variable-length non-binary string
BINARY A fixed-length binary string
VARBINARY A variable-length binary string
TINYBLOB A very small BLOB (binary large object)
BLOB A small BLOB
MEDIUMBLOB A medium-sized BLOB
LONGBLOB A large BLOB
TINYTEXT A very small non-binary string
TEXT A small non-binary string
MEDIUMTEXT A medium-sized non-binary string
String Types Description
LONGTEXT A large non-binary string
ENUM An enumeration; each column value may be assigned one enumeration member
SET A set; each column value may be assigned zero or more SET members

MySQL date and time data types


MySQL provides types for date and time as well as the combination of date and time. In addition, MySQL
supports timestamp data type for tracking the changes in a row of a table. If you just want to store the year
without date and month, you can use the YEAR data type.

The following table illustrates the MySQL date and time data types:

Date and Time Types Description


DATE A date value in CCYY-MM-DD format
TIME A time value in hh:mm:ss format
DATETIME A date and time value inCCYY-MM-DD hh:mm:ssformat
TIMESTAMP A timestamp value in CCYY-MM-DD hh:mm:ss format
YEAR A year value in CCYY or YY format

MySQL spatial data types


MySQL supports many spatial data types that contain various kinds of geometrical and geographical
values as shown in the following table:

Spatial Data Types Description


GEOMETRY A spatial value of any type
POINT A point (a pair of X-Y coordinates)
LINESTRING A curve (one or more POINT values)
POLYGON A polygon
GEOMETRYCOLLECTION A collection of GEOMETRYvalues
MULTILINESTRING A collection of LINESTRINGvalues
MULTIPOINT A collection of POINTvalues
MULTIPOLYGON A collection of POLYGONvalues
JSON data type
MySQL supported a native JSON data type since version 5.7.8 that allows you to store and manage JSON
documents more efficiently. The native JSON data type provides automatic validation of JSON documents
and optimal storage format.

In this tutorial, you have learned various MySQL data types that help you determine which data type you
should use for columns when you create tables.

MySQL INT Data Type Explained With Examples


Summary: in this tutorial, you will learn about MySQL INT or integer data type and how to use it in your
database table design. In addition, we will show you how to use the display width and ZEROFILLattributes
of an integer column in a table.

Introduction to MySQL INT type


In MySQL, INT stands for the integer that is a whole number. An integer can be written without a
fractional component e.g., it is 1, 100, 4, -10, etc., and it cannot be 1.2, 5/3, etc. An integer can be zero,
positive, and negative.

MySQL supports all standard SQL integer types INTEGER or INT and SMALLINT . In addition, MySQL
provides TINYINT MEDIUMINT , and BIGINT as extensions to the standard SQL.

MySQL INT data type can be signed and unsigned. The following table illustrates the characteristics of
each integer type including storage in bytes, minimum value, and maximum value.

Type Storage Minimum Value Maximum Value


(Bytes) (Signed/Unsigned) (Signed/Unsigned)
TINYINT 1 -128 127
0 255
SMALLINT 2 -32768 32767
0 65535
MEDIUMINT 3 -8388608 8388607
0 16777215
INT 4 -2147483648 2147483647
0 4294967295
BIGINT 8 -9223372036854775808 9223372036854775807
Type Storage Minimum Value Maximum Value
(Bytes) (Signed/Unsigned) (Signed/Unsigned)
0 18446744073709551615

Using INT in a column


Because integer type represents exact numbers, you usually use it as the primary key of a table. In
addition, the INT column can have an AUTO_INCREMENT attribute.

When you insert a NULL value or 0 into the INT AUTO_INCREMENT column, the value of the column is set
to the next sequence value. Notice that the sequence value starts with 1.

When you insert a value, which is not NULL or zero, into the AUTO_INCREMENT column, the column
accepts the value. In addition, the sequence is reset to next value of the inserted value.

Let’s take a look at an example of a table that uses an integer column with the AUTO_INCREMENT
attributes.

First, create a new table named items with an integer column as the primary key using the following
statement:

1 CREATE TABLE items (


2 item_id INT AUTO_INCREMENT PRIMARY KEY,
3 item_text VARCHAR(255)
4 );

you can use either INT or INTEGER in the CREATE TABLE statement above because they are
interchangeable. Whenever you insert a new row into the items table, the value of the item_id column is
increased by 1.

Next, the following INSERT statement inserts three rows into the items table.

1 INSERT INTO items(item_text)


2 VALUES('laptop'), ('mouse'),('headphone');

Then, query data from the items table using the following SELECT statement:

1 SELECT
2 *
3 FROM
4 items;
After that, insert a new row whose value of the item_id column is specified explicitly.

1 INSERT INTO items(item_id,item_text)


2 VALUES(10,'Server');

Because the current value of the item_id column is 10, the sequence is reset to 11. If you insert a new
row, the AUTO_INCREMENT column will use 11 as the next value.

1 INSERT INTO items(item_text)


2 VALUES('Router');

Finally, query the data of the items table again to see the result.

1 SELECT
2 *
3 FROM
4 items;

Note that since MySQL 5.1, the AUTO_INCREMENT column only accepts positive values. Negative values
are not supported for the AUTO_INCREMENT column.

MySQL INT and display width attribute


MySQL provides an extension that allows you to specify the display width along with the INT data type.
The display width is wrapped inside parentheses following the INT keyword e.g., INT(5) specifies
an INT with the display width of five digits.
It is important to note that the display width attribute does not control the value ranges that the column can
store. The display width attribute is typically used by the applications to format the integer values. MySQL
includes the display width attribute as the metadata of the returned result set.

MySQL INT with ZEROFILL attribute


In addition to the display width, MySQL provides a non-standard ZEROFILL attribute. In this case, MySQL
replaces the spaces with zero. Consider the following example.

First, create a table named zerofill_tests using the following statement:

1 CREATE TABLE zerofill_tests(


2 id INT AUTO_INCREMENT PRIMARY KEY,
3 v1 INT(2) ZEROFILL,
4 v2 INT(3) ZEROFILL,
5 v3 INT(5) ZEROFILL
6 );

Second, insert a new row into the zerofill_tests table.

1 INSERT into zerofill_tests(v1,v2,v3)


2 VALUES(1,6,9);

Third, query data from the zerofill_tests table.

1 SELECT
2 v1, v2, v3
3 FROM
4 zerofill_tests;

The v1 column has a display width 2 including ZEROFILL. Its value is 1 therefore, you see 01 in the
output. MySQL replaces the first space by 0.

The v2 column has a display with 3 including ZEROFILL . Its value is 6 therefore, you see 00 as the
leading zeros.

The v3 column has the display width 5 with ZEROFILL , while its value is 9, therefore MySQL pads 0000 at
the beginning of the number in the output.
Note that if you use ZEROFILL attribute for an integer column, MySQL will automatically add
an UNSIGNED attribute to the column.

In this tutorial, we have shown you how to use MySQL INT data type in the table and also introduced you
to the display width and ZEROFILL attributes of an integer column.
MySQL DECIMAL Data Type
Summary: in this tutorial, we will introduce you to the MySQL DECIMAL data type and how to use it
effectively in your database table.

Introduction to MySQL DECIMAL data type


The MySQL DECIMAL data type is used to store exact numeric values in the database. We often use the
DECIMAL data type for columns that preserve exact precision e.g., money data in accounting systems.

To define a column whose data type is DECIMAL you use the following syntax:

1 column_name DECIMAL(P,D);

In the syntax above:

 P is the precision that represents the number of significant digits. The range of P is 1 to 65.

 D is the scale that that represents the number of digits after the decimal point. The range of D is 0
and 30. MySQL requires that D is less than or equal to (<=) P.

The DECIMAL(P,D) means that the column can store up to P digits with D decimals. The actual range of
the decimal column depends on the precision and scale.

Besides the DECIMAL keyword, you can also use DEC , FIXED , or NUMERIC because they are synonyms
for DECIMAL .

Like the INT data type, the DECIMAL type also has UNSIGNED and ZEROFILL attributes. If we use
the UNSIGNED attribute, the column with DECIMAL UNSIGNED will not accept negative values.

In case we use ZEROFILL , MySQL will pad the display value by 0 up to display width specified by the
column definition. In addition, if we use ZERO FILL for the DECIMAL column, MySQL will add
the UNSIGNED attribute to the column automatically.

The following example defines amount column with DECIMAL data type.

1 amount DECIMAL(6,2);

In this example, the amount column can store 6 digits with 2 decimal places; therefore, the range of the
amount column is from 9999.99 to -9999.99.

MySQL allows us to use the following syntax:

1 column_name DECIMAL(P);

This is equivalent to:


1 column_name DECIMAL(P,0);

In this case, the column contains no fractional part or decimal point.

In addition, we can even use the following syntax.

1 column_name DECIMAL;

The default value of P is 10 in this case.

MySQL DECIMAL storage


MySQL assigns the storage for integer and fractional parts separately. MySQL uses binary format to store
the DECIMAL values. It packs 9 digits into 4 bytes.

For each part, it takes 4 bytes to store each multiple of 9 digits. The storage required for leftover digits is
illustrated in the following table:

Leftover Digits Bytes


0 0
1–2 1
3–4 2
5–6 3
7–9 4

For example, DECIMAL(19,9) has 9 digits for the fractional part and 19-9 = 10 digits for integer part. The
fractional part requires 4 bytes. The integer part requires 4 bytes for the first 9 digits, for 1 leftover digit, it
requires 1 more byte. In total, the DECIMAL(19,9) column requires 9 bytes.

MySQL DECIMAL data type and monetary data


We often use the DECIMAL data type for monetary data such as prices, salary, account balances, etc. If
you design a database that handle the monetary data, the following syntax should be OK.

1 amount DECIMAL(19,2);

However, if you want to comply with Generally Accepted Accounting Principles (GAAP) rules, the
monetary column must have at least 4 decimal places to make sure that the rounding value does not
exceed $0.01. In this case, you should define the column with 4 decimal places as follows:

1 amount DECIMAL(19,4);
MySQL DECIMAL data type example
First, create a new table named materials with three columns: id, description, and cost.

1 CREATE TABLE materials (


2 id INT AUTO_INCREMENT PRIMARY KEY,
3 description VARCHAR(255),
4 cost DECIMAL(19 , 4 ) NOT NULL
5 );

Second, insert data into the materials table.

1 INSERT INTO materials(description,cost)


2 VALUES('Bicycle', 500.34),('Seat',10.23),('Break',5.21);

Third, query data from the materials table.

1 SELECT
2 *
3 FROM
4 materials;

Fourth, change the cost column to include the ZEROFILL attribute.

1 ALTER TABLE materials


2 MODIFY cost DECIMAL(19,4) zerofill;

Fifth, query the materials table again.

1 SELECT
2 *
3 FROM
4 materials;
As you see, we have many zeros padded in the output values.

In this tutorial, we have shown gave you detailed information on MySQL DECIMAL data type and shown
you how to apply it to the columns that store exact numeric data such as financial data.

Pramatic Uses of MySQL BIT Data Type


Summary: this tutorial introduces you to MySQL BIT data type that allows you to store bit values.

Introduction to MySQL BIT data type


MySQL provides the BIT type that allows you to store bit values. The BIT(m) can store up to m-bit
values, which m can range from 1 to 64.

The default value of m is 1 if you omit it. So the following statements are the same:

1 column_name BIT(1);

and

1 column_name BIT;

To specify a bit value literal, you use b'val' or 0bval notation, which val is a binary value that contains
only 0 and 1.

The leading b can be written as B , for example:

1 b01
2 B11

are the valid bit literals.

However, the leading 0b is case-sensitive, therefore, you cannot use 0B . The following is an invalid bit
literal value:

1 0B'1000'

By default the character set of a bit-value literal is the binary string as follows:

1 SELECT CHARSET(B'); -- binary

MySQL BIT examples


The following statement creates a new table named working_calendar that has the days column
is BIT(7) :

1 CREATE TABLE working_calendar(


2 y INT
3 w INT,
4 days BIT(7),
5 PRIMARY KEY(y,w)
6 );

The values in days column indicate the working day or day off i.e., 1: working day and 0: day off.

Suppose the Saturday and Friday of the first week of 2017 are not the working days, you can insert a
rowinto the working_calendar table as follows:

1 INSERT INTO working_calendar(y,w,days)


2 VALUES(2017,1,B'1111100');

The following query retrieves data from the working_calendar table:

1 SELECT
2 y, w , days
3 FROM
4 working_calendar;

As you see, the bit value in the days column is converted into an integer. To represent it as bit values,
you use the BIN function:

1 SELECT
2 y, w , bin(days)
3 FROM
4 working_calendar;

If you insert a value to a BIT(m) column that is less than m bits long, MySQL will pad zeros on the left of
the bit value.

Suppose the first day of the second week is off, you can insert 01111100 into the days column.
However, the 111100 value will also work because MySQL will pad one zero on the left.
1 INSERT INTO working_calendar(y,w,days)
2 VALUES(2017,2,B'111100');

To view the data you use the same query as above:

1 SELECT
2 y, w , bin(days)
3 FROM
4 working_calendar;

As you can see, MySQL removed the leading zeros prior returning the result. To display it correctly, you
can use the LPAD function:

1 SELECT
2 y, w , lpad(bin(days),7,'0')
3 FROM
4 working_calendar;

It is working fine now.

In this tutorial, you have learned how to use the MySQL BIT type to store bit values.

An Introduction to MySQL BOOLEAN Data Type


Summary: this tutorial shows you how to use MySQL BOOLEAN data type to store Boolean values, true
and false.

Introduction to MySQL BOOLEAN data type


MySQL does not have built-in Boolean type. However, it uses TINYINT(1) instead. To make it more
convenient, MySQL provides BOOLEAN or BOOL as the synonym of TINYINT(1) .

In MySQL, zero is considered as false, and non-zero value is considered as true. To use Boolean literals,
you use the constants TRUE and FALSE that evaluate to 1 and 0 respectively. See the following example:

1 SELECT true, false, TRUE, FALSE, True, False;


2
-- 1 0 1 0 1 0

MySQL BOOLEAN example


MySQL stores Boolean value in the table as an integer. To demonstrate this, let’s look at the
following tasks table:

1 CREATE TABLE tasks (


2 id INT PRIMARY KEY AUTO_INCREMENT,
3 title VARCHAR(255) NOT NULL,
4 completed BOOLEAN
5 );

Even though we specified the completed column as BOOLEAN , when we show the table definition, it
is TINYINT(1) as follows:

1 DESCRIBE tasks;

The following statement inserts 2 rows into the tasks table:

1 INSERT INTO tasks(title,completed)


2 VALUES('Master MySQL Boolean type',true),
3 ('Design database table',false);
Before saving data into the Boolean column, MySQL converts it into 1 or 0. The following query retrieves
data from tasks table:

1 SELECT
2 id, title, completed
3 FROM
4 tasks;

As you see, the true and false were converted to 1 and 0.


Because Boolean is TINYINT(1) , you can insert value other than 1 and 0 into the Boolean column.
Consider the following example:

1 INSERT INTO tasks(title,completed)


2 VALUES('Test Boolean with a number',2);

It is working fine.

If you want to output the result as true and false , you can use the IF function as follows:

1 SELECT
2 id,
3 title,
4 IF(completed, 'true', 'false') completed
5 FROM
6 tasks;

MySQL BOOLEAN operators


To get all completed tasks in the tasks table, you might come up with the following query:

1 SELECT
2 id, title, completed
3 FROM
4 tasks
5 WHERE
6 completed = TRUE;
As you see, it only returned the task with completed value 1. To fix it, you must use IS operator:

1 SELECT
2 id, title, completed
3 FROM
4 tasks
5 WHERE
6 completed IS TRUE;

In this example, we used the IS operator to test a value against a Boolean value.

To get the pending tasks, you use IS FALSE or IS NOT TRUE as follows:

1 SELECT
2 id, title, completed
3 FROM
4 tasks
5 WHERE
6 completed IS NOT TRUE

In this tutorial, you have learned how to use the MySQL BOOLEAN data type, which is the synonym
of TINYINT(1) , and how to manipulate Boolean values.

MySQL CHAR Data Type


Summary: in this tutorial, you will learn about MySQL CHAR data type and how to apply it in your
database table design.

Introduction to MySQL CHAR data type


The CHAR data type is a fixed-length character type in MySQL. We often declare the CHAR type with a
length that specifies the maximum number of characters that we want to store. For
example, CHAR(20) can hold up to 20 characters.

If the data that you want to store is a fixed size, you should use the CHAR data type. You’ll get a better
performance in comparison with VARCHAR in this case.
The length of the CHAR data type can be any value from 0 to 255. When you store a CHAR value, MySQL
pads its value with spaces to the length that you declared.

When you query the CHAR value, MySQL removes the trailing spaces.

Note that MySQL will not remove the trailing spaces if you enable
the PAD_CHAR_TO_FULL_LENGTHSQL mode.

The following statement creates a table with a CHAR column.

1 CREATE TABLE mysql_char_test (


2 status CHAR(3)
3 );

The status column has the CHAR data type. It can hold up to 3 characters.
Now, we insert 2 rows into the mysql_char_test table.

1 INSERT INTO mysql_char_test(status)


2 VALUES('Yes'),('No');

We use the length function to get the length of each CHAR value.

1 SELECT
2 status, LENGTH(status)
3 FROM
4 mysql_char_test;

The following statement inserts a CHAR value with the leading and trailing spaces.

1 INSERT INTO mysql_char_test(status)


2 VALUES(' Y ');

However, when we retrieve the value, MySQL removes the trailing space.

1 SELECT
2 status, LENGTH(status)
3 FROM
4 mysql_char_test;
Comparing MySQL CHAR values
When storing or comparing the CHAR values, MySQL uses the character set collation assigned to the
column.

MySQL does not consider trailing spaces when comparing CHAR values using the comparison operator
such as =, <>, >, <, etc.

Notice that the LIKE operator does consider the trailing spaces when you do pattern matching
with CHAR values.

In the previous example, we stored the value Y with both leading and trailing spaces. However, when we
execute the following query:

1 SELECT
2 *
3 FROM
4 mysql_char_test
5 WHERE
6 status = 'Y';
MySQL returns no row because it does not consider the trailing space. To match with the ‘ Y ‘, we need to
remove the trailing space as follows:

1 SELECT
2 *
3 FROM
4 mysql_char_test
5 WHERE
6 status = ' Y';

MySQL CHAR and UNIQUE index


If the CHAR column has a UNIQUE index and you insert a value that is different from an existing value in a
number of trailing spaces, MySQL will reject the changes because of duplicate-key error.
See the following example.

First, create a unique index for the status column of the mysql_char_test table.

1 CREATE UNIQUE INDEX uidx_status ON mysql_char_test(status);


Second, insert a new row into the mysql_char_test table.

1 INSERT INTO mysql_char_test(status)


2 VALUES('N');

Third, insert the following value will cause a duplicate-key error.

1 INSERT INTO mysql_char_test(status)


2 VALUES('N ');

1 Error Code: 1062. Duplicate entry 'N' for key 'uidx_status'

In this tutorial, we have introduced you to the MySQL CHAR data type and its features. Now, you should
have a good understanding of the CHAR data type to apply it in your database design.

The Essential Guide to MySQL VARCHAR Data Type


Summary: this tutorial introduces you to the MySQL VARCHAR data type and discusses some important
features of VARCHAR .

Introduction to MySQL VARCHAR data type


MySQL VARCHAR is the variable-length string whose length can be up to 65,535. MySQL stores
a VARCHAR value as a 1-byte or 2-byte length prefix plus actual data.
The length prefix specifies the number of bytes in the value. If a column requires less than 255 bytes, the
length prefix is 1 byte. In case the column requires more than 255 bytes, the length prefix is two length
bytes.

The maximum length, however, is subject to maximum row size (65,535 bytes) and the character setused.
It means that the total length of all columns should be less than 65,535 bytes.

Let’s take a look at an example.

We will create a new table that has two columns s1 and s2 with the length of 32765(+2 for length prefix)
and 32766 (+2).Note that 32765+2+32766+2=65535, which is the maximum row size.

1 CREATE TABLE IF NOT EXISTS varchar_test (


2 s1 VARCHAR(32765) NOT NULL,
3 s2 VARCHAR(32766) NOT NULL
4 ) CHARACTER SET 'latin1' COLLATE LATIN1_DANISH_CI;

The statement created the table successfully. However, if we increase the length of the s1 column by 1.

1 CREATE TABLE IF NOT EXISTS varchar_test_2 (


2 s1 VARCHAR(32766) NOT NULL, -- error
3 s2 VARCHAR(32766) NOT NULL
4 ) CHARACTER SET 'latin1' COLLATE LATIN1_DANISH_CI;

MySQL will issue the error message:

Error Code: 1118. Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes
1
storage overhead, check the manual. You have to change some columns to TEXT or BLOBs 0.000 sec

As you can see, the row size is too large and the statement failed.

If you insert a string whose length is greater than the length of a VARCHAR column, MySQL will issue an
error. Consider the following example:

1 CREATE TABLE items (


2 id INT PRIMARY KEY AUTO_INCREMENT,
3 title VARCHAR(3)
4 );
5
6 INSERT INTO items(title)
7 VALUES('ABCD');

In this example, MySQL issued the following error message:

1 Error Code: 1406. Data too long for column 'title' at row 1 0.000 sec

MySQL VARCHAR and spaces


MySQL does not pad space when it stores the VARCHAR values. Also, MySQL retains the trailing spaces
when it inserts or selects VARCHAR values. See the following example:

1 INSERT INTO items(title)


2 VALUES('AB ');

1 SELECT
2 id, title, length(title)
3 FROM
4 items;
However, MySQL will truncate the trailing spaces when inserting a VARCHAR value that contains trailing
spaces which cause the column length exceeded. In addition, MySQL issues a warning. Let’s see the
following example:

1 INSERT INTO items(title)


2 VALUES('ABC ');

This statement inserts a string whose length is 4 into the title column. MySQL still inserts the string,
however, it truncates the trailing space before inserting the value.

1 1 row(s) affected, 1 warning(s): 1265 Data truncated for column 'title' at row 1

You can verify it by using the following query:

1 SELECT
2 title, LENGTH(title)
3 FROM
4 items;

In this tutorial, you have learned how to use MySQL VARCHAR data type to store variable strings in the
database.

The Basics Of MySQL TEXT Data Type


Summary: in this tutorial, you will learn how to use MySQL TEXT for storing text data in the database
table.

Introduction to MySQL TEXT data type


Besides CHAR and VARCHAR character types, MySQL provides us with TEXT type that has more features
which CHAR and VARCHAR cannot cover.

The TEXT is useful for storing long-form text strings that can take from 1 byte to 4 GB. We often find
the TEXT data type for storing article body in news sites, product description in e-commerce sites.

Different from CHAR and VARCHAR , you don’t have to specify a storage length when you use a TEXT type
for a column. In addition, MySQL does not remove or pad spaces when retrieve or insert text data
like CHAR and VARCHAR .
Note that the TEXT data is not stored in the database server’s memory, therefore, whenever you
query TEXT data, MySQL has to read from it from the disk, which is much slower in comparison
with CHAR and VARCHAR .

MySQL provides four TEXT types: TINYTEXT , TEXT , MEDIUMTEXT , and LONGTEXT .
The following shows the size of each TEXT type with the assumption that we are using a character set that
take 1 byte to store a character

TINYTEXT – 1 Byte (255 characters)


The maximum characters that TINYTEXT can store is 255 ( 2^8 = 256, 1 byte overhead).

You should use TINYTEXT for column that require less than 255 characters, has inconsistent length, and
does not require sorting such as excerpt of a blog post, summary of an article, etc.
See the following example:

1 CREATE TABLE articles (


2 id INT AUTO_INCREMENT PRIMARY KEY,
3 title VARCHAR(255),
4 summary TINYTEXT
5 );

In this example, we created a new table named articles that has summary column with the data type
is TINYTEXT .

TEXT – 64KB (65,535 characters)


The TEXT data type can hold up to 64 KB that is equivalent to 65535 (2^16 – 1) characters. TEXT also
requires 2 byte overhead.

The TEXT can hold the body of an article. Consider the following example:

1 ALTER TABLE articles


2 ADD COLUMN body TEXT NOT NULL
3 AFTER summary;

In this example, we added the body column with TEXT data type to the articles table using the ALTER
TABLE statement.

MEDIUMTEXT – 16MB (16,777,215 characters)


The MEDIUMTEXT can hold up to 16MB text data that is equivalent to 16,777,215 characters. It requires 3
bytes overhead.

The MEDIUMTEXT is useful for storing quite large text data like text of a book, white papers, etc. For
example:
1 CREATE TABLE whitepapers (
2 id INT AUTO_INCREMENT PRIMARY KEY,
3 body MEDIUMTEXT NOT NULL,
4 published_on DATE NOT NULL
5 );

LONGTEXT – 4GB (4,294,967,295 characters)


The LONGTEXT can store text data up to 4 GB, which is a lot. It requires 4 bytes overhead.
In this tutorial, you have learned how to use various MySQL TEXT data types for storing text in database
tables.

The Ultimate Guide To MySQL DATE and Date


Functions
Summary: in this tutorial, we will introduce you to the MySQL DATE data type and show you some useful
date functions to handle the date data effectively.

Introduction to MySQL DATE data type


MySQL DATE is one of the five temporal data types used for managing date values. MySQL uses yyyy-
mm-dd format for storing a date value. This format is fixed and it is not possible to change it.

For example, you may prefer to use mm-dd-yyyy format but you can’t. Instead, you follow the standard
date format and use the DATE_FORMAT function to format the date the way you want.

MySQL uses 3 bytes to store a DATE value. The DATE values range from 1000-01-01 to 9999-12-31 . If
you want to store a date value that is out of this range, you need to use a non-temporal data type
like integer e.g., three columns, and each column for the year, month, and day. You also need to
create stored functions to simulate the built-in date functions provided by MySQL, which is not
recommended.

When strict mode is disabled, MySQL converts any invalid date e.g., 2015-02-30 to the zero
date value 0000-00-00 .

MySQL Date values with two-digit years


MySQL stores the year of the date value using four digits. In case you use two-digit year values, MySQL
still accepts them with the following rules:

 Year values in the range 00-69 are converted to 2000-2069.

 Year values in the range 70-99 are converted to 1970 – 1999.


However, a date value with two digits is ambiguous therefore you should avoid using it.

Let’s take a look at the following example.

First, create a table named people with birth date column with DATE data type.

1 CREATE TABLE people (


2 id INT AUTO_INCREMENT PRIMARY KEY,
3 first_name VARCHAR(50) NOT NULL,
4 last_name VARCHAR(50) NOT NULL,
5 birth_date DATE NOT NULL
6 );

Next, insert a row into the people table.

1 INSERT INTO people(first_name,last_name,birth_date)


2 VALUES('John','Doe','1990-09-01');

Then, query the data from the people table.

1 SELECT
2 first_name,
3 last_name,
4 birth_date
5 FROM
6 people;

After that, use the two-digit year format to insert data into the people table.

1 INSERT INTO people(first_name,last_name,birth_date)


2 VALUES('Jack','Daniel','01-09-01'),
3 ('Lily','Bush','80-09-01');

In the first row, we used 01 (range 00-69) as the year, so MySQL converted it to 2001. In the second row,
we used 80 (range 70-99) as the year, MySQL converted it to 1980.

Finally, we can query data from the people table to check whether data was converted based on the
conversion rules.
1 SELECT
2 first_name,
3 last_name,
4 birth_date
5 FROM
6 people;

MySQL DATE functions

MySQL provides many useful date functions that allow you to manipulate date effectively.

To get the current date and time, you use NOW() function.

1 SELECT NOW();

1 +---------------------+
2 | NOW() |
3 +---------------------+
4 | 2017-05-13 07:59:38 |
5 +---------------------+
6 1 row in set (0.02 sec)

To get only date part of a DATETIME value, you use the DATE() function.

1 SELECT DATE(NOW());

1 +-------------+
2 | DATE(NOW()) |
3 +-------------+
4 | 2015-07-13 |
5 +-------------+
6 1 row in set (0.01 sec)

To get the current system date, you use CURDATE() function as follows:

1 SELECT CURDATE();

1 +------------+
2 | CURDATE() |
3 +------------+
4 | 2015-07-13 |
5 +------------+
6 1 row in set (0.02 sec)

To format a date value, you use DATE_FORMAT function. The following statement formats the date
as mm/dd/yyyy using the date format pattern %m/%d/%Y :

1 SELECT DATE_FORMAT(CURDATE(), '%m/%d/%Y') today;

1 +------------+
2 | today |
3 +------------+
4 | 07/13/2015 |
5 +------------+
6 1 row in set (0.02 sec)

To calculate the number of days between two date values, you use the DATEDIFF function as follows:

1 SELECT DATEDIFF('2015-11-04','2014-11-04') days;

1 +------+
2 | days |
3 +------+
4 | 365 |
5 +------+
6 1 row in set (0.02 sec)

To add a number of days, weeks, months, years, etc., to a date value, you use the DATE_ADD function:

1 SELECT
2 '2015-01-01' start,
3 DATE_ADD('2015-01-01', INTERVAL 1 DAY) 'one day later',
4 DATE_ADD('2015-01-01', INTERVAL 1 WEEK) 'one week later',
5 DATE_ADD('2015-01-01', INTERVAL 1 MONTH) 'one month later',
6 DATE_ADD('2015-01-01', INTERVAL 1 YEAR) 'one year later';

Similarly, you can subtract an interval from a date using the DATE_SUB function:
1 SELECT
2 '2015-01-01' start,
3 DATE_SUB('2015-01-01', INTERVAL 1 DAY) 'one day before',
4 DATE_SUB('2015-01-01', INTERVAL 1 WEEK) 'one week before',
5 DATE_SUB('2015-01-01', INTERVAL 1 MONTH) 'one month before',
6 DATE_SUB('2015-01-01', INTERVAL 1 YEAR) 'one year before';

If you want to get the day, month, quarter, and year of a date value, you can use the corresponding
function DAY , MONTH , QUARTER , and YEAR as follows:

1 SELECT DAY('2000-12-31') day,


2 MONTH('2000-12-31') month,
3 QUARTER('2000-12-31') quarter,
4 YEAR('2000-12-31') year;

1 +------+-------+---------+------+
2 | day | month | quarter | year |
3 +------+-------+---------+------+
4 | 31 | 12 | 4 | 2000 |
5 +------+-------+---------+------+
6 1 row in set (0.00 sec)

To get the week information week related functions. For example, WEEK function returns the week
number, WEEKDAY function returns the weekday index, and WEEKOFYEAR function returns the calendar
week.

1 SELECT
2 WEEKDAY('2000-12-31') weekday,
3 WEEK('2000-12-31') week,
4 WEEKOFYEAR('2000-12-31') weekofyear;

1 +---------+------+------------+
2 | weekday | week | weekofyear |
3 +---------+------+------------+
4| 6 | 53 | 52 |
5 +---------+------+------------+
6 1 row in set (0.04 sec)
The week function returns the week number with the zero-based index if you don’t pass the second
argument or if you pass 0. If you pass 1, it will return week number with 1-indexed.

1 SELECT
2 WEEKDAY('2000-12-31') weekday,
3 WEEK('2000-12-31',1) week,
4 WEEKOFYEAR('2000-12-31') weekofyear;

1 +---------+------+------------+
2 | weekday | week | weekofyear |
3 +---------+------+------------+
4| 6 | 52 | 52 |
5 +---------+------+------------+
6 1 row in set (0.00 sec)

In this tutorial, you have learned about the MySQL DATE data type and how to use some
useful date functions to manipulate date values.

Mastering MySQL TIME Data Type


Summary: in this tutorial, we will introduce you to the MySQL TIME data type and show you useful
temporal functions to manipulate time data effectively.

Introduction to MySQL TIME data type


MySQL uses the 'HH:MM:SS' format for querying and displaying a time value that represents a time of
day, which is within 24 hours. To represent a time interval between two events, MySQL uses
the 'HHH:MM:SS' format, which is larger than 24 hours.

To define a TIME column, you use the following syntax:

1 column_name TIME;

For example, the following snippet defines a column named start_at with TIME data type.

1 start_at TIME;

A TIME value ranges from -838:59:59 to 838:59:59 . In addition, a TIME value can have fractional
seconds part that is up to microseconds precision (6 digits). To define a column whose data type
is TIME with a fractional second precision part, you use the following syntax:

1 column_name TIME(N);

N is an integer that represents the fractional part, which is up to 6 digits.


The following snippet defines a column with TIME data type including 3 digits of fractional seconds.

1 begin_at TIME(3);

A TIME value takes 3 bytes for storage. In case a TIME value includes fractional second precision, it will
take additional bytes based on the number of digits of the fractional second precision. The following table
illustrates the storage required for fractional second precision.

Fractional Second Precision Storage (BYTES)


0 0
1, 2 1
3, 4 2
5, 6 3

For example, TIME and TIME(0) takes 3 bytes. TIME(1) and TIME(2) takes 4 bytes (3 +

1); TIME(3) and TIME(6) take 5 and 6 bytes.

MySQL TIME data type example


Let’s take a look at an example of using the TIME data type for columns in a table.
First, create a new table named tests that consists of four columns: id , name , start_at , and end_at .

The data types of the start_at and end_at columns are TIME .

1 CREATE TABLE tests (


2 id INT PRIMARY KEY AUTO_INCREMENT,
3 name VARCHAR(255) NOT NULL,
4 start_at TIME,
5 end_at TIME
6 );

Second, insert a row into the tests table.

1 INSERT INTO tests(name,start_at,end_at)


2 VALUES('Test 1', '08:00:00','10:00:00');

Third, query data from the tests table.

1 SELECT
2 name, start_at, end_at
3 FROM
4 tests;
Notice that we use 'HH:MM:SS' as the literal time value in the INSERT statement. Let’s examine all the
valid time literals that MySQL can recognize.

MySQL TIME literals


MySQL recognizes various time formats besides the 'HH:MM:SS' format that we mentioned earlier.

MySQL allows you to use the 'HHMMSS' format without delimiter ( : ) to represent time value. For
example, '08:30:00' and '10:15:00' can be rewritten as '083000' and '101500' .

1 INSERT INTO tests(name,start_at,end_at)


2 VALUES('Test 2','083000','101500');

However, 108000 is not a valid time value because 80 does not represent the correct minute. In this case,
MySQL will raise an error if you try to insert an invalid time value into a table.

1 INSERT INTO tests(name,start_at,end_at)


2 VALUES('Test invalid','083000','108000');

MySQL issued the following error message after executing the above statement.

1 Error Code: 1292. Incorrect time value: '108000' for column 'end_at' at row 1

In addition to the string format, MySQL accepts the HHMMSS as a number that represents a time value.
You can also use SS , MMSS . For example, instead of using '082000' , you can use 082000 as follows:

1 INSERT INTO tests(name,start_at,end_at)


2 VALUES('Test 3',082000,102000);
For the time interval, you can use the 'D HH:MM:SS' format where D represents days with a range from 0
to 34. A more flexible syntax is 'HH:MM' , 'D HH:MM' , 'D HH' , or 'SS' .

If you use the delimiter:, you can use 1 digit to represent hours, minutes, or seconds. For
example, 9:5:0 can be used instead of '09:05:00' .

1 INSERT INTO tests(name,start_at,end_at)


2 VALUES('Test 4','9:5:0',100500);

Useful MySQL TIME functions


MySQL provides several useful temporal functions for manipulating TIME data.

Getting to know the current time


To get the current time of the database server, you use the CURRENT_TIME function.

The CURRENT_TIME function returns the current time value as a string ( 'HH:MM:SS' ) or a numeric value
( HHMMSS ) depending on the context where the function is used.

The following statements illustrate the CURRENT_TIME function in both string and numeric contexts:

1 SELECT
2 CURRENT_TIME() AS string_now,
3 CURRENT_TIME() + 0 AS numeric_now;

Adding and Subtracting time from a TIME value


To add a TIME value to another TIME value, you use the ADDTIME function. To subtract a TIME value from
another TIME value, you use the SUBTIME function.

The following statement adds and subtracts 2 hours 30 minutes to and from the current time.
1 SELECT
2 CURRENT_TIME(),
3 ADDTIME(CURRENT_TIME(), 023000),
4 SUBTIME(CURRENT_TIME(), 023000);

In addition, you can use the TIMEDIFF() function to get a difference between two TIME values.

1 SELECT
2 TIMEDIFF(end_at, start_at)
3 FROM
4 tests;

Formatting MySQL TIME values


Although MySQL uses 'HH:MM:SS' when retrieving and displaying the a TIME value, you can display
the TIME value in your preferred way using the TIME_FORMAT function.

The TIME_FORMAT function is like the DATE_FORMAT function except that the TIME_FORMAT function is
used to format a TIME value only.
See the following example.

1 SELECT
2 name,
3 TIME_FORMAT(start_at, '%h:%i %p') start_at,
4 TIME_FORMAT(end_at, '%h:%i %p') end_at
5 FROM
6 tests;

In the time format string above:

 %h means two-digit hours from 0 to 12.


 %i means two-digit minutes from 0 to 60.
 %p means AM or PM.
Extracting hour, minute, and second from a TIME value
To extract the hour, minute, and second from a TIME value, you use HOUR , MINUTE , and SECOND functions
as follows:

Getting UTC time value


To get the UTC time, you use UTC_TIME function as follows:

1 SELECT
2 CURRENT_TIME(),
3 UTC_TIME();

In this tutorial, we have been covered a lot about MySQL TIME data type and some commonly used
temporal functions for manipulating TIME values.

A Complete Guide To MySQL DATETIME Data Type


Summary: in this tutorial, you will learn about MySQL DATETIME data type and how to use some handy
functions for manipulating DATETIME effectively.

Introduction to MySQL DATETIME data type


You use MySQL DATETIME to store a value that contains both date and time. When you query data from
a DATETIME column, MySQL displays the DATETIME value in the following format:

1 YYYY-MM-DD HH:MM:SS

By default, DATETIME values range from 1000-01-01 00:00:00 to 9999-12-31 23:59:59 .

A DATETIME value uses 5 bytes for storage. In addition, a DATETIME value can include a trailing fractional
second up to microseconds with the format YYYY-MM-DD HH:MM:SS[.fraction] e.g., 2015-12-20
10:01:00.999999 . When including the fractional second precision, DATETIME values require more
storage as illustrated in the following table:
Fractional Seconds Precision Storage (Bytes)
0 0
1, 2 1
3, 4 2
5, 6 3

For example, 2015-12-20 10:01:00.999999 requires 8 bytes, 5 bytes for 2015-12-20 10:01:00 and
3 bytes for .999999 while 2015-12-20 10:01:00.9 requires only 6 bytes, 1 byte for the fractional
second precision.
Note that before MySQL 5.6.4, DATETIME values requires 8 bytes storage instead of 5 bytes.
MySQL DATETIME vs. TIMESTAMP
MySQL provides another temporal data type that is similar to the DATETIME called TIMESTAMP .

The TIMESTAMP requires 4 bytes while DATETIME requires 5 bytes.

Both TIMESTAMP and DATETIME require additional bytes for fractional seconds precision.
TIMESTAMP values range from 1970-01-01 00:00:01 UTC to 2038-01-19 03:14:07 UTC . If you want
to store temporal values that are beyond 2038, you should use DATETIME instead of TIMESTAMP .

MySQL stores TIMESTAMP in UTC value. However, MySQL stores the DATETIME value as is without
timezone. Let’s see the following example.

First, set the timezone of the current connection to +00:00 .

1 SET time_zone = '+00:00';

Next, create a table named timestamp_n_datetime that consists of two


columns: ts and dt with TIMESTAMP and DATETIME types using the following statement.

1 CREATE TABLE timestamp_n_datetime (


2 id INT AUTO_INCREMENT PRIMARY KEY,
3 ts TIMESTAMP,
4 dt DATETIME
5 );

Then, insert the current date and time into both ts and dt columns of the timestamp_n_datetime table,

1 INSERT INTO timestamp_n_datetime(ts,dt)


2 VALUES(NOW(),NOW());

After that, query data from the timestamp_n_datetime table.

1 SELECT
2 ts,
3 dt
4 FROM
5 timestamp_n_datetime;

Both values in DATETIME and TIMESTAMP columns are the same.

Finally, set the connection’s time zone to +03:00 and query data from the timestamp_n_datetime table
again.

1 SET time_zone = '+03:00';


2
3 SELECT
4 ts,
5 dt
6 FROM
7 timestamp_n_datetime;

As you can see, the value in the TIMESTAMP column is different. This is because the TIMESTAMP column
stores the date and time value in UTC when we changed the time zone, the value of
the TIMESTAMP column is adjusted according to the new time zone.

It means that if you use the TIMESTAMP data to store date and time values, you should take a serious
consideration when you move your database to a server located in a different time zone.

MySQL DATETIME functions


The following statement sets the variable @dt to the current date and time using the NOW() function.

1 SET @dt = NOW();

To query the value of the @dt variable, you use the following SELECT statement:

1 SELECT @dt;
MySQL DATE function
To extract the date portion from a DATETIME value, you use the DATE function as follows:

1 SELECT DATE(@dt);

This function is very useful in case you want to query data based on a date but the data stored in the
column is based on both date and time.

Let’s see the following example.

1 CREATE TABLE test_dt (


2 id INT AUTO_INCREMENT PRIMARY KEY,
3 created_at DATETIME
4 );
5
6 INSERT INTO test_dt(created_at)
7 VALUES('2015-11-05 14:29:36');

Suppose you want to know which row created on 2015-11-05 , you use the following query:

1 SELECT
2 *
3 FROM
4 test_dt
5 WHERE
6 created_at = '2015-11-05';

It returns no rows.

This is because the created_at column contains not only date but also time. To correct it, you use
the DATE function as follows:

1 SELECT
2 *
3 FROM
4 test_dt
5 WHERE
6 DATE(created_at) = '2015-11-05';
It returns one row as expected. In case the table has many rows, MySQL has to perform a full table scan
to locate the rows that match the condition.

MySQL TIME function


To extract the time portion from a DATETIME value, you use the TIME function as the following statement:

1 SELECT TIME(@dt);

MySQL YEAR, QUARTER, MONTH, WEEK, DAY, HOUR, MINUTE and


SECOND functions
To get the year, quarter, month, week, day, hour, minute, and second from a DATETIME value, you use
the functions as shown in the following statement:

1 SELECT
2 HOUR(@dt),
3 MINUTE(@dt),
4 SECOND(@dt),
5 DAY(@dt),
6 WEEK(@dt),
7 MONTH(@dt),
8 QUARTER(@dt),
9 YEAR(@dt);

MySQL DATE_FORMAT function


To format a DATETIME value, you use the DATE_FORMAT function. For example, the following statement
formats a DATETIME value based on the %H:%i:%s - %W %M %Y format:

1 SELECT DATE_FORMAT(@dt, '%H:%i:%s - %W %M %Y');

MySQL DATE_ADD function


To add an interval to a DATETIME value, you use DATE_ADD function as follows:
1 SELECT @dt start,
2 DATE_ADD(@dt, INTERVAL 1 SECOND) '1 second later',
3 DATE_ADD(@dt, INTERVAL 1 MINUTE) '1 minute later',
4 DATE_ADD(@dt, INTERVAL 1 HOUR) '1 hour later',
5 DATE_ADD(@dt, INTERVAL 1 DAY) '1 day later',
6 DATE_ADD(@dt, INTERVAL 1 WEEK) '1 week later',
7 DATE_ADD(@dt, INTERVAL 1 MONTH) '1 month later',
8 DATE_ADD(@dt, INTERVAL 1 YEAR) '1 year later';

MySQL DATE_SUB function


To subtract an interval from a DATETIME value, you use DATE_SUB function as follows:

1 SELECT @dt start,


2 DATE_SUB(@dt, INTERVAL 1 SECOND) '1 second before',
3 DATE_SUB(@dt, INTERVAL 1 MINUTE) '1 minute before',
4 DATE_SUB(@dt, INTERVAL 1 HOUR) '1 hour before',
5 DATE_SUB(@dt, INTERVAL 1 DAY) '1 day before',
6 DATE_SUB(@dt, INTERVAL 1 WEEK) '1 week before',
7 DATE_SUB(@dt, INTERVAL 1 MONTH) '1 month before',
8 DATE_SUB(@dt, INTERVAL 1 YEAR) '1 year before';

MySQL DATE_DIFF function


To calculate a difference in days between two DATETIME values, you use the DATEDIFF function. Notice
that the DATEDIFF function only considers the date part of a DATETIME value in the calculation.

See the following example.

First, create a table named datediff_test that has one column whose data type is DATETIME .

1 CREATE TABLE datediff_test (


2 dt DATETIME
3 );

Second, insert some rows into the datediff_test table.

1 INSERT INTO datediff_test(dt)


2 VALUES('2010-04-30 07:27:39'),
3 ('2010-05-17 22:52:21'),
4 ('2010-05-18 01:19:10'),
5 ('2010-05-22 14:17:16'),
6 ('2010-05-26 03:26:56'),
7 ('2010-06-10 04:44:38'),
8 ('2010-06-13 13:55:53');

Third, use the DATEDIFF function to compare the current date and time with the value in each row of
the datediff_test table.

1 SELECT
2 dt,
3 DATEDIFF(NOW(), dt)
4 FROM
5 datediff_test;

In this tutorial, you have learned about MySQL DATETIME data type and some useful DATETIME functions.

MySQL TIMESTAMP
Summary: in this tutorial, you will learn about MySQL TIMESTAMP and TIMESTAMP column features
such as automatic initialization and updating.

Introduction to MySQL TIMESTAMP


The MySQL TIMESTAMP is a temporal data type that holds the combination of date and time.

The format of a TIMESTAMP column is YYYY-MM-DD HH:MM:SS which is fixed at 19 characters.

The TIMESTAMP value has a range from '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07'
UTC .

When you insert a TIMESTAMP value into a table, MySQL converts it from your connection’s time zone to
UTC for storage. When you query a TIMESTAMP value, MySQL converts the UTC value back to your
connection’s time zone. Notice that this conversion does not take place for other temporal data types such
as DATETIME .
By default, the connection time zone is the MySQL database server’s time zone. You can use a different
time zone when you connect to MySQL database server.

When you retrieve a TIMESTAMP value that was inserted by a client in a different time zone, you will get a
value that is not the same as the value stored in the database. As long as you don’t change the time zone,
you can get the same TIMESTAMP value that you stored.

MySQL TIMESTAMP time zone example


Let’s look at an example to see how MySQL handles TIMESTAMP values.

First, created a new table named test_timestamp that has a TIMESTAMP column: t1 ;

1 CREATE TABLE IF NOT EXISTS test_timestamp (


2 t1 TIMESTAMP
3 );

Second, set session the time zone to ‘+00:00’ UTC by using the SET time_zone statement.

1 SET time_zone='+00:00';

Third, insert a TIMESTAMP value into the test_timestamp table.

1 INSERT INTO test_timestamp


2 VALUES('2008-01-01 00:00:01');

Fourth, select the TIMESTAMP value from the test_timestamp table.

1 SELECT
2 t1
3 FROM
4 test_timestamp;

Fifth, set the session’s time zone to a different time zone to see what value we get back from the database
server:

1 SET time_zone ='+03:00';


2
3 SELECT t1
4 FROM test_timestamp;

As you see, we received a different time value adjusted to the new time zone.

Automatic initialization and updating for TIMESTAMP columns

Let’s start with an example.

The following statement creates a table named categories :

1 CREATE TABLE categories (


2 id INT AUTO_INCREMENT PRIMARY KEY,
3 name VARCHAR(255) NOT NULL,
4 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
5 );

In the categories table, the created_at column is a TIMESTAMP column whose default value is set
to CURRENT_TIMESTAMP .

The following statement inserts a new row into the categories table without specifying the value for
the created_at column:

1 INSERT INTO categories(name)


2 VALUES ('A');

1 SELECT
2 *
3 FROM
4 categories;

As you can see, MySQL used the timestamp (at the time it inserted the row ) to initialize for
the created_at column.

So a TIMESTAMP column can be automatically initialized to the current timestamp for inserted rows that
specify no value for the column. This feature is called automatic initialization.
We will add a new column named updated_at to the categories table.

1 ALTER TABLE categories


2 ADD COLUMN updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;

The default value of the updated_at column is CURRENT_TIMESTAMP . However, there is a clause ON
UPDATE CURRENT_TIMESTAMP that follows the DEFAULT CURRENT_TIMESTAMP clause. We will find out its
meaning soon.

The following statement inserts a new row into the categories table.

1 INSERT INTO categories(name)


2 VALUES('B');

1 SELECT * FROM categories;

The default value of the created_at column is the timestamp when the row was inserted.

Now, we update the value in the name column of the row with id 2 and query data from
the categories table .

1 UPDATE categories
2 SET
3 name = 'B+'
4 WHERE
5 id = 2;

1 SELECT
2 *
3 FROM
4 categories
5 WHERE
6 id = 2;

Notice that the value in the updated_at column changed to the timestamp at the time the row was
updated.
The ability of a TIMESTAMP column to be automatically updated to the current timestamp when the value in
any other column in the row changed from it current value is called automatic updating.

The updated_at column is known as an auto-updated column.

Note that if you execute the UPDATE statement to update a same value for the name column,
the updated_at column will not be updated.

1 UPDATE categories
2 SET
3 name = 'B+'
4 WHERE
5 id = 2;

The value in the updated_at remains unchanged.

For more information on automatic initialized and updating, please check it out the time initialization on
MySQL website.

As of MySQL 5.6.5, the DATETIME columns also have automatic initialization and updating features. In
addition, the DEFAULT_CURRENT_TIMESTAMP and ON UPDATE CURRENT TIMESTAMP can be applied to
multiple columns.

In this tutorial, we have introduced you to MySQL TIMESTAMP data type and shown you how to use
automatic initialization and updating features of TIMESTAMP columns work.

A Practical Guide to MySQL JSON Data Type By


Example
Summary: in this tutorial, you will learn how to use MySQL JSON data type to store JSON documents in
the database.

Introduction to MySQL JSON data type


MySQL supports the native JSON data type since version 5.7.8. The native JSON data type allows you to
store JSON documents more efficiently than the JSON text format in the previous versions.

MySQL stores JSON documents in an internal format that allows quick read access to document
elements. The JSON binary format is structured in the way that permits the server to search for values
within the JSON document directly by key or array index, which is very fast.
The storage of a JSON document is approximately the same as the storage
of LONGBLOB or LONGTEXT data.

To define a column whose data type is JSON, you use the following syntax:

1 CREATE TABLE table_name (


2 ...
3 json_column_name JSON,
4 ...
5 );

Notice that a JSON column cannot have a default value. In addition, a JSON column cannot
be indexeddirectly. Instead, you can create an index on a generated column that contains values
extracted from the JSON column. When you query data from the JSON column, the MySQL optimizer will
look for compatible indexes on virtual columns that match JSON expressions.

MySQL JSON data type example


Suppose, we have to track the visitors and their actions on our website. Some visitors may just view the
pages and other may view the pages and buy the products. To store this information, we will create a new
table called events .

1 CREATE TABLE events(


2 id int auto_increment primary key,
3 event_name varchar(255),
4 visitor varchar(255),
5 properties json,
6 browser json
7 );

Each event in the events table has an id that uniquely identifies the event. An event also has a name
e.g., pageview, purchase, etc., The visitor column is used to store the visitor information.

The properties and browser columns are the JSON columns. They are used to store properties of an
event and specification of the browser that visitors use to browse the website.

Let’s insert some data into the events table:

1 INSERT INTO events(event_name, visitor,properties, browser)


2 VALUES (
3 'pageview',
4 '1',
5 '{ "page": "/" }',
6 '{ "name": "Safari", "os": "Mac", "resolution": { "x": 1920, "y": 1080 } }'
7 ),
8 ('pageview',
9 '2',
10 '{ "page": "/contact" }',
11 '{ "name": "Firefox", "os": "Windows", "resolution": { "x": 2560, "y": 1600 } }'
12 ),
13 (
14 'pageview',
15 '1',
16 '{ "page": "/products" }',
17 '{ "name": "Safari", "os": "Mac", "resolution": { "x": 1920, "y": 1080 } }'
18 ),
19 (
20 'purchase',
21 '3',
22 '{ "amount": 200 }',
23 '{ "name": "Firefox", "os": "Windows", "resolution": { "x": 1600, "y": 900 } }'
24 ),
25 (
26 'purchase',
27 '4',
28 '{ "amount": 150 }',
29 '{ "name": "Firefox", "os": "Windows", "resolution": { "x": 1280, "y": 800 } }'
30 ),
31 (
32 'purchase',
33 '4',
34 '{ "amount": 500 }',
35 '{ "name": "Chrome", "os": "Windows", "resolution": { "x": 1680, "y": 1050 } }'
36 );

To pull values out of the JSON columns, you use the column path operator ( -> ).

1 SELECT id, browser->'$.name' browser


2 FROM events;

This query returns the following output:

1 +----+-----------+
2 | id | browser |
3 +----+-----------+
4 | 1 | "Safari" |
5 | 2 | "Firefox" |
6 | 3 | "Safari" |
7 | 4 | "Firefox" |
8 | 5 | "Firefox" |
9 | 6 | "Chrome" |
10 +----+-----------+
11 6 rows in set (0.00 sec)

Notice that data in the browser column is surrounded by quote marks. To remove the quote marks, you
use the inline path operator ( ->> ) as follows:
1 SELECT id, browser->>'$.name' browser
2 FROM events;

As you can see in the following output, the quote marks were removed:

1 +----+---------+
2 | id | browser |
3 +----+---------+
4 | 1 | Safari |
5 | 2 | Firefox |
6 | 3 | Safari |
7 | 4 | Firefox |
8 | 5 | Firefox |
9 | 6 | Chrome |
10 +----+---------+
11 6 rows in set (0.00 sec)

To get the browser usage, you can use the following statement:

1 SELECT browser->>'$.name' browser,


2 count(browser)
3 FROM events
4 GROUP BY browser->>'$.name';
The output of the query is as follows:

1 +---------+----------------+
2 | browser | count(browser) |
3 +---------+----------------+
4 | Safari | 2|
5 | Firefox | 3|
6 | Chrome | 1|
7 +---------+----------------+
8 3 rows in set (0.02 sec)

To calculate the total revenue by the visitor, you use the following query:

1 SELECT visitor, SUM(properties->>'$.amount') revenue


2 FROM events
3 WHERE properties->>'$.amount' > 0
4 GROUP BY visitor;

Here is the output:

1 +---------+---------+
2 | visitor | revenue |
3 +---------+---------+
4|3 | 200 |
5|4 | 650 |
6 +---------+---------+
7 2 rows in set (0.00 sec)

In this tutorial, you have learned about the MySQL JSON data type and how to use it for storing JSON
documents in the database.

A Comprehensive Guide to Using MySQL ENUM


Summary: in this tutorial, you will learn how to use MySQL ENUM data type for defining columns that store
enumeration values.

Introduction to MySQL ENUM data type


In MySQL, an ENUM is a string object whose value is chosen from a list of permitted values defined at the
time of column creation.

The ENUM data type provides the following advantages:

 Compact data storage. MySQL ENUM uses numeric indexes (1, 2, 3, …) to represents string values.

 Readable queries and output.

To define an ENUM column, you use the following syntax:

1 CREATE TABLE table_name (


2 ...
3 col ENUM ('value1','value2','value3'),
4 ...
5 );

In this syntax, you can have more than three enumeration values. However, it is a good practice to keep
the number of enumeration values under 20.

Let’s see the following example.

Suppose, we have to store ticket information with the priority: low, medium, and high. To assign
the priority column the ENUM type, you use the following CREATE TABLE statement:

1 CREATE TABLE tickets (


2 id INT PRIMARY KEY AUTO_INCREMENT,
3 title VARCHAR(255) NOT NULL,
4 priority ENUM('Low', 'Medium', 'High') NOT NULL
5 );

The priority column will accept only three values Low , Medium and High . Behind the scenes, MySQL
maps each enumeration member to a numeric index. In this case, Low , Medium , and High are map to 1, 2
and 3 respectively.

Inserting MySQL ENUM values

To insert data into an ENUM column, you use the enumeration values in the predefined list. For example,
the following statement inserts a new row into the tickets table.

1 INSERT INTO tickets(title, priority)


2 VALUES('Scan virus for computer A', 'High');

Besides the enumeration values, you can use the numeric index of the enumeration member for inserting
data into an ENUM column. For instance, the following statement inserts a new ticket with the Low priority:

1 INSERT INTO tickets(title, priority)


2 VALUES('Upgrade Windows OS for all computers', 1);
In this example, instead of using the Low enumeration value, we used value 1. Since Low is mapped to 1,
it is acceptable.

Let’s add some more rows to the tickets table:

1 INSERT INTO tickets(title, priority)


2 VALUES('Install Google Chrome for Mr. John', 'Medium'),
3 ('Create a new user for the new employee David', 'High');

Because we defined the priority as a NOT NULL column, when you insert a new row without specifying
the value for the priority column, MySQL will use the first enumeration member as the default value.

See the following statement:

1 INSERT INTO tickets(title)


2 VALUES('Refresh the computer of Ms. Lily');

In the non-strict SQL mode, if you insert an invalid value into an ENUM column, MySQL will use an empty
string '' with the numeric index 0 for inserting. In case the strict SQL mode is enabled, trying to insert an
invalid ENUM value will result in an error.

Note that an ENUM column can accept NULL values if it is defined as a null-able column.
Filtering MySQL ENUM values

The following statement gets all high priority tickets:

1 SELECT
2 *
3 FROM
4 tickets
5 WHERE
6 priority = 'High';

Because the enumeration member ‘High’ is mapped to 3, the following query returns the same result set:

1 SELECT
2 *
3 FROM
4 tickets
5 WHERE
6 priority = 3;

Sorting MySQL ENUM values


MySQL sorts ENUM values based on their index numbers. Therefore, the order of member depends on
how they were defined in the enumeration list.

The following query selects the tickets and sorts them by the priority from High to Low :

1 SELECT
2 title, priority
3 FROM
4 tickets
5 ORDER BY priority DESC;
It’s always a good practice to define the enumeration values in the order that you want to sort when you
create the column.

MySQL ENUM disadvantages


MySQL ENUM has the following disadvantages:

1. Changing enumeration members requires rebuilding the entire table using the ALTER
TABLE statement, which is expensive in terms of resources and time.

Getting the complete enumeration list is complex because you need to access
the information_schema database:

1 SELECT
2 column_type
3 FROM
4 information_schema.COLUMNS
5 WHERE
6 TABLE_NAME = 'tickets'
7 AND COLUMN_NAME = 'priority';

2. Porting to other RDBMS could be an issue because ENUM is not SQL-standard and not many
database system support it.

3. Adding more attributes to the enumeration list is impossible. Suppose you want to add a service
agreement for each priority e.g., High (24h), Medium (1-2 days), Low (1 week), it is not possible
with ENUM . In this case, you need to have a separate table for storing priority list e.g., priorities(id,
name, sort_order, description) and replace the priority field in the tickets table
by priority_id that references to the id field of the priorities table.

4. Comparing to the look-up table ( priorities ), an enumeration list is not reusable. For example, if
you want to create a new table named tasks and want to reuse the priority list, it is not possible.

In this tutorial, we have introduced you to MySQL ENUM data type and how to use it for defining columns
that store enumeration values.

Section 14. MySQL constraints


 NOT NULL constraint – introduce you to the NOT NULL constraint and show you how to define
a NOT NULL constraint for a column or add the NOT NULL constraint to an existing column.

 Primary key constraint – guide you how to use primary key constraint to create the primary key for
a table.

 Foreign key constraint – introduce you to the foreign key and show you step by step how to create
and drop foreign keys.
 UNIQUE constraint – show you how to use UNIQUE constraint to enforce the uniqueness of values
in a column or a group of columns in a table.

 CHECK constraint emulation – walk you through various ways to emulate the CHECK constraint in
MySQL.

MySQL NOT NULL Constraint


Summary: this tutorial introduces you to the MySQL NOT NULL constraint that helps you keep your data
consistent.

Introduction to MySQL NOT NULL constraint


The NOT NULL constraint is a column constraint that forces the values of a column to non-NULL values
only.

The syntax of the NOT NULL constraint is as follows:

1 column_name data_type NOT NULL;

A column may contain one NOT NULL constraint only, which specifies a rule that the column must not
contain any NULL value.

The following CREATE TABLE statement creates the tasks table:

1 CREATE TABLE tasks (


2 id INT AUTO_INCREMENT PRIMARY KEY,
3 title VARCHAR(255) NOT NULL,
4 start_date DATE NOT NULL,
5 end_date DATE
6 );

The title and start_date columns have the NOT NULL constraints explicitly. The id column has
the PRIMARY KEY constraint, therefore, it implicitly includes a NOT NULL constraint.

The end_date column can have NULL values. This is because when we add a new task we may not know
its end date.

It’s a best practice to have the NOT NULL constraint in every column of a table unless you have a good
reason not to do so.

Generally, the NULL value makes your queries more complicated. In such cases, you can use the NOT
NULL constraint and provide a default value for the column. See the following example:

1 CREATE TABLE inventory (


2 material_no VARCHAR(18),
3 warehouse_no VARCHAR(10),
4 quantity DECIMAL(19 , 2 ) NOT NULL DEFAULT 0,
5 base_unit VARCHAR(10) NOT NULL,
6 PRIMARY KEY (material_no , warehouse_no)
7 );

In this example, the default value for quantity column is 0. Because at the time we add a row to
the inventory table, the value of the quantity column should be 0, not NULL .

Add a NOT NULL constraint to an existing column


Typically, you add a NOT NULL constraints to columns when you create the table. However, sometimes,
you want to add a NOT NULL constraint to NULL-able column of an existing table. In this case, you use the
following steps:

1. Check the current values of the column.

2. Update the NULL values to non-null values.

3. Add the NOT NULL constraint

Let’s take a look at an example.

We insert data into the tasks table for the demonstration.

1 INSERT INTO tasks(title ,start_date, end_date)


2 VALUES('Learn MySQL NOT NULL constraint', '2017-02-01','2017-02-02'),
3 ('Check and update NOT NULL constraint to your database', '2017-02-01',NULL);

Now, suppose you want to force users to give estimated end date when creating a new task. To do this,
you need to add the NOT NULL constraint to the end_date column of the tasks table.

First, check the value of end_date table. We use the IS NULL operator to check if the value in a column
is NULL or not:

1 SELECT
2 *
3 FROM
4 tasks
5 WHERE
6 end_date IS NULL;

The query returns one row with the end_date value is NULL .
Second, update the NULL values to non-null values. In this case, we can create a rule that if
the end_date is NULL , we make the end date one week after the start date.

1 UPDATE tasks
2 SET
3 end_date = start_date + 7
4 WHERE
5 end_date IS NULL;

Let’s check the change:

1 SELECT
2 *
3 FROM
4 tasks

Third, add the NOT NULL constraint to the code end_date column. To do it, you use the following ALTER
TABLE statement:

1 ALTER TABLE table_name


2 CHANGE old_column_name new_column_name new_column_definition;

In our case, the old column name and the new column name must be the same except for the column
definition that has the NOT NULL constraint:

1 ALTER TABLE tasks


2 CHANGE end_date end_date DATE NOT NULL;

Let’s verify the change by using the DESCRIBE statement:

1 DESCRIBE tasks;
As you see, the NOT NULL constraint was added to the end_date column.

In this tutorial, you have learned how to define NOT NULL constraint for a column and add the NOT
NULL constraint to an existing column.

MySQL Primary Key


Summary: in this tutorial, you will learn how to use MySQL primary key constraint to create a primary
key for the table.

Introduction to MySQL primary key


A primary key is a column or a set of columns that uniquely identifies each row in the table. You must
follow the rules below when you define a primary key for a table:

 A primary key must contain unique values. If the primary key consists of multiple columns, the
combination of values in these columns must be unique.

 A primary key column cannot contain NULL values. It means that you have to declare the primary
key column with the NOT NULL attribute. If you don’t, MySQL will force the primary key column
as NOT NULL implicitly.

 A table has only one primary key.

Because MySQL works faster with integers, the data type of the primary key column should be the integer
e.g., INT, BIGINT. You can choose a smaller integer type: TINYINT , SMALLINT , etc. However, you should
make sure that the range of values of the integer type for the primary key is sufficient for storing all
possible rows that the table may have.

A primary key column often has the AUTO_INCREMENT attribute that generates a unique sequence for the
key automatically. The primary key of the next row is greater than the previous one.

MySQL creates an index named PRIMARY with PRIMARY type for the primary key in a table.

Defining MySQL PRIMARY KEY Constraints


MySQL allows you to create a primary key by defining a primary key constraint when you create or modify
the table.

Defining MySQL PRIMARY KEY constraints using CREATE TABLE statement


MySQL allows you to create the primary key when you create the table using the CREATE
TABLEstatement. To create a PRIMARY KEY constraint for the table, you specify the PRIMARY KEY in the
primary key column’s definition.

The following example creates users table whose primary key is user_id column:
1 CREATE TABLE users(
2 user_id INT AUTO_INCREMENT PRIMARY KEY,
3 username VARCHAR(40),
4 password VARCHAR(255),
5 email VARCHAR(255)
6 );

You can also specify the PRIMARY KEY at the end of the CREATE TABLE statement as follows:

1 CREATE TABLE roles(


2 role_id INT AUTO_INCREMENT,
3 role_name VARCHAR(50),
4 PRIMARY KEY(role_id)
5 );
In case the primary key consists of multiple columns, you must specify them at the end of the CREATE
TABLE statement. You put a coma-separated list of primary key columns inside parentheses followed
the PRIMARY KEY keywords.

1 CREATE TABLE userroles(


2 user_id INT NOT NULL,
3 role_id INT NOT NULL,
4 PRIMARY KEY(user_id,role_id),
5 FOREIGN KEY(user_id) REFERENCES users(user_id),
6 FOREIGN KEY(role_id) REFERENCES roles(role_id)
7 );

Besides creating the primary key that consists of user_id and role_id columns, the statement also
created two foreign key constraints.

Defining MySQL PRIMARY KEY constraints using ALTER TABLE statement


If a table, for some reasons, does not have a primary key, you can use the ALTER TABLE statement to
add a column that has all necessary primary key’s characteristics to the primary key as the following
statement:

1 ALTER TABLE table_name


2 ADD PRIMARY KEY(primary_key_column);

The following example adds the id column to the primary key.

First, create the t1 table without defining the primary key.

1 CREATE TABLE t1(


2 id int,
3 title varchar(255) NOT NULL
4 );
Second, make the id column as the primary key of the t1 table.

1 ALTER TABLE t1
2 ADD PRIMARY KEY(id);

PRIMARY KEY vs. UNIQUE KEY vs. KEY


A KEY is a synonym for INDEX . You use the KEY when you want to create an index for a column or a set
of columns that is not the part of a primary key or unique key.

A UNIQUE index creates a constraint for a column whose values must be unique. Unlike
the PRIMARY index, MySQL allows NULL values in the UNIQUE index. A table can also have
multiple UNIQUE indexes.

For example, the email and username of a user in the users table must be unique. You can
define UNIQUE indexes for the email and username columns as the following statement:

Add a UNIQUE index for the username column.

1 ALTER TABLE users


2 ADD UNIQUE INDEX username_unique (username ASC) ;

Add a UNIQUE index for the email column.

1 ALTER TABLE users


2 ADD UNIQUE INDEX email_unique (email ASC) ;

In this tutorial, you have learned how to create a primary key for a new table or add a primary key for an
existing table.

MySQL Foreign Key


Summary: in this tutorial, you will learn about MySQL foreign key and how to create, add, and drop
foreign key constraints in MySQL.

Introduction to MySQL foreign key


A foreign key is a field in a table that matches another field of another table. A foreign key places
constraints on data in the related tables, which enables MySQL to maintain referential integrity.

Let’s take a look at the following database diagram in the sample database.
We have two tables: customers and orders. Each customer has zero or more orders and each order
belongs to only one customer. The relationship between customers table and orders table is one-to-
many, and it is established by a foreign key in the orders table specified by the customerNumber field.

The customerNumber field in the orders table relates to the customerNumber primary key field in
the customers table.

The customers table is called parent table or referenced table, and the orders table is known as child
table or referencing table.

A foreign key can be a column or a set of columns. The columns in the child table often refer to
the primary key columns in the parent table.

A table may have more than one foreign key, and each foreign key in the child table may refer to a
different parent table.

A row in the child table must contain values that exist in the parent table e.g., each order record in
the orders table must have a customerNumber that exists in the customers table. Multiple orders can
refer to the same customer therefore, this relationship is called one (customer) to many (orders), or one-
to-many.

Sometimes, the child and parent tables are the same. The foreign key refers back to the primary key of
the table e.g., the following employees table:
The reportTo column is a foreign key that refers to the employeeNumber column which is the primary
key of the employees table to reflect the reporting structure between employees i.e., each employee
reports to another employee and an employee can have zero or more direct reports. We have a
specific tutorial on the self-join to help you query data against this kind of table.

The reportTo foreign key is also known as recursive or self-referencing foreign key.
Foreign keys enforce referential integrity that helps you maintain the consistency and integrity of the data
automatically. For example, you cannot create an order for a non-existent customer.

In addition, you can set up a cascade on delete action for the customerNumber foreign key so that when
you delete a customer in the customers table, all the orders associated with the customer are also
deleted. This saves you time and efforts of using multiple DELETE statements or a DELETE JOIN
statement.

The same as deletion, you can also define a cascade on update action for the customerNumber foreign
key to perform the cross-table update without using multiple UPDATE statements or an UPDATE JOIN
statement.

In MySQL, the InnoDB storage engine supports foreign keys so that you must create InnoDB tables in
order to use foreign key constraints.

Creating foreign keys for tables


MySQL creating foreign key syntax
The following syntax illustrates how to define a foreign key in a child table in CREATE TABLE statement.

1 CONSTRAINT constraint_name
2 FOREIGN KEY foreign_key_name (columns)
3 REFERENCES parent_table(columns)
4 ON DELETE action
5 ON UPDATE action
Let’s examine the syntax in greater detail:

 The CONSTRAINT clause allows you to define constraint name for the foreign key constraint. If you
omit it, MySQL will generate a name automatically.

 The FOREIGN KEY clause specifies the columns in the child table that refers to primary key columns
in the parent table. You can put a foreign key name after FOREIGN KEY clause or leave it to let
MySQL create a name for you. Notice that MySQL automatically creates an index with
the foreign_key_name name.

 The REFERENCES clause specifies the parent table and its columns to which the columns in the child
table refer. The number of columns in the child table and parent table specified in the FOREIGN
KEY and REFERENCES must be the same.

 The ON DELETE clause allows you to define what happens to the records in the child table when the
records in the parent table are deleted. If you omit the ON DELETE clause and delete a record in the
parent table that has records in the child table refer to, MySQL will reject the deletion. In addition,
MySQL also provides you with actions so that you can have other options such as ON DELETE
CASCADE that ask MySQL to delete records in the child table that refers to a record in the parent
table when the record in the parent table is deleted. If you don’t want the related records in the child
table to be deleted, you use the ON DELETE SET NULL action instead. MySQL will set the foreign
key column values in the child table to NULL when the record in the parent table is deleted, with a
condition that the foreign key column in the child table must accept NULL values. Notice that if you
use ON DELETE NO ACTION or ON DELETE RESTRICT action, MySQL will reject the deletion.

 The ON UPDATE clause enables you to specify what happens to the rows in the child table when
rows in the parent table are updated. You can omit the ON UPDATE clause to let MySQL reject any
updates to the rows in the child table when the rows in the parent table are updated. The ON
UPDATE CASCADE action allows you to perform a cross-table update, and the ON UPDATE SET
NULL action resets the values in the rows in the child table to NULL values when the rows in the
parent table are updated. The ON UPDATE NO ACTION or UPDATE RESTRICT actions reject any
updates.

MySQL creating table foreign key example


The following example creates a dbdemo database and two tables: categories and products. Each
category has one or more products and each product belongs to only one category. The cat_id field in
the products table is defined as a foreign key with UPDATE ON CASCADE and DELETE ON
RESTRICT actions.

1 CREATE DATABASE IF NOT EXISTS dbdemo;


2
3 USE dbdemo;
4
5 CREATE TABLE categories(
6 cat_id int not null auto_increment primary key,
7 cat_name varchar(255) not null,
8 cat_description text
9 ) ENGINE=InnoDB;
10
11 CREATE TABLE products(
12 prd_id int not null auto_increment primary key,
13 prd_name varchar(355) not null,
14 prd_price decimal,
15 cat_id int not null,
16 FOREIGN KEY fk_cat(cat_id)
17 REFERENCES categories(cat_id)
18 ON UPDATE CASCADE
19 ON DELETE RESTRICT
20 )ENGINE=InnoDB;

Adding a foreign key to a table


MySQL adding foreign key syntax
To add a foreign key to an existing table, you use the ALTER TABLE statement with the foreign key
definition syntax above:

1 ALTER table_name
2 ADD CONSTRAINT constraint_name
3 FOREIGN KEY foreign_key_name(columns)
4 REFERENCES parent_table(columns)
5 ON DELETE action
6 ON UPDATE action;

MySQL adding foreign key example


Now, let’s add a new table named vendors and change the products table to include the vendor id field:

1 USE dbdemo;
2
3 CREATE TABLE vendors(
4 vdr_id int not null auto_increment primary key,
5 vdr_name varchar(255)
6 )ENGINE=InnoDB;
7
8 ALTER TABLE products
9 ADD COLUMN vdr_id int not null AFTER cat_id;

To add a foreign key to the products table, you use the following statement:

1 ALTER TABLE products


2 ADD FOREIGN KEY fk_vendor(vdr_id)
3 REFERENCES vendors(vdr_id)
4 ON DELETE NO ACTION
5 ON UPDATE CASCADE;

Now, the products table has two foreign keys, one refers to the categories table and another refers to
the vendors table.

Dropping MySQL foreign key


You also use the ALTER TABLE statement to drop foreign key as the following statement:

1 ALTER TABLE table_name


2 DROP FOREIGN KEY constraint_name;

In the statement above:

 First, you specify the table name from which you want to remove the foreign key.

 Second, you put the constraint name after the DROP FOREIGN KEY clause.

Notice that constraint_name is the name of the constraint specified when you created or added the
foreign key to the table. If you omit it, MySQL generates a constraint name for you.

To obtain the generated constraint name of a table, you use the SHOW CREATE TABLE statement as
follows:

1 SHOW CREATE TABLE table_name;

For example, to see the foreign keys of the products table, you use the following statement:

1 SHOW CREATE TABLE products;

The following is the output of the statement:

1 CREATE TABLE products (


2 prd_id int(11) NOT NULL AUTO_INCREMENT,
3 prd_name varchar(355) NOT NULL,
4 prd_price decimal(10,0) DEFAULT NULL,
5 cat_id int(11) NOT NULL,
6 vdr_id int(11) NOT NULL,
7 PRIMARY KEY (prd_id),
8 KEY fk_cat (cat_id),
9 KEY fk_vendor(vdr_id),
10
11 CONSTRAINT products_ibfk_2
12 FOREIGN KEY (vdr_id)
13 REFERENCES vendors (vdr_id)
14 ON DELETE NO ACTION
15 ON UPDATE CASCADE,
16
17 CONSTRAINT products_ibfk_1
18 FOREIGN KEY (cat_id)
19 REFERENCES categories (cat_id)
20 ON UPDATE CASCADE
21 ) ENGINE=InnoDB;

The products table has two foreign key constraints: products_ibfk_1 and products_ibfk_2
You can drop the foreign keys of the products table by using the following statement:

1 ALTER TABLE products


2 DROP FOREIGN KEY products_ibfk_1;
3
4 ALTER TABLE products
5 DROP FOREIGN KEY products_ibfk_2;

MySQL disabling foreign key checks


Sometimes, it is very useful to disable foreign key checks e.g., when you import data from a CSV file into
a table. If you don’t disable foreign key checks, you have to load data into a proper order i.e., you have to
load data into parent tables first and then child tables, which can be tedious. However, if you disable the
foreign key checks, you can load data in any orders.

Another example is that, unless you disable the foreign key checks, you cannot drop a table that is
referenced by a foreign key constraint. When you drop a table, any constraints that you defined for the
table are also removed.

To disable foreign key checks, you use the following statement:

1 SET foreign_key_checks = 0;

And of course, you can enable it using the statement below:

1 SET foreign_key_checks = 1;

In this tutorial, we have covered a lot about MySQL foreign key. We also introduced you to some very
handy statements that allow you to manage foreign keys effectively in MySQL.

MySQL UNIQUE Constraint


Summary: in this tutorial, you will learn about MySQL UNIQUE constraint to enforce the uniqueness of
the values in a column or a group of columns.
Introduction to MySQL UNIQUE constraint
Sometimes, you want to enforce the uniqueness value in a column e.g., the phones of the suppliers in the
suppliers table must be unique, or the combination of the supplier name and address must not be
duplicate.

To enforce this rule, you need to use the UNIQUE constraint.

The UNIQUE constraint is either column constraint or table constraint that defines a rule that constrains
values in a column or a group of columns to be unique.

To add the UNIQUE constraint to a column, you use the following syntax:

1 CREATE TABLE table_1(


2 column_name_1 data_type UNIQUE,
3 );

Or you can define the UNIQUE constraint as the table constraint as follows:

1 CREATE TABLE table_1(


2 ...
3 column_name_1 data_type,
4 ...
5 UNIQUE(column_name_1)
6 );

If you insert or update a value that causes a duplicate value in the column_name_1 column, MySQL will
issue an error message and reject the change.

In case you want to enforce unique values across columns, you must define the UNIQUE constraint as the
table constraint and separate the each column by a comma:

1 CREATE TABLE table_1(


2
3 ...
4 column_name_1 data_type,
5 column_name_2 data type,
6 ...
7 UNIQUE(column_name_1,column_name_2)
8 );

MySQL will use the combination of the values in both column_name_1 and column_name_2 columns to
evaluate the uniqueness.

If you want to assign a specific name to a UNIQUE constraint, you use the CONSTRAINT clause as follows:

1 CREATE TABLE table_1(


2 ...
3 column_name_1 data_type,
4 column_name_2 data type,
5 ...
6 CONSTRAINT constraint_name UNIQUE(column_name_1,column_name_2)
7 );

MySQL UNIQUE constraint example

The following statement creates a new table named suppliers with the two UNIQUE constraints:

1 CREATE TABLE IF NOT EXISTS suppliers (


2 supplier_id INT PRIMARY KEY AUTO_INCREMENT,
3 name VARCHAR(255) NOT NULL,
4 phone VARCHAR(12) NOT NULL UNIQUE,
5 address VARCHAR(255) NOT NULL,
6 CONSTRAINT uc_name_address UNIQUE (name , address)
7 );

The first UNIQUE constraint is applied on the phone column. It means that every supplier must have a
distinct phone number. In other words, no two suppliers have the same phone number.

The second UNIQUE constraint has a name uc_name_address that enforces the uniqueness of values in
the name and address columns. It means suppliers can have the same name or address, but cannot
have the same name and address.

Let’s insert some rows into the suppliers table to test the UNIQUE constraint.

The following statement inserts a row into to the suppliers table.

1 INSERT INTO suppliers(name, phone, address)


2 VALUES('ABC Inc', '408-908-2476','4000 North 1st Street, San Jose, CA, USA');

1 1 row(s) affected

We try to insert a different supplier but has the phone number that already exists in the suppliers table.

1 INSERT INTO suppliers(name, phone, address)


2 VALUES('XYZ Corporation', '408-908-2476','4001 North 1st Street, San Jose, CA, USA');

MySQL issued an error:

1 Error Code: 1062. Duplicate entry '408-908-2476' for key 'phone'

Let’s change the phone number to a different one and execute the insert statement again.

1 INSERT INTO suppliers(name, phone, address)


2 VALUES('XYZ Corporation', '408-908-2567','400 North 1st Street, San Jose, CA, USA');
1 1 row(s) affected

Now we execute the following INSERT statement to insert a row with the values in the name and address
columns that already exists.

1 INSERT INTO suppliers(name, phone, address)


2 VALUES('XYZ Corporation', '408-908-102','400 North 1st Street, San Jose, CA, USA');

MySQL issued an error.

1 Error Code: 1062. Duplicate entry 'XYZ Corporation-400 North 1st Street, San Jose, CA, USA' for key 'name'

Because the UNIQUE constraint uc_name_address was violated.

Managing MySQL UNIQUE constraints


When you add a unique constraint to a table MySQL creates a corresponding BTREE index to the
database. The following SHOW INDEX statement displays all indexes created on the suppliers table.

1 SHOW INDEX FROM classicmodels.suppliers;

As you see, there are two BTREE indexes corresponding to the two UNIQUE constraints created.

To remove a UNIQUE constraint, you use can use DROP INDEX or ALTER TABLE statement as follows:

1 DROP INDEX index_name ON table_name;

1 ALTER TABLE table_name


2 DROP INDEX index_name;

For example, to remove the uc_name_address constraint on the suppliers table, you the following
statement:

1 DROP INDEX uc_name_address ON suppliers;

Execute the SHOW INDEX statement again to verify if the uc_name_unique constraint has been removed.
1 SHOW INDEX FROM classicmodels.suppliers;

What if you want to add a UNIQUE constraint to a table that already exists?

To do this, you use the ALTER TABLE statement as follows:

1 ALTER TABLE table_name


2 ADD CONSTRAINT constraint_name UNIQUE (column_list);

For example, to add the uc_name_address UNIQUE constraint back to the suppliers table, you use the
following statement:

1 ALTER TABLE suppliers


2 ADD CONSTRAINT uc_name_address UNIQUE (name,address);

Note that the combination of values in the name and address columns must be unique in order to make
the statement execute successfully.

In this tutorial, you have learned how to use the MySQL UNIQUE constraint to enforce the uniqueness of
values in a column or a group of columns in a table.

MySQL CHECK Constraint Emulation


Summary: in this tutorial, you will learn how to use triggers or views with check option to emulate MySQL
CHECK constraint.

To follow this tutorial, you need to have a good understanding of triggers, views, and stored procedures.

Introduction to the SQL CHECK constraint


Standard SQL provides CHECK constraints that specify a value in a certain column must satisfy a
Boolean expression. For example, you can add a CHECK constraint to enforce the cost of a part to be
positive as follows:
1 CREATE TABLE IF NOT EXISTS parts (
2 part_no VARCHAR(18) PRIMARY KEY,
3 description VARCHAR(40),
4 cost DECIMAL(10 , 2 ) NOT NULL CHECK(cost > 0),
5 price DECIMAL (10,2) NOT NULL
6 );

SQL allows you to apply multiple CHECK constraints to a column or a CHECK constraint across multiple
columns. For example, to make sure that the price is always greater or equal cost, you use the CHECK
constraint as follows:

1 CREATE TABLE IF NOT EXISTS parts (


2 part_no VARCHAR(18) PRIMARY KEY,
3 description VARCHAR(40),
4 cost DECIMAL(10 , 2 ) NOT NULL CHECK (cost > 0),
5 price DECIMAL(10 , 2 ) NOT NULL CHECK (price > 0),
6 CHECK (price >= cost)
7 );

Once the CHECK constraints are in place, whenever you insert or update a value that causes the Boolean
expression evaluates to false, the check constraint is violated and the database system rejects the
change.

Unfortunately, MySQL does not support CHECK constraint. Actually, MySQL accepts the CHECK clause
in the CREATE TABLE statement but it ignores it silently.

MySQL CHECK constraint using triggers


The first way to simulate the CHECK constraint in MySQL, we use two triggers: BEFORE INSERT and
BEFORE UPDATE.

First, create the parts tables for the demonstration.

1 CREATE TABLE IF NOT EXISTS parts (


2 part_no VARCHAR(18) PRIMARY KEY,
3 description VARCHAR(40),
4 cost DECIMAL(10 , 2 ) NOT NULL,
5 price DECIMAL(10,2) NOT NULL
6 );

Second, create a stored procedure to check the values in the cost and price columns.

1 DELIMITER $$
2
3 CREATE PROCEDURE `check_parts`(IN cost DECIMAL(10,2), IN price DECIMAL(10,2))
4 BEGIN
5 IF cost < 0 THEN
6 SIGNAL SQLSTATE '45000'
7 SET MESSAGE_TEXT = 'check constraint on parts.cost failed';
8 END IF;
9
10 IF price < 0 THEN
11 SIGNAL SQLSTATE '45001'
12 SET MESSAGE_TEXT = 'check constraint on parts.price failed';
13 END IF;
14
15 IF price < cost THEN
16 SIGNAL SQLSTATE '45002'
17 SET MESSAGE_TEXT = 'check constraint on parts.price & parts.cost failed';
18 END IF;
19
20 END$$
21
22 DELIMITER ;

Third, create BEFORE INSERT and BEFORE UPDATE triggers. Inside the triggers, call
the check_parts() stored procedure.

1 -- before insert
2 DELIMITER $$
3 CREATE TRIGGER `parts_before_insert` BEFORE INSERT ON `parts`
4 FOR EACH ROW
5 BEGIN
6 CALL check_parts(new.cost,new.price);
7 END$$
8 DELIMITER ;
9 -- before update
10 DELIMITER $$
11 CREATE TRIGGER `parts_before_update` BEFORE UPDATE ON `parts`
12 FOR EACH ROW
13 BEGIN
14 CALL check_parts(new.cost,new.price);
15 END$$
16 DELIMITER ;

Fourth, insert a new row that satisfies all the following conditions:

 cost > 0
 And price > 0
And price >= cost
1 INSERT INTO parts(part_no, description,cost,price)
2 VALUES('A-001','Cooler',100,120);

1 1 row(s) affected

The INSERT statement invokes the BEFORE INSERT trigger and accepts the values.

The following INSERT statement fails because it violates the condition: cost > 0.

1 INSERT INTO parts(part_no, description,cost,price)


2 VALUES('A-002','Heater',-100,120);

1 Error Code: 1644. check constraint on parts.cost failed

The following INSERT statement fails because it violates the condition: price > 0.

1 INSERT INTO parts(part_no, description,cost,price)


2 VALUES('A-002','Heater',100,-120);

1 Error Code: 1644. check constraint on parts.price failed

The following INSERT statement fails because it violates the condition: price > cost.

1 INSERT INTO parts(part_no, description,cost,price)


2 VALUES('A-003','wiper',120,100);

Let’s see what we are having now in the parts table.

1 SELECT * FROM parts;

We try to update the cost to make it lower than the price:

1 UPDATE parts
2 SET price = 10
3 WHERE part_no = 'A-001';

1 Error Code: 1644. check constraint on parts.price & parts.cost failed


It was rejected.

So by using two triggers: BEFORE INSERT and BEFORE UPDATE , we are able to emulate the CHECK
constraint in MySQL.

MySQL CHECK constraint using an updatable view with check


option
The idea is to create a view with check option against the base table. In the SELECT statement of the
view, we select only valid rows that satisfy the CHECK conditions. Any insert or update against the view
will be rejected if it would cause the new row to not appear in the view.

First, drop the parts table to remove all the associated triggers and create a new table like
the parts table but have a different name parts_data :

1 DROP TABLE IF EXISTS parts;


2
3 CREATE TABLE IF NOT EXISTS parts_data (
4 part_no VARCHAR(18) PRIMARY KEY,
5 description VARCHAR(40),
6 cost DECIMAL(10 , 2 ) NOT NULL,
7 price DECIMAL(10,2) NOT NULL
8 );

Second, create a view named parts based on the parts_data table. By doing this, we can keep the
code of the applications that use the parts table remain intact. In addition, all the privileges to the
old parts table remain unchanged.

1 CREATE VIEW parts AS


2 SELECT
3 part_no, description, cost, price
4 FROM
5 parts
6 WHERE
7 cost > 0 AND price > 0 AND price >= cost
8 WITH CHECK OPTION;

Third, insert a new row into the parts_data table through the parts view:

1 INSERT INTO parts(part_no, description,cost,price)


2 VALUES('A-001','Cooler',100,120);

It is accepted because the new row is valid which can appear in the view.
However, the following statement fails because the new row would not appear in the view.

1 INSERT INTO parts_checked(part_no, description,cost,price)


2 VALUES('A-002','Heater',-100,120);

1 Error Code: 1369. CHECK OPTION failed 'classicmodels.parts_checked'

In this tutorial, we have introduced you to the standard SQL CHECK constraint and two ways to emulate
the CHECK constraint in MySQL.

Section 15. MySQL globalization


 MySQL character Set – discuss MySQL character set and show you step by step how to perform
various operations on character sets.

 MySQL collation – discuss MySQL collation and show you how to set character set and collations
for the MySQL server, database, tables, and columns.

MySQL Character Set


Summary: in this tutorial, you will learn about MySQL character set. After the tutorial, you will know how
to get all character sets in MySQL, how to convert strings between character sets, and how to configure
proper character sets for client connections.

Introduction to MySQL character set


A MySQL character set is a set of characters that are legal in a string. For example, we have an alphabet
with letters from a to z.We assign each letter a number, for example, a = 1 , b = 2 etc. The letter a is
a symbol, and the number 1 that associates with the letter a is the encoding. The combination of all
letters from a to z and their corresponding encodings is a character set.

Each character set has one or more collations that define a set of rules for comparing characters within
the character set. Check it out the MySQL collation tutorial to learn about the collations in MySQL.

MySQL supports various character sets that allow you to store almost every character in a string. To get
all available character sets in MySQL database server, you use the SHOW CHARACTER SET statement as
follows:

1 SHOW CHARACTER SET;


The default character set in MySQL is latin1 . If you want to store characters from multiple languages in
a single column, you can use Unicode character sets, which is utf8 or ucs2 .

The values in the Maxlen column specify the number of bytes that a character in a character set holds.

Some character sets contain single-byte characters e.g., latin1 , latin2 , cp850 , etc., whereas other
character sets contain multi-byte characters.

MySQL provides the LENGTH function to get a length of a string in bytes, and the CHAR_LENGTH function to
get the length of a string in characters. If a string contains the multi-bytes character, the result of
the LENGTH function is greater than the result of the CHAR_LENGTH() function. See the following example:

1 SET @str = CONVERT('MySQL Character Set' USING ucs2);


2 SELECT LENGTH(@str), CHAR_LENGTH(@str);

The CONVERT function converts a string into a specific character set. In this example, it converts the
character set of the MySQL Character Set string into ucs2 . Because ucs2 character set contains 2-
byte characters, therefore the length of the @str string in bytes is greater than its length in characters.

Notice that some character sets contain multi-byte characters, but their strings may contain only single-
byte characters e.g., utf8 as shown in the following statements:

1 SET @str = CONVERT('MySQL Character Set' USING utf8);


2 SELECT LENGTH(@str), CHAR_LENGTH(@str);
However, if a utf8 string contains special character e.g., ü in the pingüino string; its length in bytes is
different, see the following example:

1 SET @str = CONVERT('pingüino' USING utf8);


2 SELECT LENGTH(@str), CHAR_LENGTH(@str);

Converting between different character sets


MySQL provides two functions that allow you to convert strings between different character
sets: CONVERT and CAST . We have used the CONVERT function several times in the above examples.

The syntax of the CONVERT function is as follows:

1 CONVERT(expression USING character_set_name)

The CAST function is similar to the CONVERT function. It converts a string to a different character set:

1 CAST(string AS character_type CHARACTER SET character_set_name)

Take a look at the following example of using the CAST function:

1 SELECT CAST(_latin1'MySQL character set' AS CHAR CHARACTER SET utf8);

Setting character sets for client connections


When an application exchanges data with a MySQL database server, the default character set is latin1 .

However, if the database stores Unicode strings in the utf8 character set, using the latin1 character
set in the application would not be sufficient. Therefore, the application needs to specify a proper
character set when it connects to MySQL database server.

To configure a character set for a client connection, you can do one of the following ways:

 Issue the SET NAME statement after the client connected to the MySQL database server. For
example, to set a Unicode character set utf8 , you use the following statement:
1 SET NAMES 'utf8';

 If the application supports the --default-character-set option, you can use it to set the
character set. For example, mysql client tool supports --default-character-set and you can set
it up in the configuration file as follows:

1 [mysql]
2 default-character-set=utf8

 Some MySQL connectors allow you to set character set, for example, if you use PHP PDO, you can
set the character set in the data source name as follows:

1 $dsn ="mysql:host=$host;dbname=$db;charset=utf8";

Regardless of which way you use, make sure that the character set used by the application matches with
the character set stored in the MySQL database server.

In this tutorial, you have learned about MySQL character set, how to convert strings between character
sets and how to configure proper character sets for client connections.

MySQL Collation
Summary: in this tutorial, you will learn about MySQL collation and how to set character sets and
collations for the MySQL server, database, table, and column.

Introduction to MySQL collation


A MySQL collation is a set of rules used to compare characters in a particular character set. Each
character set in MySQL can have more than one collation, and has, at least, one default collation. Two
character sets cannot have the same collation.

MySQL provides you with the SHOW CHARACTER SET statement that allows you to get the default
collations of character sets as follows:

1 SHOW CHARACTER SET;


The values of the default collation column specify the default collations for the character sets.

By convention, a collation for a character set begins with the character set name and ends with _ci (case
insensitive) _cs (case sensitive) or _bin (binary).

To get all collations for a given character set, you use the SHOW COLLATION statement as follows:

1 SHOW COLLATION LIKE 'character_set_name%';

For example, to get all collations for the latin1 character set, you use the following statement:

1 SHOW COLLATION LIKE 'latin1%';

MySQL Collations for latin1 Character Set

As mentioned above, each character set has at a default collation e.g., latin1_swedish_ci is the default
collation for the latin1 character set.

Setting character sets and collations


MySQL allows you to specify character sets and collations at four levels: server, database, table, and
column.

Setting character sets and collations at server Level


Notice MySQL uses latin1 as the default character set, therefore, its default collation
is latin1_swedish_ci . You can change these settings at server startup.

If you specify only a character set at server startup, MySQL will use the default collation of the character
set. If you specify both a character set and a collation explicitly, MySQL will use the character set and
collation for all databases created in the database server.

The following statement sets the utf8 character set and utf8_unicode_cs collation for the server via
command line:

1 >mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci

Setting character sets and collations at database level


When you create a database, if you do not specify its character set and collation, MySQL will use the
default character set and collation of the server for the database.

You can override the default settings at database level by using CREATE DATABASE or ALTER
DATABASEstatement as follows:

1 CREATE DATABASE database_name


2 CHARACTER SET character_set_name
3 COLLATE collation_name

1 ALTER DATABASE database_name


2 CHARACTER SET character_set_name
3 COLLATE collation_name

MySQL uses the character set and collation at the database level for all tables created within the
database.

Setting character sets and collations at table level


A database may contain tables with character sets and collations that are different from the default
database’s character set and collation.

You can specify the default character set and collation for a table when you create the table by using
the CREATE TABLE statement or when you alter the table’s structure by using the ALTER
TABLE statement.
1 CREATE TABLE table_name(
2)
3 CHARACTER SET character_set_name
4 COLLATE collation_name

1 ALTER TABLE table_name(


2)
3 CHARACTER SET character_set_name
4 COLLATE collation_name

Setting character set and collation at column level


A column of type CHAR , VARCHAR or TEXT can have its own character set and collation that is different
from the default character set and collation of the table.

You can specify a character set and a collation for the column in the column’s definition of either CREATE
TABLE or ALTER TABLE statement as follows:

1 column_name [CHAR | VARCHAR | TEXT] (length)


2 CHARACTER SET character_set_name
3 COLLATE collation_name

These are the rules for setting the character set and collation:

 If you specify both a character set and a collation explicitly, the character set and collation are used.

 If you specify a character set and omit the collation, the default collation of the character set is used.

 If you specify a collation without a character set, the character set associated with the collation is
used.

 If you omit both character set and collation, the default character set and collation are used.

Let’s take a look at some examples of setting the character sets and collations.

Examples of setting character sets and collations


First, we create a new database with utf8 as the character set and utf8_unicode_ci as the default collation:

1 CREATE DATABASE mydbdemo


2 CHARACTER SET utf8
3 COLLATE utf8_unicode_ci;

Because we specify the character set and collation for the mydbdemo database explicitly,
the mydbdemo does not take the default character set and collation at the server level.
Second, we create a new table named t1 in the mydbdemo database:

1 USE mydbdemo;
2 CREATE TABLE t1(
3 c1 char(25)
4 );

We did not specify the character set and collation for the t1 table; MySQL will check the database level to
determine the character set and collation for the t1 table. In this case, the t1 table has utf8 as the
default character set and utf8_unicode_ci as the default collation.

Third, for the t1 table, we change its character set to latin1 and its collation to latin1_german1_ci :

1 ALTER TABLE t1
2 CHARACTER SET latin1
3 COLLATE latin1_german1_ci;

The c1 column in the t1 table has latin1 as the character set and latin1_german1_ci as the collation.
Fourth, let’s change the character set of the c1 column to latin1 :

1 ALTER TABLE t2
2 MODIFY c1 VARCHAR(25)
3 CHARACTER SET latin1;

Now, the c1 column has the latin1 character set, but what about its collation? Is it inheriting
the latin1_german1_ci collation from the table’s collation? No, because the default collation of
the latin1 character set is latin1_swedish_ci , the c1 column has the latin1_swedish_ci collation.

In this tutorial, you have learned about MySQL collation and how to specify character sets and collations
for MySQL server, databases, tables and columns.

Reference
 http://dev.mysql.com/doc/refman/5.7/en/charset.html – MySQL character set support
 http://collation-charts.org/mysql60/ – MySQL collation charts

Section 16. MySQL import & export


 Import CSV File Into MySQL Table – show you how to use LOAD DATA INFILE statement to import
CSV file into a MySQL table.

 MySQL Export Table to CSV – learn various techniques of how to export MySQL table to a CSV file
format.
Import CSV File Into MySQL Table
This tutorial shows you how to use the LOAD DATA INFILE statement to import CSV file into MySQL
table.

The LOAD DATA INFILE statement allows you to read data from a text file and import the file’s data into a
database table very fast.

Before importing the file, you need to prepare the following:

 A database table to which the data from the file will be imported.

 A CSV file with data that matches with the number of columns of the table and the type of data in
each column.

 The account, which connects to the MySQL database server, has FILE and INSERT privileges.

Suppose we have a table named discounts with the following structure:

We use CREATE TABLE statement to create the discounts table as follows:

1 CREATE TABLE discounts (


2 id INT NOT NULL AUTO_INCREMENT,
3 title VARCHAR(255) NOT NULL,
4 expired_date DATE NOT NULL,
5 amount DECIMAL(10 , 2 ) NULL,
6 PRIMARY KEY (id)
7 );

The following discounts.csv file contains the first line as column headings and other three lines of data.
The following statement imports data from the c:\tmp\discounts.csv file into the discounts table.

1 LOAD DATA INFILE 'c:/tmp/discounts.csv'


2 INTO TABLE discounts
3 FIELDS TERMINATED BY ','
4 ENCLOSED BY '"'
5 LINES TERMINATED BY '\n'
6 IGNORE 1 ROWS;

The field of the file is terminated by a comma indicated by FIELD TERMINATED BY ',' and enclosed by
double quotation marks specified by ENCLOSED BY '" ‘.

Each line of the CSV file is terminated by a newline character indicated by LINES TERMINATED BY '\n' .

Because the file has the first line that contains the column headings, which should not be imported into the
table, therefore we ignore it by specifying IGNORE 1 ROWS option.

Now, we can check the discounts table to see whether the data is imported.

1 SELECT * FROM discounts;

Transforming data while importing


Sometimes the format of the data does not match the target columns in the table. In simple cases, you
can transform it by using the SET clause in the LOAD DATA INFILE statement.

Suppose the expired date column in the discount_2.csv file is in mm/dd/yyyy format.

When importing data into the discounts table, we have to transform it into MySQL date format by
using str_to_date() function as follows:

1 LOAD DATA INFILE 'c:/tmp/discounts_2.csv'


2 INTO TABLE discounts
3 FIELDS TERMINATED BY ',' ENCLOSED BY '"'
4 LINES TERMINATED BY '\n'
5 IGNORE 1 ROWS
6 (title,@expired_date,amount)
7 SET expired_date = STR_TO_DATE(@expired_date, '%m/%d/%Y');

Importing file from client to a remote MySQL database server


It is possible to import data from client (local computer) to a remote MySQL database server using
the LOAD DATA INFILE statement.

When you use the LOCAL option in the LOAD DATA INFILE , the client program reads the file on the client
and sends it to the MySQL server. The file will be uploaded into the database server operating system’s
temporary folder e.g., C:\windows\temp on Windows or /tmp on Linux. This folder is not configurable
or determined by MySQL.

Let’s take a look at the following example:

1 LOAD DATA LOCAL INFILE 'c:/tmp/discounts.csv'


2 INTO TABLE discounts
3 FIELDS TERMINATED BY ','
4 ENCLOSED BY '"'
5 LINES TERMINATED BY '\n'
6 IGNORE 1 ROWS;

The only difference is the LOCAL option in the statement. If you load a big CSV file, you will see that with
the LOCAL option, it will be a little bit slower to load the file because it takes time to transfer the file to the
database server.

The account that connects to MySQL server doesn’t need to have the FILE privilege to import the file
when you use the LOCAL option.

Importing the file from client to a remote database server using LOAD DATA LOCAL has some security
issues that you should be aware of to avoid potential security risks.

Importing CSV file using MySQL Workbench


MySQL workbench provides a tool to import data into a table. It allows you to edit data before making
changes.

The following are steps that you want to import data into a table:

Open table to which the data is loaded.


Click Import button, choose a CSV file and click Open button

Review the data, click Apply button.


MySQL workbench will display a dialog “Apply SQL Script to Database”, click Apply button to insert data
into the table.

We have shown you how to import CSV into MySQL table using LOAD DATA LOCAL and using MySQL
Workbench. With these techniques, you can load data from other text file formats such as tab-delimited.
MySQL Export Table to CSV
Summary: in this tutorial, you will learn various techniques of how to export a MySQL table to a CSV file.

The CSV stands for comma separated values. You often use the CSV file format to exchange data
between applications such as Microsoft Excel, Open Office, Google Docs, etc.

It will be useful to have data from MySQL database in CSV file format because you can analyze and
format the data in the way you want.

MySQL provides an easy way to export the query’s result into a CSV file that resides in the database
server.

Before exporting data, you must ensure that:

 The MySQL server’s process has the write access to the target folder that contains the target CSV
file.
 The target CSV file must not exist.

The following query selects cancelled orders from the orders table:

1 SELECT
2 orderNumber, status, orderDate, requiredDate, comments
3 FROM
4 orders
5 WHERE
6 status = 'Cancelled';

To export this result set into a CSV file, you add some clauses to the query above as follows:

1 SELECT
2 orderNumber, status, orderDate, requiredDate, comments
3 FROM
4 orders
5 WHERE
6 status = 'Cancelled'
7 INTO OUTFILE 'C:/tmp/cancelled_orders.csv'
8 FIELDS ENCLOSED BY '"'
9 TERMINATED BY ';'
10 ESCAPED BY '"'
11 LINES TERMINATED BY '\r\n';

The statement created a CSV file named cancelled_orders.csv in the C:\tmp folder that contains the
result set.
The CSV file contains lines of rows in the result set. Each line is terminated by a sequence of carriage
return and a line feed character specified by the LINES TERMINATED BY '\r\n' clause. Each line
contains values of each column of the row in the result set.

Each value is enclosed by double quotation marks indicated by FIELDS ENCLOSED BY '”' clause. This
prevents the value that may contain a comma (,) will be interpreted as the field separator. When enclosing
the values by the double quotation marks, the commas inside the value are not recognized as the field
separators.

Exporting data to a CSV file whose filename contains timestamp


You often need to export data into a CSV file whose name contains timestamp at which the file is created.
To do so, you need to use the MySQL prepared statement.

The following commands export the whole orders table into a CSV file with timestamp as a part of the file
name.

1 SET @TS = DATE_FORMAT(NOW(),'_%Y_%m_%d_%H_%i_%s');


2
3 SET @FOLDER = 'c:/tmp/';
4 SET @PREFIX = 'orders';
5 SET @EXT = '.csv';
6
7 SET @CMD = CONCAT("SELECT * FROM orders INTO OUTFILE '",@FOLDER,@PREFIX,@TS,@EXT,
8 "' FIELDS ENCLOSED BY '\"' TERMINATED BY ';' ESCAPED BY '\"'",
9 " LINES TERMINATED BY '\r\n';");
10
11 PREPARE statement FROM @CMD;
12
13 EXECUTE statement;

Let’s examine the commands above in more detail.

 First, we constructed a query with current timestamp as a part of the file name.

 Second, we prepared the statement for execution by using PREPARE statement FROM command.

 Third, we executed the statement by using the EXECUTE command.

You can wrap the command by an event and schedule the event run periodically if needed.

Exporting data with column headings


It would be convenient if the CSV file contains the first line as the column headings so that the file is more
understandable.
To add the column headings, you need to use the UNION statement as follows:

1 (SELECT 'Order Number','Order Date','Status')


2 UNION
3 (SELECT orderNumber,orderDate, status
4 FROM orders
5 INTO OUTFILE 'C:/tmp/orders.csv'
6 FIELDS ENCLOSED BY '"' TERMINATED BY ';' ESCAPED BY '"'
7 LINES TERMINATED BY '\r\n');

As the query showed, you need to include the column heading of every column.

Handling NULL values


In case the values in the result set contain NULL values, the target file will contain "N instead of NULL . To
fix this issue, you need to replace the NULL value by another value e.g., not applicable ( N/A ) by using
the IFNULL function as the following query:

1 SELECT
2 orderNumber, orderDate, IFNULL(shippedDate, 'N/A')
3 FROM
4 orders INTO OUTFILE 'C:/tmp/orders2.csv'
5 FIELDS ENCLOSED BY '"'
6 TERMINATED BY ';'
7 ESCAPED BY '"' LINES
8 TERMINATED BY '\r\n';

We replaced NULL values in the shippedDate column by the N/A strings. The CSV file
shows N/A instead of NULL values.

Exporting data to CSV file using MySQL Workbench


In case you don’t have access to the database server to get the exported CSV file, you can use MySQL
Workbench to export the result set of a query to a CSV file in your local computer as follows:

 First, execute a query get its result set.


 Second, from the result panel, click “export recordset to an external file”. The result set is also
known as a recordset.
 Third, a new dialog displays. It asks you for a filename and file format. Enter the file name, choose
CSV as the file format and click Save button.
The CSV file exported by MySQL Workbench supports column headings, NULL values and other great
features.

You might also like