MySQL quick tutorial
last modified January 10, 2023
The MySQL quick tutorial will quickly introduce you to the basics of the MySQL database.
The world database
The MySQL documentation website offers some example databases. We are going to use a world database. The data is outdated but it does not matter for our test purposes.
$ wget http://downloads.mysql.com/docs/world.sql.gz
We download the compressed file with the wget
tool.
$ ls -sh world.sql.gz 92K world.sql.gz
The compressed file has about 92KB.
$ gunzip world.sql.gz
We unzip the file. We have a world.sql
file.
$ ls -hs world.sql 392K world.sql
The uncompressed file has 392KB.
$ mysql -uroot -p
We connect to the server with the root account. We need the root account to create a new database and give permissions to our test account for the new database.
mysql> CREATE DATABASE world;
The world database is created.
mysql> USE world;
We change to the world database. Now the world database is the current database.
mysql> source world.sql
We build the tables of the world database by executing
world.sql
SQL script. It takes some time.
mysql> GRANT ALL ON world.* TO 'user12'@'localhost';
We grant privileges to all objects of the world database to the
user12
.
mysql> quit Bye $ mysql -u user12 -p Enter password: mysql> USE world;
We quit the connection. Reconnect with the user12
test account
and change to the world database. We are ready for work.
Examining the database
In this section, we are going to look at the tables of the world database in general.
mysql> SHOW TABLES; +-----------------+ | Tables_in_world | +-----------------+ | city | | country | | countrylanguage | +-----------------+ 3 rows in set (0,00 sec)
We show all available tables with the SHOW TABLES
statement. There
are three.
mysql> DESCRIBE city; +-------------+----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------+----------+------+-----+---------+----------------+ | ID | int(11) | NO | PRI | NULL | auto_increment | | Name | char(35) | NO | | | | | CountryCode | char(3) | NO | MUL | | | | District | char(20) | NO | | | | | Population | int(11) | NO | | 0 | | +-------------+----------+------+-----+---------+----------------+ 5 rows in set (0,00 sec)
With the DESCRIBE
statement, we can see the table structure
of the City
table. We see the column names and their data
types. Plus other important information.
mysql> SHOW CREATE TABLE city;
If we wanted to find out the SQL to create the City
table, we would
issue the SHOW CREATE TABLE city
statement.
$ mysqldump -u root -p world city > city.sql
Here we use the mysqldump
tool to back up the
city
table.
mysql> DROP TABLE city; mysql> SHOW TABLES; +-----------------+ | Tables_in_world | +-----------------+ | country | | countrylanguage | +-----------------+ 2 rows in set (0,00 sec)
We use the DROP TABLE
statement to drop the
city
table. Subsequent statement verifies that the table
was removed.
mysql> source city.sql mysql> SHOW TABLES; +-----------------+ | Tables_in_world | +-----------------+ | city | | country | | countrylanguage | +-----------------+ 3 rows in set (0,00 sec)
We recreate the city
table from the backup. The
source command executes the backup city.sql
script.
Queries
Queries are used to look up data from the database tables.
Limiting data output
There are thousands of rows in the tables of the database. They
cannot be displayed all on the screen. We can control the number
of rows to be displayed with the LIMIT
clause.
mysql> SELECT Id, Name, Population FROM city limit 10; +----+----------------+------------+ | Id | Name | Population | +----+----------------+------------+ | 1 | Kabul | 1780000 | | 2 | Qandahar | 237500 | | 3 | Herat | 186800 | | 4 | Mazar-e-Sharif | 127800 | | 5 | Amsterdam | 731200 | | 6 | Rotterdam | 593321 | | 7 | Haag | 440900 | | 8 | Utrecht | 234323 | | 9 | Eindhoven | 201843 | | 10 | Tilburg | 193238 | +----+----------------+------------+ 10 rows in set (0,00 sec)
In the above query, we show three of the five columns of the
City
table. There are lots of rows in the table. We limit
the query to the first 10 rows.
mysql> SELECT Id, Name, Population FROM city limit 15, 5; +----+-------------------+------------+ | Id | Name | Population | +----+-------------------+------------+ | 16 | Haarlem | 148772 | | 17 | Almere | 142465 | | 18 | Arnhem | 138020 | | 19 | Zaanstad | 135621 | | 20 | ´s-Hertogenbosch | 129170 | +----+-------------------+------------+ 5 rows in set (0,00 sec)
The LIMIT
clause can be followed by two numbers. The first one
is the offset and the second one is the number of rows to display. Our
query shows rows 16-20.
mysql> pager less PAGER set to 'less' mysql> SELECT * FROM city; +------------------------------------+------------+ | Name | Population | +------------------------------------+------------+ | Kabul | 1780000 | | Qandahar | 237500 | | Herat | 186800 | ... :
Since the city
table has more than four thousand rows, we
cannot see them in one screen. We can use the pager command to show the data in a
less program. We can navigate through the data with the cursor keys or
page down, page up keys. If we want to go the the default setting, simply
hit the pager without any argument.
$ mysql -u user12 -p world -e "SELECT * FROM city" > city Enter password: $ ls -sh city 144K city
The mysql
command tool can be used in a non-interactive way.
We specify the SQL statement after the -e
option and redirect
the result to the city file. Now we can use any text editor to display the data.
The COUNT(), MAX(), MIN() functions
The COUNT(), MAX(), MIN() are MySQL aggregate functions which compute some value from aggregate data.
mysql> SELECT COUNT(Id) AS '# of cities' FROM city; +-------------+ | # of cities | +-------------+ | 4079 | +-------------+ 1 row in set (0,00 sec)
There are 4079 cities in the table. We use the built-in
COUNT()
function to find out the number of rows.
mysql> SELECT Name, Population FROM city -> WHERE Population = (SELECT Max(Population) FROM city); +-----------------+------------+ | Name | Population | +-----------------+------------+ | Mumbai (Bombay) | 10500000 | +-----------------+------------+ 1 row in set (0,08 sec)
The above query shows the most populated city in the table. The SQL is a special type of a query called a subquery. The outer query uses the data returned by the inner query. The inner query is bounded by parentheses.
mysql> SELECT Name, Population FROM city -> WHERE Population = (SELECT Min(Population) FROM city); +-----------+------------+ | Name | Population | +-----------+------------+ | Adamstown | 42 | +-----------+------------+ 1 row in set (0,02 sec)
This subquery shows the least populated city in the table.
Selecting specific rows with the WHERE clause
The WHERE
clause can be used to filter the results. It provides
a selection criteria to select only specific rows from the data.
mysql> SELECT Name, Population FROM city -> WHERE Population > 1000000; +--------------------------+------------+ | Name | Population | +--------------------------+------------+ | Kabul | 1780000 | | Alger | 2168000 | | Luanda | 2022000 | | Buenos Aires | 2982146 | | La Matanza | 1266461 | | Córdoba | 1157507 | | Yerevan | 1248700 | | Sydney | 3276207 | ...
The above SQL statement returns all cities with a population above one million people.
mysql> SELECT Name FROM city WHERE Name LIKE 'Kal%'; +-------------+ | Name | +-------------+ | Kalookan | | Kalyan | | Kalemie | | Kallithea | | Kalisz | | Kaliningrad | | Kaluga | +-------------+ 7 rows in set (0,00 sec)
Here we select all city names which begin with 'Kal'. We have found seven
cities in the table. We can look for a specific pattern in the column with
the LIKE
clause.
mysql> SELECT Name, Population FROM city WHERE ID IN (5, 23, 432, 2021); +------------+------------+ | Name | Population | +------------+------------+ | Amsterdam | 731200 | | Dordrecht | 119811 | | Eunápolis | 96610 | | Jining | 265248 | +------------+------------+ 4 rows in set (0,05 sec)
This SQL code returns cities and their populations for rows with ID 5, 23, 432, and 2021.
mysql> SELECT * FROM city WHERE Name = 'Bratislava'; +------+------------+-------------+------------+------------+ | ID | Name | CountryCode | District | Population | +------+------------+-------------+------------+------------+ | 3209 | Bratislava | SVK | Bratislava | 448292 | +------+------------+-------------+------------+------------+ 1 row in set (0,00 sec)
With the above SQL statement we select all columns for one specific city, namely Bratislava.
mysql> SELECT Name, Population FROM city -> WHERE Population BETWEEN 670000 AND 700000; +----------------+------------+ | Name | Population | +----------------+------------+ | Teresina | 691942 | | Natal | 688955 | | Bandar Lampung | 680332 | | Gwalior | 690765 | | Kermanshah | 692986 | | Palermo | 683794 | | Toronto | 688275 | | Huainan | 700000 | | Jixi | 683885 | | Antananarivo | 675669 | | Chihuahua | 670208 | | Kano | 674100 | | Tunis | 690600 | +----------------+------------+ 13 rows in set (0,03 sec)
Say we wanted to find out cities with a population between two specific
values. There is a BETWEEN
operator for this. We have found
thirteen cities with a population in the range 670,000 and 700,000.
Ordering data
Ordering data can be done with the ORDER BY
clause.
mysql> SELECT Name, Population FROM city -> ORDER BY Population DESC LIMIT 10; +-------------------+------------+ | Name | Population | +-------------------+------------+ | Mumbai (Bombay) | 10500000 | | Seoul | 9981619 | | São Paulo | 9968485 | | Shanghai | 9696300 | | Jakarta | 9604900 | | Karachi | 9269265 | | Istanbul | 8787958 | | Ciudad de México | 8591309 | | Moscow | 8389200 | | New York | 8008278 | +-------------------+------------+ 10 rows in set (0,03 sec)
We find the ten most populated cities. We order the data by population from
the most populated to the least populated city. We limit the output with the
LIMIT
clause.
mysql> SELECT Name, Population FROM city -> ORDER BY Population ASC LIMIT 10; +---------------------+------------+ | Name | Population | +---------------------+------------+ | Adamstown | 42 | | West Island | 167 | | Fakaofo | 300 | | Città del Vaticano | 455 | | Bantam | 503 | | Yaren | 559 | | The Valley | 595 | | Alofi | 682 | | Flying Fish Cove | 700 | | Kingston | 800 | +---------------------+------------+ 10 rows in set (0,02 sec)
Here we get the least populated cities. This time we order the data
in the ascending order. For this we use the ASC
keyword.
mysql> SELECT Name, Population FROM city ORDER By Name LIMIT 10; +------------------------+------------+ | Name | Population | +------------------------+------------+ | A Coruña (La Coruña) | 243402 | | Aachen | 243825 | | Aalborg | 161161 | | Aba | 298900 | | Abadan | 206073 | | Abaetetuba | 111258 | | Abakan | 169200 | | Abbotsford | 105403 | | Abeokuta | 427400 | | Aberdeen | 213070 | +------------------------+------------+ 10 rows in set (0.01 sec)
In the above SQL statement we order data by city name and get the first ten cities.
Grouping data
The GROUP BY
clause is used to combine database records with
identical values into a single record. It is often used with the
aggregation functions.
mysql> SELECT District, SUM(Population) FROM city -> WHERE District = 'New York' GROUP BY District; +----------+-----------------+ | District | SUM(Population) | +----------+-----------------+ | New York | 8958085 | +----------+-----------------+ 1 row in set (0,09 sec)
The above SQL statement returns the total number of people in the towns of the New York district, which are listed in our database.
mysql> SELECT Name, District FROM city WHERE District = 'New York'; +-----------+----------+ | Name | District | +-----------+----------+ | New York | New York | | Buffalo | New York | | Rochester | New York | | Yonkers | New York | | Syracuse | New York | | Albany | New York | +-----------+----------+ 6 rows in set (0,00 sec)
The previous number is a sum of these six cities.
mysql> SELECT District, SUM(Population) FROM city -> WHERE CountryCode = 'USA' GROUP BY District -> HAVING SUM(Population) > 3000000; +------------+-----------------+ | District | SUM(Population) | +------------+-----------------+ | Arizona | 3178903 | | California | 16716706 | | Florida | 3151408 | | Illinois | 3737498 | | New York | 8958085 | | Texas | 9208281 | +------------+-----------------+ 6 rows in set (0,28 sec)
We select all districts which have population over 3 million people. When
we work with groups of data, we use the HAVING
clause instead
of the WHERE
clause.
Updating, deleting, and inserting data
Next we will concern ourselves with updating, deleting, and inserting data.
mysql> SELECT Name, HeadOfState FROM country WHERE Name = 'United States'; +---------------+----------------+ | Name | HeadOfState | +---------------+----------------+ | United States | George W. Bush | +---------------+----------------+ 1 row in set (0,12 sec)
As we have already stated, the world database is outdated. George Bush is not the president of the USA anymore.
mysql> UPDATE country SET HeadOfState = 'Donald Trump' -> WHERE Name = 'United States';
With the UPDATE
statement we change the row to the
actual data.
mysql> SELECT Name, HeadOfState FROM country WHERE Name = 'United States'; +---------------+--------------+ | Name | HeadOfState | +---------------+--------------+ | United States | Donald Trump | +---------------+--------------+ 1 row in set (0,02 sec)
We have successfully updated the row.
mysql> CREATE TABLE toptencities engine=MEMORY SELECT * FROM city LIMIT 10;
We create a temporary table in the memory. It will contain first ten cities
from the city
table.
mysql> SELECT * FROM toptencities; +----+----------------+-------------+---------------+------------+ | ID | Name | CountryCode | District | Population | +----+----------------+-------------+---------------+------------+ | 1 | Kabul | AFG | Kabol | 1780000 | | 2 | Qandahar | AFG | Qandahar | 237500 | | 3 | Herat | AFG | Herat | 186800 | | 4 | Mazar-e-Sharif | AFG | Balkh | 127800 | | 5 | Amsterdam | NLD | Noord-Holland | 731200 | | 6 | Rotterdam | NLD | Zuid-Holland | 593321 | | 7 | Haag | NLD | Zuid-Holland | 440900 | | 8 | Utrecht | NLD | Utrecht | 234323 | | 9 | Eindhoven | NLD | Noord-Brabant | 201843 | | 10 | Tilburg | NLD | Noord-Brabant | 193238 | +----+----------------+-------------+---------------+------------+ 10 rows in set (0,00 sec)
This is the contents of the toptencities
table.
mysql> DELETE FROM toptencities WHERE ID IN (2, 4, 6, 8, 10);
With the DELETE FROM
statement and the WHERE
clause we delete every second row from the toptencities
table.
mysql> SELECT * FROM toptencities; +----+-----------+-------------+---------------+------------+ | ID | Name | CountryCode | District | Population | +----+-----------+-------------+---------------+------------+ | 1 | Kabul | AFG | Kabol | 1780000 | | 3 | Herat | AFG | Herat | 186800 | | 5 | Amsterdam | NLD | Noord-Holland | 731200 | | 7 | Haag | NLD | Zuid-Holland | 440900 | | 9 | Eindhoven | NLD | Noord-Brabant | 201843 | +----+-----------+-------------+---------------+------------+ 5 rows in set (0.00 sec)
We have five rows left in the table.
mysql> TRUNCATE TABLE toptencities; Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM toptencities; Empty set (0,00 sec)
We delete all rows from the table with the TRUNCATE
statement.
There is no data left.
mysql> INSERT INTO toptencities VALUES(1, 'Kabul', 'AFG', 'Kabol', 1780000); mysql> SELECT * FROM toptencities;; +----+-------+-------------+----------+------------+ | ID | Name | CountryCode | District | Population | +----+-------+-------------+----------+------------+ | 1 | Kabul | AFG | Kabol | 1780000 | +----+-------+-------------+----------+------------+ 1 row in set (0.00 sec)
With the INSERT INTO
statement, we insert one row into the table.
mysql> DROP TABLE toptencities; Query OK, 0 rows affected (0,06 sec)
We drop the table from the database.
In this chapter, we have quickly introduced some basics of the MySQL database. We go into more details in the following chapters.