Mysql 3rd Edition
Mysql 3rd Edition
Mysql 3rd Edition
.
-
-
.,.. --·
-- . ...
-
Joel Murach
TRAINING & REFERENCE
3RD EDITION
Joel Murach
10 9 8 7 6 5 4 3 2 1
ISBN: 978-1-943872-36-7
Content
• ••
Introduction Xlll
Appendixes
Appendix A How to install the software for this book on Windows 593
Appendix B How to install the software for this book on macOS 601
••
Expanded contents VI I
Expanded contents
Section 1 An introduction to MySQL
=============
Chapter 1 An introduction to relational databases
An introduction to client/server systems ......................................... 4
The hardware con1ponents of a client/server system ...................................................... 4
The softwa re components of a client/server syste111 ....................................................... 6
Other client/server architectures ............................................... ..................................... 8
An introduction to the relational database model ......................... 10
How a table is organ ized .......... ...................... ............................................................... 10
How tables are related .............................. ...................................... ............................... 12
How columns are defined ...................................................................................... ....... 14
How to read a database diagram ............................................................ ....................... 16
An introduction to SQL and SQL-based systems ......................... 18
A brief history of SQL ................................................ .................................................. 18
A comparison of Oracle, DB2, M icrosoft SQL Server, and MySQL ........................... 20
The SQL statements ......................................................................... 22
An introduction to the SQL statements ...................... .......... ........................................ 22
How to work with database objects .............................................................................. 24
How to query a sin.gle table ........................................................................................... 26
How to join data from two or more tables .................................................................... 28
How to add, update, and delete data in a table ........ ..................................................... 30
SQL coding guidelines ............................................... .................................................. 32
How to use SQL from an application program .............................. 34
Com mon options for accessing MySQL data ... ..................................... .......... ............. 34
PHP code that retrieves data from MySQL .................................................................. 36
Java code that retrieves data from MySQL ...................................................... ............. 38
need to do that. Or, you can learn how to work with other database features
like transactions or stored procedures if you need to do that.
• Unlike most MySQL books, this one shows you how to use MySQL
Workbench to enter and run your SQL statements. MySQL Workbench is a
graphical tool that's an intuitive and user-friendly alternative to the MySQL
Command Line Client, a command-line program that has been around sin,c e
the beginning of MySQL. In 011r experience, using MySQL Workbench
instead of the command line helps you learn more quickly.
• Like all of our books, this one includes hundreds of examples that range
from the simple to the complex. That way, you can quickly get the idea of
how a feature works from the simple examples, but you'll also see how the
feature is used in the real world from the complex examples.
• Like all of our books, this one has exercises at the end of each chapter that
give you hands-on experience by letting you practice what you've learned.
These exercises also encourage you to experiment and to apply what you've
learned in new ways.
• If you page through this book, you'll see that all of the info1·mation is
presented in ''paired pages," with the essential syntax, examples, and
guidelines on the right page and the perspective and extra explanation on
the left page. This helps you learn more with less reading, and it is the ideal
reference format when you need to refresh your memory about how to do
something.
JoelMurach,Author
[email protected]
An introduction to MySQL
Before you begin to learn how to write SQL statements that work with
MySQL, you need to understand some concepts and terms related to SQL
and relational databases. That's what you'll learn in chapter 1. In addition,
you'll need to learn about some of the tools you can use to work with a
MySQL database. That's what you'll learn in chapter 2.
After that, you'll be ready to learn about the most important SQL
statements. In chapter 3, you'll learn how to use the SELECT statement
to retrieve data from a single table. In chapter 4, you'll learn how to use
the SELECT statement to retrieve data from two or more tables. And in
chapter 5, you'll learn how to use the INSERT, UPDATE, and DELETE
statements to add, update, and delete rows. At that point, you'll have all of
the background and skills that you need to work with the rest of this book.
An introduction
to relational databases
This chapter presents the concepts and term.~ that you should understand
before }rou begin learning how to \Vork \Vith a SQL database such as 1'1ySQL.
Although thi chapter doesn't present the coding details. it doe pre. ent an
o~·en·ie"'' of the most importa.11t type ot· SQL staten1ents that are presented in
this book.
An introduction
to client/server syste111s
In case you aren't familiar with client/server systems, the topics that follow
introduce you to their essential hardware and software components. When
you use SQL to access a MySQL database, that system is often a client/server
system.
Database Server
Network
Client Client
Client
SQL queries
Results
I
Server software
• To store and manage the databases of the client/server system, each server requires
a database management systeni (DBMS) like MySQL.
• The processing that's done by the DBMS is typically referred to as back-end
processing, and the database server is referred to as the back end.
Client software
• The application software does the work that the user wants to do. This type of
software can be purchased or developed.
• The data access API (application programming interface) provides the interface
between the application program and the DBMS. For example, for Java applica-
tions, the most common data access API for MySQL is JDBC (Java Database
Connectivity).
• The processing that's done by the client software is typically referred to as
front-end processing, and the client is typically referred to as the front end.
Description
• In addition to a database server and clients, a client/server system can include
additional servers, such as application servers and web servers.
• Application servers are typically used to store business comporients that do part
of the processing of the application. In particular, these components are used to
process database requests from the user interface running on the client.
• Web servers are typically used to store web applications and web services. Web
applications are applications that are designed to run on a web server. Web services
are like business components, except that, like web applications, they are designed
to run on a web server.
• In a web-based system, a web browser running on a client sends a request to a web
server over the Internet. Then, the web server processes the request and passes any
requests for data on to the database server.
• More complex system architectures can include two or more application servers,
web servers, and database servers.
An introduction
to the relational database model
In 1970, Dr. E. F. Codd developed a model for a new type of database called
a relational database. Thjs type of database eliminated some of the problems
that were associated with standard files and other database designs. By using the
relational model, you can reduce data redundancy, which saves disk storage and
leads to efficient data retrieval. You can also view and manipulate data in a way
that is both intuitive and efficient. Today, relational databases are the de facto
standard for database applications.
9
10
Pacific Gas & Electric
Robbins Mobile Lode And Key
Box 52001
'1669N Fresno
"®''
IM!I
San Franciscc
Fresno
11 Bill Marvin aectric Inc 4583EHome IU9!1 Fresno
12 Oty OfFresno PO Box 2069 m!t!I Fresno 'V
< >
Concepts
• A relational database consists of tables. Tables consist of rows and columns, which
can also be referred to as records and fields.
• A table is typically modeled after a real-world entity, such as an invoice or a
vendor.
• A colu1nn represents some attribute of the entity, such as the amount of an invoice
or a vendor's address.
• A row contains a set of values for a single instance of the entity, such as one invoice
or one vendor.
• The intersection of a row and a column is so1netimes called a cell. A cell stores a
single value.
• Most tables have a primary key that unjquely identifies each row in the table. The
primary key is usually a single column, but it can also consist of two or more
columns. If a primary key uses two or more columns, it's called a composite
priniary key.
• In addition to primary keys, some database management systems let you define one
or more non-primary keys. In MySQL, these keys are called unique keys. Like a
primary key, a non-primary key uniquely identifies each row in tl1e table.
• A table can also be defined with one or more indexes. An index provides an
efficient way to access data from a table based on the values in specific columns.
An index is automatically created for a table's primary and non-primary keys.
The relationship between the Vendors and Invoices tables in the database
Primary key
60
. 123
122
4-314-3057
989319~7
2018-06-11
20 18-06- 12
13.75
2312.20
13.75
2312.20 0.00
3
3
--
I~: .
•
115
123
2494'6731
963253269
2018-06-15
2018-06-15
25.67
26.75
25.67
26.75
0.00
o.oo
4
3
63 122 989319-427 2018-06-16 2115.81 2115.81 0.00 3
. .
I- , . 123 963253267 2018--06- 17 23.50 23.50 0.00 3 V
< >
Foreign key
Concepts
• The vendor_id column in the Invoices table is called aforeign key because it
identifies a related row in the Vendors table. A table may contain one or more
foreign keys.
• When you define a foreign key for a table in MySQL, you can have that foreign key
enforce referential integrity. Then, MySQL makes sure that any changes to the data
in the database don' t create invalid relationships between tables.
• The most common type of relationship is a one-to-many relationship as illustrated
by the Vendors and Invoices tables. A table can also have a one-to-one relationship
or a many-to-many relation,ship with another table.
O,arset/CoDation: Default:
Description
• The data type that's assigned to a column determines the type of information that
can be stored in the column.
• Each column definition also indicates whether or not it can contain null values. A
null value indicates that the value of the column is unknown.
• A column can also be defined with a defa ult value. Then, that value is used if
another value isn't provided when a row is added to the table.
• A column can also be defined as an auto increment column. An auto increment
column is a numeric column whose value is generated automatically when a row is
added to the table.
Description
• An entity-relationship (ER) diagram or enhanced entity- relationship (EER)
diagram can be used to show how the tables in a database are defmed and related.
An introduction to SQL
and SQL-based systems
In the topics that follow, you '11 learn how SQL and SQL-based database
management systems evolved. In addition, you'll lea111 how some of the most
popular SQL-based systems compare.
Description
• Although SQL is a standard langt1age, each vendor has its own SQL dialect, or
variant, that may include extensions to the standards.
Description
• Oracle is typically used for large, mission-critical systems that run on one or more
Unix servers.
• DB2 is typically used for large, mission-critical systems that run on legacy IBM
mainframe systems using the z/OS or OS/390 operating system.
• Microsoft (MS) SQL Server is typically used for small- to medium-sized systems
that run on one or more Windows servers.
• MySQL is a popular open-source database that runs on all major operating systems
and is commonly used for web applications.
Description
• The SQL statements can be divided into two categories: the data manipulation
language (DML) that lets you work with the data in the database and the data
definition language (DDL) that lets you work with the objects in the database.
• MySQL programmers typically work with the DML statements, while database
administrato1·s (DBAs) use the DDL statements.
A SELECT statement that retrieves and sorts selected columns and rows
from the Invoices table
SELECT invoic e _ number, invoice_ date, invo ice_ total,
payment_ total, credit_ total,
invoice_ total - payment_ total - credit_ total AS balance_ due
FROM invoices
WHERE invoice_ total - payment_ total - credit_ total > 0
ORDER BY invoice_ date
Concepts
• You use the SELECT statement to retrieve selected columns and rows from a base
table. The result of a SELECT statement is a result table, or result set, like the one
shown above.
• A result set can include calculated values that are calculated from columns in the
table.
• A SELECT statement is commonly referred to as a quer)'·
A SELECT statement that joins data from the Vendors and Invoices tables
SELECT vendor_ name, invoice_ number, invoic e _ date, invo ice_ total
FROM vendors INNER JOIN invoices
ON vendors.vendor_ id = invoi c es.ve ndor_ id
WHERE invoice_ total >= 500
ORDER BY v endor_ narn~, invoice_ total DESC
Concepts
• A join lets you combine data from two or more tables into a single result set.
• The most common type of join is an inner join. This type of join returns rows from
both tables only if their related columns match.
• An outer join returns rows from one table in the join even if the other table doesn' t
contain a matching row.
A statement that deletes all paid invoices from the Invoices table
DELETE FROM inv oic es
WHERE invoice_ total - payment_ total - credit total= 0
Concepts
• You use the INSERT statement to add rows to a table.
• You use the UPDATE statement to change the values in one or more rows of a table
based on the condition you specify.
• You use the DELETE statement to delete one or more rows from a table based on
the condition you specify.
Warning
• If you 're new to SQL statements, please don't execute the statements above until
you read chapter 5 and understa.nd the effect that these statements can have on the
database.
Coding recommendations
• Capitalize all keywords, and use lowercase for the other code in a SQL statement.
• Separate the words in names with underscores, as in invoice_number.
• Start each clause on a new line.
• Break long clauses into multiple lines and indent continued lines.
• Use comments only for portions of code that are difficult to understand. Then, make
sure that the comments are correct and up-to-date.
Description
• Line breaks, white space, indentation, and capitalization have no effect on the
operation of a statement.
• Comments can be used to document what a statement does or what specific parts of
the code do. They are not executed by the system.
Description
• To work with a MySQL database, an application uses a data access API. For
example, PHP uses the mysqli API or the PDO API, Java uses the JDBC API, and
.NET languages like C# and Visual Basic use the ADO.NET API.
• Most modem programming languages provide an API that you can use to access
MySQL.
• Some programming languages include a piece of software known as a database
driver for the API that it uses to access MySQL. For example, PHP includes a
MySQL driver for both the mysqli and PDQ APis. As a result, you typically don't
need to install a database driver when you use PHP.
• Some programming languages don't provide a database driver to communicate
with a MySQL database. For example, Java doesn 't include a MySQL driver for the
JDBC API. As a result, you typically need to install a database driver such as the
Connector/J driver before you can use Java to access MySQL.
$dsn = 'mysql:host=localhost;dbname=ap•;
$username = 'ap_ tester';
$password= •sesame•;
try {
$db= new PDO($dsn, $username, $password);
} catch (PDOException $e) {
$error_ message = $e->getMessage();
echo $error_ message;
exit();
}
$statement= $db->prepare($query);
$statement->execute();
$rows= $statement->fetchAll();
?>
<!DOCTYPE html>
<html>
<head>
<title>DB Test</title>
</head>
<body>
<hl>Invoices with totals over 500:</hl>
</body>
</html>
Note
• For this code to run con·ectly with MySQL 8.0 or later, you must be using a
recent version of PHP that includes a PDQ driver that supports MySQL 8.0's
new default authentication plug-in (caching_sha2_password), or you must use
MySQL's older authentication plug-in (mysql_native~password).
'
impor 1 *;
t Java.sq.
'
import java.text.NwnberFormat;
System.out.println(
"Vendor: "+ vendorName + 11 \n 11
+ ":Invoice No: 11 + invoiceNwnber + 11 \n"
+ 0 Total: 11
+ invoiceTotalString + "\n");
}
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}
}
Description
• Before you can use Java to work with MySQL, you must install a database driver.
To do that, you can download the JAR file for the driver and add it to the libraries
that are available to your Java application.
• To execute a SQL statement from a Java application, you can use JDBC objects
such as the Connection, PreparedStatement, and ResultSet objects.
Perspective
To help you understand how SQL is used from an application program,
this chapter has introduced you to the hardware and software components
of a client/server system. It has also described how relational databases are
organized and how you use some of the SQL statements to work with the data
in a relational database. With that as background, you're now ready to start
using MySQL. In the next chapter, then, you'll leain how to use some of the
tools for working with a MySQL database.
Terms
client table open-source database
server row data manipulation
database server column language (DML)
network record data definition
client/server system field language (DDL)
local area network cell database administrator
(LAN) value (DBA)
enterprise system primary key constraint
wide area network composite primary key base table
(WAN) non-primary key result set
database management unique key calculated value
• •
system (DBMS) index ]Oln
• • •
back end foreign key mner JOin
application software one-to-many outer join
API (application relationship comment
•
progralilllling one-to-one relationship block comment
interface) many-to-many single-line comment
data access API rel ati onship database driver
JDBC (Java Database referential integrity mysqli
Connectivity) data type PDO
front end null value ADO.NET
SQL (Structured Query default value
Language) at1to increment column
query entity-relationship
query results (ER) diagram
application server enhanced entity-
web server relationship (EER)
business component diagram
web application relational database
web service management
web browser system (RDBMS)
thin client SQL dialect
relational database SQL extension
How to use
MySQL Workbench
and other development tools
In the last chapter, you learned about some of the SQL statements that you can
use to work with the data in a relational database. Before you learn the details
of coding these statements, however, you need to learn how to use MySQL
Workbench to enter and execute SQL statements. In addition, you should learn
how to use the MySQL Reference manual, and you should at least be familiar
with the MySQL Command Line Client.
Browse Docun,entation > Read the Blog > Discuss on the Forums >
Description
• The Home page of MySQL Workbench is divided into three tabs displayed at the
left side of the window: Welcome, Models, and Migration.
• You can use the MySQL Connections section of the Welcome tab to start and stop
the database server and to code and run SQL statements.
• You can use the links on the Welcome tab to view the documentation for using
MySQL Workbench, view the MySQL Workbench blog, and view and join in the
MySQL Workbench forum.
• You can use the Models tab to create and work with EER models.
• You can use the Migration tab to migrate other databases to MySQL and to copy a
database from one instance of MySQL to another.
• You can return to the Home page by clicking the tab with the house icon. This tab
is always displayed in the top left corner of the Workbench window.
Note
• In so1ne cases, you'll get an ''Unsupported Operating System'' 1nessage when you
start MySQL Workbench. This happens, for example, when you start MySQL
Workbench 8.0 on Wmdows 7. If you click the OK button when this message is
displayed, MySQL Workbench should work fine. This is a known bug that should
be fixed in a future release of Workbench.
Password:
Description
• To connect as the root user to an instance of MySQL that's running on the local
host computer, click the stored connection named ''Local instance MySQL80'', and
enter the password for the root user if prompted.
• To save the password for a connection so you don ' t have to enter it every time,
check the ''Save password in vault'' option when you 're prompted fo1· your
password.
• To clear the password from the vault so you are prompted for your password,
right-click the connection, select the Edit Connection item, click the Clear button
for the password, and click the Close button.
• To edit the connection parameters for a connection, right-click the connection,
select the Edit Connection item, enter the connection parameters, and click the
Close button. This lets you specify the usemame, the host address, the port number,
and other connection parameters.
• To add a new connection to the Welcome tab of the Home page, click the (±) icon
to the right of MySQL Connections, enter the connection pararneters, and click the
OK button. Then, the connection appears in the list of connections.
- (........-
MANAGEMtNT
Local nstancr MySQU!O
0 Server Status
Startup / Shutdown MySQL Server
.J. Client Connections
.J. Users and PrMleoes The database~ Is sUJlll)ed, To start the Server, use the 'Start Server•button
e Status and System Va riables The database server rnstance rs ~= Slart Server
.!i Data Ellport If you stop the server, neither you nor your appkallons can use the d"t:abase and al a.rent aimections wl be do5ed •
.!, Data Import/Restore
INSTANCE '-"!I 2018· 11-01 11:36:,;a · WoridJench 'I'll use and slid commands to start/stop thrs rns1ance
0 St artup / Shutdown 2018·11-01 U:36:48 ·Sever rsn.rnio
A Server log.s
FROM /IJ'4t-E.·21ll5-K.err:
/ ' Options File 2018·U-01T18:37:'\2 o Sysll!m) (MY-013105} [Server C:'frcvarn Fles\'-1ySQt.'f-1ySQl Server 8.0~',nysqld.exe: Normal srotdom.
2018-11-01T18:37:44 o Wal'nl'lgj (MY-O 10909) [Server C: 'f'r.ogram Aes'f,lySQL'f,1ySQt Server 8, 0'bwlynysqld.exe: Faong dooe of
PERFORMANCE t!Tead 27 user: 'root',
201S · l1-0IT18:37: '14 O WarnlnO] (MY-010909} [Server C:'f'raoram Fles't1ySQL'M}'SQl Server 8.0lp,n'mysqld.exe: l'«dnlJ close of
C Dashboard t!Yead 28 user: 'root'.
8'J Performance Reports 2018·11-01 U :37:50 -Server stop done.
Connertlon ~opened.
Description
• After you install MySQL, the database server usually starts automatically each
ti1ne you start your computer.
• The database server can also be referred to as the database service or the database
•
engine.
• If you aren't able to use Workbench to start and stop the database server, you may
need to edit your connection so it points to the correct instance of MySQL. To do
that, right-click the connection on the Welco1ne tab of the Home page, select the
Edit Connection item, click the System Profile tab, and edit the service name. For
MySQL 8.0 on Windows, the service name is typically ''MySQL80''.
SOifM
~AS
6
_ _ _ _ _~ .. o e 1, ti n 1~ 1 ~ J Lrito 1000rov.'S • I '4i, I '<I Q.
I
q, F~ter objects 1
"' U ap
• Tables
► Ill
oeneralJedger_a,counts
► El lnvoice_archlve
► El
,nvoiceJ,ne_ltems
► ■ Invoices
► m
tenns
► Ii
vendor_conracts
► II
vendor.:
Vi~'S
~ Stored Procedures
'al Functions
► el(
► om
► sys
Description
• Each database (or sche,na) provides access to the database objects that are
available. These database objects include tables, views, stored procedures, and
functions.
• On some systems, the Navigator window provides Administration and Schemas
tabs that you can use to display the Administration and Schemas categories. On
other systems, the Navigator window displays the Administration category above
the Schemas category.
• To display the databases for the current connection, you can use the Navigator
window to view the Schemas category.
• To navigate through the database objects for a database, click the arrows to the left
of each of the nodes in the Navigator window to expand or collapse the node.
• To work with a node or an object, right-click the node or object and select a
command from the resulting menu.
The data for the Invoices table displayed in the Result grid
Result grid
II MysQL Workbench □ X
fl. Local instance MySQL80 x
File Edit View Query Database Server Tools Scnp!Jng Help
~~~ta
Object ls>fo Session
=~t~
Description
• To view the data for a table, right-click the table in the Navigator window and
select the Select Rows - Limit 1000 comn1and to display it in a Result grid.
• To edit the data for a table, view the data. Then, you can use the buttons at the top
of the Result grid to insert, update, and delete rows.
• To apply the changes to the table, click the Apply button at the bottom of the tab.
To cancel the changes, click the Revert button.
Figure 2-5 How to view and edit the data for a table
52 Section 1 Arz introduction to MySQL
Que,y1
SCHEMAS
I
q, RI~ ob)ects
Table Name: lvendc.-s J Sdtema: ap
T .J ap
Owset/Colation: utfBni>'l - v j utf8mb'1_0900_ v Engine: lmo06 V
T'cl Tables
►
►
►
general_ledger_accounts
fnvo1ce_archlve
mvoice_lme_iteJT'6
Comments:
..
► Invokes CoumName Datatype PK l'-N UQ B ~ lF Al G Oefault,bilresslon
► te_rms vendor_id INT(U) 0 0 D D D D E2l D
► II vendor_contacts vendor_name VARCHAA(SO} D E2l E2I D D D D D
T vendors J vendor_addressl VAACHAA(SO) D D D D D D D D NULL
► [;:) Columns
►
; vie_ndor_address2 VARCHAA(SO)
□ D □ D D □ D D NULL
□ E2I □ □ □ □ D D
Ind!!RS vendor_dty VAACHAA(SO}
► ~ Fore:ion Keys
► Triggers
vendor_sta2 CHAR{2)
□ E2I □ □ D □ D □
Views
vendor_zip_codt VARCHAA(20)
□ 0 □ D D □ D □
storNI Procedures
vendor_phone VARCHAA(SO)
□ D D D D □ □ D NULL
'i!5J Functions
vendor_contact_last_name VARCHAR(SO) D D □ □ D □ D D NULL
►
vie_ndor_contact_firsLname VARCHAA(SO}
□ D D □ D □ D D NULL
►
ex ~ ddault_terms_id !Nl{l 1) □ E2I □ □ D □ D D
□ E2I □ D D □ D D
om ~ ddauft_account_number !Nl{U) V
Description
• To view the column definitions for a table, right-click the table name in the
Navigator window and select the Alter Table command. Then, select the Columns
tab at the bottom of the window that's displayed to view the column definitions for
the table.
• To edit the column definitions for a table, view the column definitions. Then, you
can t1se the resulting window to add new columns and modify and delete existing
columns.
• For more information about creating and modifying tables, see chapter 11.
11 M orkbench D X
6 / wcat tns:tance MySQL.80 X
File 1 -1 V!e'N Query Database Saver Toals Sc · · no Help
Query 1 X
Description
• To open a new SQL tab, press Ctrl+T or click the Create New SQL Tab button ( )
in the SQL Editor toolbar.
• To select the current database, double-click it in the Schemas tab of the Navigator
window. This displays the selected database in bold.
• To enter a SQL statement, type it into the SQL editor.
• As you enter the text for a statement, the SQL editor applies color to various
elements, such as SQL keywords, to make them easy to identify.
• To execute a SQL statement, press Ctrl+Enter or click the Execute Current
Statement button ({if ) in the SQL Editor toolbar. If the statement retrieves data, the
data is displayed in a Result grid below the SQL tab.
SQl ~dd1i:Jons
Description
• The SQL Additions window contains context help and snippets. Snippets contain
the syntax for many common SQL statements. You can use the snippets to guide
you as you create a SQL statement. You can also create your own snippets and save
them for later use.
• The SQL Additions window is displayed to the right of the SQL Editor tab by
default. If this window isn't displayed, you can display it by clicking the rightmost
button ( □ ) at the right side of the SQL Editor toolbar. Then, you can click the
Snippets tab to display the available snippets.
• The snippets are organized into categories. To display any category of snippets,
select the category from the drop-down list at the top of the Snippets tab.
• To enter a snippet into a SQL editor, select the snippet and then click the Insert
Snippet button ( ~ at the top of the Snippets tab. Then, edit the snippet code so it's
appropriate for your SQL statement.
• To replace code in the SQL editor with a snippet, select the code, select the snippet
you want to replace it with, and then click the Replace Current Text button ( ~ ).
• To create your own snippet, enter the code for the snippet into a SQL editor tab.
Then, select the category where you want to save the snippet, click the Save
Snippet button ( 1-¢) in the SQL Editor toolbar, and enter a name for the snippet.
• To delete a snippet, right-click it in the Snippets tab and select the Delete Snippet
item.
iil'Hi1__________________________
SCKEMAS c;i Q I~ lll' fl I~ I Q I Lmit to 1000rows • I
q_ [niter obJeds 1 • SE~ECT vendor_name, vendor_city, vendor_shrte
y § ap 2 FR0'1 vendor
3 ORDER BV vendor_nam~
T Tables
► II Qeneral_ledger_accounts
► II lnvolce_archlve
► II lnvolce:_line:_ltems
► Invoices
► II terms
► 8 ve:ndor_contacls
► vendors
Views
'rJl Stored Procedures
i;ai Funcbons
► ex
► om
► sys
vendor id ll'lt,U) O 1 12.19:45 SELECT vendor_name. vendor_cty. vend«_slal... &rorCode: 1146 Table 'ap.vendor'doesn\ eiosl 0.000 sec
AJPK
vendor_name varcha
vendor llddress l v11rd'la
vendor- address2 varcha
vendof=dty ~archa
vendor_state char(! ..,
ObJe:ct Info Session
Description
• If an error occurs during the execution of a SQL statement, MySQL Workbench
displays a message in the Output tab that includes an error code and a brief descrip-
tion of the error.
• Most errors are caused by incorrect syntax and can be corrected without any
additional assistance. Otherwise, you can usually get more information about
an error by searching for the error code or description in the MySQL Reference
Manual or on the Internet.
D X
._....., ms_tance MySQL.80 X
Description
• A SQL script is a ftle that contains one or more SQL statements.
• To open a file that contains a SQL script, click the Open SQL Script File button in
the SQL Editor toolbar or press the Ctrl+Shift+O keys. Then, use the Open SQL
Script dialog box to locate and open the SQL script.
• When you open a SQL script, MySQL Workbench displays it in its own SQL
Editor tab. To switch between open scripts, select the appropriate tab.
• To cut, copy, and paste code from one SQL script to another, use the standard
techniques.
• To save a SQL statement to a script file, click the Save btttton in the SQL Editor
toolbar or press Ctrl+S. Then, use the Save SQL Script dialog box to specify a
location and name for the file.
• To save a script you've modified to a new file, press the Ctrl+Shift+S keys or select
the File ➔ Save Script As command.
■ MySQL Workbench D X
6 local ins!ance MySQLBO x
File Edit 1/,e,, Que,y Databffe Server Tools
NaV19atOC"
SCHEMAS ~ I ~to 1000rows • I~ I 0.. Llli L!!J
q_ IAl:rr ~1$ 1 • SELECT vendor_name, vendor_city
2 FR<Y-1 vendors
T J ap
3 l,lfERE vendor_id: ;
T Tables
4
► II gcneral_ledger_accounts 5 • SELECT COUttT (*) AS number_of_invoices,
► 6J lnvoice_archlve 6 SUM(invoice_total - payment _total - credit_total) AS total_due
► invoiu_line_items 7 FRCJ1 invoices
► Invoice 8 i..HERE vendor id= ;
► II terms
► El vendor_contacts < >
► C vcndo3 I Result Grid ~I---~' f>ll>o<t: Eg Iw~ eel c.ontent:
JJ t'\ F.l.r Row11 IA □
- Vitv,'S
1211 Stored Procedures I vendor_~ vendcr_oty
'al fundions ► IBM Sanfraooscx>
► e,,.
► om
► sys
Description
• When you code a script that contains more than one statement, you must code a
semicolon at the end of each statement.
• To run an entire SQL script, press the Ctrl+Shift+Enter keys or click the Execute
SQL Script button ( 'I ) that's located just to the left of the Execute Current
Statement button in the SQL Editor toolbar.
• When you run a SQL script, the results of each statement that returns data are
displayed in a separate Result grid. To switch between these Result grids, you can
click on the tabs that are displayed below the current Result grid.
• To execute one SQL statement within a script, move the insertion point into that
statement and press the Ctrl+Enter keys or click the Execute Current Statement
button ( fi ). If the statement retrieves data, the data is displayed in a Result grid.
• To execute two or more statements within a script, select them in the editor and
then press the Ctrl+Shift+Enter keys or click the Execute SQL Script button.
The v10rld s most popula Of)"'JI source database 0. Contact MySQL I Login I Register
Q.
1.1 About This Manual
A Documentation Home
This 1s the Reference Manual for the MySQL Database System, version 8.0,
MySQL 8.0 Reference Manual through release 8.0.15. Differences between minor versions of MySQL 8.0 are
noted In the present text with reference to release numbers (8.0. x). For license
Preface and Legal Notices
1nformatlon, see the Legal Notices .
., General Information
About This Manual This manual Is not intended for use with older versions of the MySQL software
Typographical and Syntax Convenoons due to the many functional and other differences between MY5QL 8.0 and
> overview of the MY5QL Database previous versions. If you are using an earlier release of the MySQL software,
Management System
please refer to the appropnate manual. For example, MY5QL 5. 7 Reference
• What Is New In MySQL 8.0
Monuol covers the S.7 senes of MySQL software releases .
• Server and Status vanables and
opoons Added, Deprecated, or
Rem011ed jr) MY5QL 8.0 Because this manual serves as a reference, It does not provide general
Description
• To view the MySQL Reference Manual, go to the MySQL website and select the
correct version of the manual. The web address for MySQL 8.0 is shown above.
• To view a chapter, click the link for the chapter in the table of contents on the right
side of the page.
• To return to the Home page for the manual, click the Start icon ( for the manual
that's displayed at the top of the left sidebar.
• To search for a particular word or plu·ase, type the word or phrase in the ''Search
this Manual'' text box in the left sidebar and click the Search icon or press the
Enter key. Then, you can scroll through the results and click links to get more
information.
• You can also download the MySQL Reference Manual. However, it typically makes
sense to use it online.
How to start the MySQL Command Line Client from the command line
For Windows
c d \ Program Files \ MySQL\ MySQL Server 8.0 \ bin
mysql -u r o ot -p
For macOS
c d / usr/ local / mysql / bin
. / mysql -u root -p
Examples
mysql - u ap_ tester -p
mysql -h localhost -u root -p
mysql -h murach. com -u ap_ tester -p
Description
• MySQL provides a command-line client program called the MySQL Command
Line Client that lets you enter SQL statements that work with MySQL databases.
This program is also known as the MySQL command line.
• For Windows, use a Command Prompt window to start the MySQL Command Line Client.
• For macOS, use a Terminal window to start the MySQL Command Line Client.
• To stop the MySQL Command Line Client, enter ''exit'' or ''quit'' at the cominand
line, followed by a semicolon.
• MySQL 8.0 also includes a Unicode version of the command-line client program. For more
information on this program, you can refer to section 4.5.1.6.2 of the reference manual.
Figure 2-1 3 How to start and stop the MySQL Command Line Client
68 Section 1 Arz introduction to MySQL
Description
• You can use the MySQL Command Line Client to work with any of the databases
running on the database server. To do that, you can use any SQL statement that
works with a MySQL database.
• To execute a SQL statement, type the statement on the command line, followed by
a semicolon. Then, press the Enter key.
• To show a list of all available databases, you can use the SHOW DATABASES
statement.
• To select the database that you want to work with, you can use the USE statement.
• SQL statements aren't case-sensitive. As a result, when using the MySQL
Command Line Client, most programmers enter their statements in lowercase
letters beca11se they 're easier to type.
Figure 2-14 How to use the MySQL Command Line Cl ient to work with a database
70 Section 1 Arz introduction to MySQL
Perspective
In this chapter, you learned how to use MySQL Workbench to start and
stop a MySQL server and to enter and execute SQL statements. With that
as background, you're ready to go on to the next chapter, where you'll start
learning the details of coding your own SQL state1nents.
Terms
MySQL Workbench
database server
database service
database engine
database object
schema
snippet
SQL script
MySQL Reference manual
MySQL Command Line Client
Exercises
In these exercises, you ' ll use MySQL Workbench to review the tables in the AP
database. In addition, you'll use MySQL Workbench to enter SQL statements
and run them against these tables.
5. Navigate through the database objects and view the column definitions for at
least the Vendors and Invoices tables.
Use MySQL Workbench to enter and run SQL statements
6. Double-click the AP database to select it. When you do that, MySQL
Workbench should display the database in bold.
7. Open a SQL Editor tab. Then, enter and run this SQL statement:
SELECT vendor_ namA FROM vendors
8. Delete thee at the end of vendor_name and run the statement again. Note the
error number and the description of the error.
9. Open another SQL Editor tab. Then, enter and run this statement:
SELECT COUNT(*) AS nwnber_ of_ invoices,
SUM(invoice_ total) AS grand_ invoice_ total
FROM invoices
An introduction
to the SELECT staten,ent
To get you started quickly, this chapter begins by presenting the basic syntax
of the SELECT statement. Then, it presents several examples that should give
you an overview of how this statement works.
Description
• You use the basic SELECT statement shown above to retrieve the columns speci-
fied in the SELECT clause from the base table specified in the FROM clause and
store them in a result set.
• The WHERE clause is used to filter the rows in the base table so that only those
rows that match the search condition are included in the result set. If you omit the
WHERE clause, all of the rows in the base table are included.
• The search condition of a WHERE clause consists of one or more Boolean expres-
sions that result in a true, false, or null value. If the combination of all the expres-
sions is a t1ue value, the row being tested is included in the result set. Otherwise,
it's not.
• If you include the ORDER BY clause, the rows in the result set are sorted in the
specified sequence. Otherwise, the sequence of the rows is not guaranteed by
MySQL.
• If you include the LIMIT clause, the result set that's retrieved is limited to a speci-
fied number of 1·ows. If you omit this clause, all rows that match are returned.
• You 1nust code the clauses in the 01·der shown or you'll get a syntax error.
Note
• The syntax shown above does not include all of the clauses of the SELECT state-
ment. You '11 learn about the other clauses later in this book.
A SELECT statement that retrieves all the data from the Invoices table
SELECT* FROM invoices
It,.
invoice_id vendor_id invoice_number invoice_date invoice_total payment_total credit_total termsjd
~ 1 122 989319-457 2018-04-08 3813.33 3813.33 0.00 3
2 123 263253241 2018-04-10 40. 20 40. 20 0.00 3
3 123 963253234 2018-04-13 138.75 1.38. 75 0.00 3 \I
< >
(114 rows)
( 114 rows )
(37 rows )
'
Description
• Use SELECT * only when you need to retrieve all of the columns from a table.
Otherwise, list the names of the columns you need.
• An expression is a combination of column names and operators that evaluate to a
single value. In the SELECT clause, you can code expressions that include one or
more arithmetic operators and expressions that include one or more functions.
• After each column specification, you can code an AS clause to specify the name for
the column in the result set. See figure 3-4 for details.
Note
• The ALL and DISTINCT keywords specify whether or not duplicate rows are
rettn·ned. See figlll·e 3-9 for details.
(114 rows)
(114 rows)
Description
• By default, a column in the result set is given the same name as the column in
the base table. If that's not what you want, you can specify a substitute name, or
column alias, for the column.
• To specify an alias for a column, use the AS phrase. Although the AS keyword is
optional, I recommend you code it for readability.
• If you don't specify an alias for a column that's based on a calculated value,
MySQL uses the expression for the calculated value as the column name.
• To include spaces or special characters in an alias, enclose the alias in double
quotes ( " ) or single quotes ( ' ).
Figure 3-4 How to name the columns in a result set using aliases
82 Section 1 Arz introduction to MySQL
► 1 22 24 .
2 23 27
3 24 30
► 1 0.3333 0 1 '--
2 0.6667 0 2
I
3 1.0000 l 0
Description
• Unless parentheses are used, the operations in an expression take place from left to right
in the order of precedence. For arithmetic expressions, MySQL performs multiplication,
division, and modulo operations first. Then, it performs addition and subtraction operations.
• When necessary, you can use parentheses to override or clarify the sequence of operations.
(122 rows)
(122 rows}
(122 rows)
Description
• An expression can include any of the functions that are supported by MySQL. A
function performs an operation and returns a value.
• To code a function, code the function name followed by a set of parentheses. Within
the parentheses, code any parameters, or arguments, required by the function. If a
function requires two or more arguments, separate them with commas.
• To code a literal value for a string, enclose one or more characters within single
quotes ( ' ) or double quotes ( " ).
• To include a single quote within a literal value for a string, code two single quotes.
Or, use double quotes instead of single quotes to start and end the literal value.
• To join, or concatenate, two or more string columns or literal values, use the
CONCAT function.
( 122 rows )
( 114 rows)
( 114 rows )
Description
• When using the DATE_FORMAT function to specify the format of a date, you use
the percent sign (%) to identify a format code. For example, a format code of m
returns the month number with a leading zero if necessary. For more information
about these codes, see chapter 9.
• For more information about using functions, see chapter 9.
Figure 3-7 How to use functions with strings, dates, and numbers
88 Section 1 Arz introduction to MySQL
Description
• With MySQL, you don't have to code a FROM clause. This makes it easy to test
expressions that include arithmetic operators and functions.
• The CURRENT_DATE function returns the current date. The parentheses are
optional for this function .
(122 rows)
(53 rows )
Description
• The DISTINCT keyword prevents duplicate (identical) rows from being included in
the result set. DISTINCTROW is a synonym for DISTINCT.
• The ALL keyword causes all rows matching the search condition to be included in
the result set, regardless of whether rows are duplicated. Since this is the defat1lt,
you'll usually omit the ALL keyword.
• To use the DISTINCT or ALL keyword, code it immediately after the SELECT
keyword as shown above.
Description
• You can use a comparison operator to compare any two expressions. Since MySQL
automatically converts the data for comparison, the expressions may be of unlike
data types. However, the comparison may sometimes produce unexpected results.
• If the result of a compaiison is a true value, the row being tested is included in the
result set. If it's a false or null value, the row isn't included.
• To use a string literal or a date literal in a comparison, enclose it in quotes. To use a
numeric literal, enter the number without quotes.
• Character comparisons perforrr1ed on MySQL databases are not case-sensitive. So,
for example, 'CA' and ' ca' are considered equivalent.
• If you compare a null value using one of these comparison operators, the result is
always a null value. To test for null values, use the IS NULL clause presented in
figure 3-15.
Figure 3-1 O How to use the comparison operators
94 Section 1 Arz introduction to MySQL
The OR operator
WHERE vendor_ state = 'NJ' OR vendor_ city = 'Pittsburg'
{ 33 rows )
{11 rows )
Description
• You can use the AND and OR logical operators to create compound conditions that
consist of two or more conditions. You use the AND operator to specify that the
search must satisfy both of the conditions, and you use the OR operator to specify
that the search must satisfy at least one of the conditions.
• You can use the NOT operator to negate a condition. Because this can make the
search condition unclear, you should rephrase the condition if possible so it doesn' t
use NOT.
• When M ySQL evaluates a compound condition, it evaluates the operators in this
sequence: ( 1) NOT, (2) AND, and (3) OR. You can use parentheses to override this
order of precedence or to clarify the sequence in which the operations are evaluated.
Figure 3-11 How to use the AND, OR, and NOT logical operators
96 Section 1 An introduction to MySQL
Description
• You can use the IN phrase to test whether an expression is equal to a value in a list
of expressions. Each of the expressions in the list is automatically converted to the
same type of data as the test expression.
• The list of expressions can be coded in any order without affecting the order of the
rows in the result set.
• You can use the NOT operator to test for an expression that's not in the list of
•
expressions.
• You can also compare the test expression to the items in a list returned by a
subquery. You'll learn more about coding subqueries in chapter 7.
Description
• You can use the BETWEEN phrase to test whether an expression falls within a
range of values. The lower limit must be coded as the frrst expression, and the
upper limit must be coded as the second expression. Otherwise, MySQL returns an
empty result set.
• The two expressions used in the BETWEEN phrase for the range of values are
inclusive. That is, the result set includes values that are equal to the upper or lower
limit.
• You can use the NOT operator to test for an expression that's not within the given
range.
LIKE wildcards
Symbol Description
~
0 Matches any string of zero or more characters.
Matches any single character.
Description
• You use the LIKE and REGEXP operators to retrieve rows that match a string pattern,
called a mask. The mask determines which values in the column satisfy the condition .
• The mask for a LIKE phrase can contain special symbols, called wildcards. The mask
for a REGEXP phrase can contain special characters and constructs. Masks aren't
case-sensitive.
• If you use the NOT keyword, only those 1·ows with values that don't match the string
pattern are included in the result set.
• Most LIKE and REGEXP phrases significantly degrade performance compared to
other types of searches, so use the1n only when necessary.
For the sake of brevity, this chapter only presents the most common symbols
that are used in regular expressions. However, MySQL supports most of the
symbols that ru:e standard for creating regular expressions. Fo1· more information
about creating regular expressions, please consult the online MySQL Reference
Manual. If you 're familiar with using regular expressions in other programming
languages such as PHP, you'll fmd that they work similarly in MySQL.
In addition to the REGEXP operator, MySQL 8.0 provides some new
functions that work with regular expressions. You'll learn about these functions
in chapter 9 when you learn about some other functions for working with strings.
- invoice id
- -
invoice total
► 1 125.00
4 2199.99 V
Description
• A null value represents a value that's unknown, unavailable, or not applicable. It
isn't the same as a zero or an empty string(").
----,
► Abbey Office Furnishings Fresno, CA 93722 -
Description
• The ORDER BY clause can include a column alias that's specified in the SELECT
clause if the column alias does not include spaces.
• The ORDER BY clause can include any valid expression. The expression can refer
to any column in the base table, even if it isn't included in the result set.
• The ORDER BY clause can use numbers to specify the columns to use for sorting.
In that case, 1 represents the frrst column in the result set, 2 represents the second
column, and so on.
A SELECT statement with a LIMIT clause that starts with the first row
SELECT vendor_ id, invoice_ total
FROM invoices
ORDER BY invoice_ total DESC
LIMIT 5
vendorjd invoice_total
-
► 110 37966.19
110 26881 .40
110 23517.58
72 21842.00
110 20551. 18
A SELECT statement with a LIMIT clause that starts with the third row
SELECT invoice_ id, vendor_ id, invoice_ total
FROM invoices
ORDER BY invoice_ id
LIMIT 2, 3
- -
invoice id vendor_id invoice
-total
123
► 3 138.75
4 123 144. 70
5 123 15.50
'
A SELECT statement with a LIMIT clause that starts with the 101 st row
SELECT invoice_ id, vendor_ id, invoice_ total
FROM invoices
ORDER BY invoice id
LIMIT 100, 1000
- -id
inv oice vendor_id invoice_total
( 14 rows )
Description
• You can use the LIMIT clause to limit the number of rows returned by the SELECT
statement. This clause takes one or two intege1· arguments.
• If you code a single argument, it specifies the maximum row count, beginning with
the first row. If you code both arguments, the offset specifies the first row to return,
where the offset of the first row is 0.
• If you want to retrieve all of the rows from a certain offset to the end of the result
set, code -1 for the row count.
• Typically, you'll use an ORDER BY clause whenever you use the LIMIT clause.
Perspective
The goal of this chapter has been to teach you the basic skills for coding
SELECT statements. As a result, you'll use these skills in almost every
SELECT statement you code.
As you'll see in the next chapter and in chapters 6 and 7, though, there's
a lot more to coding SELECT statements than what's presented here. In these
chapters, then, you'll learn additional skills for coding SELECT statements.
When you complete these chapters, you' 11 know everything you need to know
about retrieving data from a MySQL database.
Terms
keyword parameter
base table concatenate
search condition comparison operator
filter logical operator
Boolean expression compound condition
•
expression subquery
column alias string patten1
arithmetic expression mask
arithmetic operator wildcard
order of precedence regular expression
literal value null value
string nested sort
function offset
argument
Exercises
Run some of the examples in this chapter
In these exercises, you '11 use MySQL Workbench to run some of the scripts for
the examples in this chapter. This assumes that you already know how to use
MySQL Workbench, as described in chapter 2.
1. Start MySQL Workbench.
2. Open the script named 3-02.sql that you should fmd in this directory:
c:\murach\rnysql\book_scripts\ch03. When it opens, you should see all of the
queries for figure 3-2. Note that each of these queries has a semicolon at the
end of it.
3. Move the insertion point into the first query and press Ctrl+Enter or click on
the Exectite Current Statement button to run the query. This shows you the
data that's in the Invoices table that you'll be working with in this chapter.
4. Move the insertion point into the second query and run it.
Chapter 3 How to retrieve data from a sin.gle table 111
5. Open the script named 3-05.sql in the ch03 directory. Then, run the second
query. When you do, you '11 see that the 1·esult set is in sequence by the
invoice id column.
6. Delete the ORDER BY clause from the SELECT statement and run the query
again. Scroll through the result set to see that the rows are no longer in a
particular sequence. When you 're done, close the script without saving the
changes.
7. Open and run the queries for any of the other examples in this chapter that
you're interested in reviewing.
11 . Write a SELECT statement that returns these columns from the Invoices
table:
invoice- number The invoice- number column
invoice- total The invoice total column
payment_credit_total Sum of the payment_total and credit_total
columns
balance_due The invoice total column minus the
payment_total and credit_total columns
Return only invoices that have a balance due that's greater than $50.
Sort the result set by balance due in descending sequence.
Use the LIMIT clause so the result set contains only the rows with the 5
largest balances.
Work with nulls and test expressions
12. Write a SELECT statement that returns these columns from the Invoices
table:
invoice- number The invoice_number column
invoice- date The invoice date column
balance due The invoice_tota] column minus the payment_total
and credit total columns
payment_date The payment_date column
Return only the rows where the payment_date column contains a null value.
This should retrieve 11 rows.
13. Write a SELECT statement without a FROM clause that uses the
c ·U RRENT DATE function to return the current date in its default format.
Use the DATE FORMAT function to format the current date in this format:
nun-dd-yyyy
This displays the month, day, and four-digit year of the current date.
Give this column an alias of current_date. To do that, you must enclose the
alias in quotes since that name is already used by the CURRENT_DATE
function.
14. Write a SELECT statement without a FROM clause that creates a row with
these columns:
starting_principal Starting principal of $50,000
interest 6.5% of the principal
principal_plus_interest The principal plus the interest
To calculate the third column, add the expressions you used fo1· the first two
columns.
How to retrieve data
from two or more tables
ln the last chapter, you lea111ed how to create result sets that contain data from a
single table. Now, this chapter shows you how to create result sets that contain
data from two or more tables. To do that, you can use an inner join, an outer
• • •
JOin, or a union.
- invoice_number
-
vendor name
"L
Malloy Lithographing Inc
► 0-2058
0-2060 Malloy Lithographing Inc
0-2436 Malloy Lithographing Inc
1-200-5164 Federal Express Corporation
1-202-2978 Federal Express Corporation
10843 Yesmed,Inc
( 114 rows )
Description
• A join combines columns from two or more tables into a result set based on the
join conditions you specify. For an inner join, only those rows that satisfy the join
condition are included in the result set.
• A join condition names a column in each of the two tables involved in the join and
indicates how the two columns should be compared. In most cases, you use the
equal operator to retrieve rows with matching columns. However, you can also use
any of the other comparison operators in a join condition.
• Tables are typically joined on the relationship between the primary key in one table
and a foreign key in the other table. However, you can also join tables based on
relationships not defined in the database. These are called ad hoc r·elationships.
• If the two co]umns in a join condition have the same name, you must qualify them
with the table name so MySQL can distinguish between them. To code a qitalified
column name, type the table name, followed by a period, followed by the column
name.
Note
• The INNER keyword is optional and is seldom used.
(11 rows)
(6 rows )
Description
• A table cilias is an alternative table name assigned in the FROM clause. You can use
an alias, which is typically just a letter or two, to make a SQL statement easier to
code and read.
• If you assign an alias to a table, you must use that alias to refer to the table
throughout your query. You can't use the original table name.
• You ca11 use an alias for one table in a join without using an alias for another table.
(37 rows)
Description
• A MySQL server can store tables in multiple databases. These databases are
sometimes refe1Ted to as schemas.
• When you run a SELECT statement against one database, you can join to a table in
another database if you have appropriate privileges. To do that, you must prefix the
table name in the other database with the name of that database.
< >
(24 rows)
(9 rows)
(1 row)
Description
• A join condition can include two or more conditions connected by AND or OR
operators.
A self-join that returns vendors from cities in common with other vendors
SELECT DISTINCT vl.vendor_ name, vl.vendor_ city,
vl.vendor_ state
FROM vendors vl JOIN vendors v2
ON vl.vendor_ city = v2.vendor_ city AND
vl.vendor_ state = v2.vendor_ state AND
vl.vendor_ name <> v2.vendor_ name
ORDER BY vl.vendor_ state, vl.vendor_ city
__l vendor_name vendor_dty vendor _state
Computer Library
► Phoenix AZ
AT&T Phoenix AZ
Wells Fargo Bank Phoenix AZ
Aztel< Label Anaheim CA
Blue Shield of California Anaheim CA
Abbey Office Fumshings Fresno CA
California Business Machines Fresno CA
1Postmaster Fresno CA
(84 rows)
Description
• A self-join is a join that joins a table with itself.
• When you code a self-join, you must use aliases for the tables, and you must
qualify each column name with the alias.
( 11 rows )
Description
• You can think of a multi-table join as a series of two-table joins proceeding from
left to right.
- -
invoice number vendor_name
(114 rows)
(11 rows)
Description
• Instead of coding a join condition in the FROM clause, you can code it in the
WHERE clause along with any seai·ch conditions. In that case, you list the tables in
the FROM clause separated by commas.
• This syntax for coding joins is referred to as the implicit syntax. It was used prior to
the SQL-92 standards, which introduced the explicit syntax.
(202 rows)
Description
• An outer join 1·etrieves all rows that satisfy the join condition, plus unmatched rows
in the left or right table.
• In most cases, you use the equal operator to retrieve rows with matching columns.
However, you can also use any of the other comparison operators.
• When a row with unmatched columns is retrieved, any columns from the other
table that are included in the result set are given null values.
Note
• The OUTER keyword is optional and typically omitted.
► PlOll 8
PlOll 4
P1012 3
P1012 1
P1012 s
P1013 6
P1013 9
P1014 10
Description
• The examples in this figure use the Departments, Employees, and Projects tables
from the EX database.
► Accounting 1 Hernandez
Maintenance s Hardy
Operations 3 Hlf191
PayroO 2 Smith
PayroU 2 Simonian
PayroO 2 Aaronsen
Personnel 4 Jones
Personnel 4 O'Leary
(8 rows)
(9 rows)
Description
• A left outer join returns unmatched rows from the first (left) table.
• A right outer join returns unmatched rows from the second (right) table.
( 8 rows )
(7 rows)
Description
• You can use outer joins to join multiple tables.
• You can combine inner and outer joins within a single SELECT statement.
(114 rows)
(7 rows)
Description
• You can use the USING keyword to simplify the syntax for joining tables.
• The join can be an inner join or an outer join.
• The tables must be joined by a column that bas the same name in both tables.
• To include multiple colu1nns, separate them with commas.
• The join must be an equijoin, which means that the equals operator is used to
compare the two columns.
- -
invoice number vendor_name
(114 rows)
(7 rows )
Description
• You can use the NATURAL keyword to create a natural join that joins two tables
based on all columns in the two tables that have the same name.
• Although the code for a nat1rral j oin is shorter than the code for joins that use
the ON or USING clause, a natural join only works correctly for ce1tain types of
database structures. In addition, a natural join often yields unexpected results for
complex queries. As a rest1lt, it's more common to t1se the ON or USING clause to
join tables.
(45 rows)
(45 rows)
Description
• A cross join joins each row from the first table with each row from the second
table. The resuJt set returned by a cross join is known as a Cartesian product.
(22 rows)
Description
• A union combines the result sets of two or more SELECT statements into one
result set.
• Each result set must return the same number of columns, and the corresponding
columns in each result set must have compatible data types.
• By default, a union eliminates duplicate rows. If you want to include duplicate
rows, code the ALL keyword.
• The column names in the final result set are taken from the first SELECT clause.
Column aliases assigned by the other SELECT clauses have no effect on the final
result set.
• To sort the rows in the fmal result set, code an ORDER BY clause after the last
SELECT statement. This clause must refer to the column names assigned in the
first SELECT clause.
( 114 rows )
A union that combines result sets from the same two tables
SELECT invoice_ number, vendor_ name, '33% Payment' AS payment_ type,
invoice_ total AS total, invoice_ total * 0.333 AS payment
FROM invoices JOIN vendors
ON invoices.vendor_ id = vendors.vendor_ id
WHERE invoice_ total > 10000
UNION
SELECT invoice_ number, vendor_ name, '50% Payment' AS payment_ type,
invoice_ total AS total, invoice_ total * 0.5 AS payment
FROM invoices JOIN vendors
ON invoices.vendor_ id = vendors.vendor_ id
WHERE invoice total BETWEEN 500 AND 10000
UNION
SELECT invoice_ number, vendor_ name, 'Full amount' AS payment_ type,
invoice_ total AS total, invoice_ total AS payment
FROM invoices JOIN vendors
ON invoices.vendor_ id = vendors.vendor_ id
WHERE invoice total < 500
ORDER BY payment_ type, vendor_ name, invoice_ number
invoice_number vendor_name payment_type total payment
- Data Reproductions Corp 33o/o Payment
-
► 40318 21842.00 7273.38600 I--- I
( 114 rows )
Figure 4-14 How to combine result sets from the same tables
144 Section 1 An introduction to MySQL
( 10 rows )
Description
• When you use afull outer join, the result set includes all the 1·ows from both tables.
• MySQL doesn 't provide language keywords for full outer joins, but you can
simulate a full outer join by using the UNION keyword to combine the result sets
from a left outer join and a right outer join.
Perspective
In this chapter, you learned a variety of techniques for combining data
from two or more tables into a single result set. In particular, you learned how
to use the explicit syntax to code inner joins. Of all the techniques presented in
this chapter, this is the one you'll use most often. So you'll want to be sure you
understand it thorough!y before you go on.
Terms
• •
JOin implicit syntax
join condition outer join
• • •
mner JOtn left outer join
ad hoc relationship right outer join
• • •
qualified column name eqUIJOlll
explicit syntax natural join
• •
SQL-92 syntax cross JOtn
table alias Ca1tesian product
•
schema union
self-join full outer join
Exercises
1. Write a SELECT statement that returns all columns from the Vendors table
inner-joined with all columns from the Invoices table. This should return 114
rows. Hint: You can use an asterisk(*) to select the columns from both tables.
2. Write a SELECT statement that returns these four columns:
vendor- name The vendor_name column from the Vendors table
invoice number The invoice number column from the Invoices table
i11voice date The invoice date coltrmn from the Invoices table
balance due The invoice_total column minus the payment_total
and credit_total columns from the Invoices table
Use these aliases for the tables: v for Vendors and i for Invoices.
Return one row for each invoice with a non-zero balance. This should return
11 rows.
Sort the result set by vendor_name in ascending order.
3. Write a SELECT statement that returns these three columns:
vendor- name The vendor- name column from the Vendors table
default- account The default- account- number column from the
Vendors table
description The account_description column from the
General_Ledger_Accounts table
Return one row for eac.h vendor. This should return 122 rows.
Sort the result set by account_description and then by vendor_name.
Chapter 4 How to retrieve data from two or m.ore tables 147
Delete a table
DROP TABLE old invoices
Description
• You can use the CREATE TABLE AS statement to create a new table based on the
result set defined by a SELECT state1nent.
• Each column name in the SELECT clause must be unique. If you use calculated
values in the select list, you 1nust name the column.
• You can code the other clauses of the SELECT statement just as yo11 would for any
other SELECT statement, inclucling grouping, aggregates, joins, and subqueries.
• If you code the CREATE TABLE AS statement as shown above, the table you
name must not exist. If it does, you must delete the table by using the DROP
TABLE statement before you execute the CREATE TABLE AS statement.
• When you use the CREATE TABLE AS state1nent to create a table, only the
column definitions and data are copied. Definitions of primary keys, foreign keys,
indexes, and so on are not included in the new table.
Description
• You use the INSERT statement to add one or more rows to a table.
• In the INSERT clause, you specify the name of the table that you want to add a row
to, along with an optional column list. The INTO keyword is also optional.
• In the VALUES clause, you specify the values to be inserted. If you don' t include a
column list in the INSERT clause, you must specify the column values in the same
order as in the table, and you must code a value for each column. If you include a
column list, you must specify the column values in the same order as in the column
list, and you can omit columns that have default values, accept null values, or are
automatically generated.
• To insert a null value into a colt1mn, you can use the NULL keyword. To insert a
default value or to have MySQL generate a value for an auto increment column,
you can use the DEFAULT keyword. For more information, see figure 5-3.
Description
• If a column is defined so it allows null values, you can use the NULL keyword in
the list of values to insert a null value into that column.
• If a column is defined with a default va]11e, you can use the DEFAULT keyword in
the list of values to insert the default value for t11at column.
• If a column is defined as an auto increment column, you can use the DEFAULT
keyword in the list of values to have MySQL generate the value for the column.
• If you include a column list, you can omit columns with default values and null
values. Then, the default value or null value is assigned automatically. You can also
omit an auto increment column. Then, MySQL generates the value for the column.
Description
• A subquery is a SELECT statement that's coded within another SQL statement.
• To insert rows selected from one or more tables into another table, you can code a
subquery in place of the VALUES clause. Then, MySQL inserts the rows returned
by the subquery into the target table. For this to work, the target table must already
.
exist.
• The rules for working with a column list are the same as they are for any INSERT
statement.
Description
• You use the UPDATE statement to modify one or more rows in a table.
• In the SET clause, you name each column and its new value. Yott can specify the
value for a column as a literal or an expression.
• In the WHERE clause, you can specify the conditions that 1nust be met for a row to
be updated.
• You can use the DEFAULT and NULL keywords to specify default and null values
as described in figure 5-3.
• By default, MySQL Workbench 1uns in safe update mode. That prevents you from
updating rows if the WHERE clause is omitted or doesn't 1·efer to a primary key or
foreign key column.
• To get around the restrictions of safe update mode, you can turn this mode off. To
do that, select the Edit➔ Preferences command, select the SQL Editor node, change
the ''Safe Updates'' option, and restart MySQL Workbench.
Warning
• If you turn off safe update mode and omit the WHERE clause, all rows in the table
will be updated.
Update the terms for all invoices for vendors in three states
UPDATE inv oic e s
SET terms_ id = 1
WHERE vendor_ id IN
(SELECT vendor_ id
FROM vendors
WHERE vendor_ state IN ( 'CA', 'AZ', 'NV' ))
(40 rows affected)
Description
• You can code a subquery in the WHERE clause of an UPDATE statement to
provide one 01· more values used in the search condition.
Description
• You can use the DELETE statement to delete one or more rows from the table you
name in the DELETE clause.
• You specify the conditions that must be met for a row to be deleted in the WHERE
clause.
• You can use a subquery within the WHERE clause.
• A foreign key constraint may prevent you from deleting a row. In that case, you can
only delete the row if you delete all child rows for that row first.
• By default, MySQL Workbench runs in safe update mode. That prevents you from
deleting rows if the WHERE clause is omitted or doesn't refer to a primary key or
foreign key column. For information on turning safe update mode off, see figure
5-5.
Warning
• If you tum safe update mode off and omit th.e WHERE clause from a DELETE
statement, all the rows in the table will be deleted.
Perspective
In this chapter, you learned how to use the INSERT, UPDATE, and
DELETE statements to modify the data in a database. In chapters 10 and 11,
you'll learn more about how table definitions can affect the way these state-
ments work. And in chapter 14, you'll leam more about executing gi·oups of
INSERT, UPDATE, and DELETE statements as a single transaction.
Term
subquery
Exercises
To test whether a table has been modified correctly as you do these exercises,
you can write and run an appropriate SELECT statement. Or, when you 're
using MySQL Workbench, you can right-click on a table name in the Navigator
window and select the Select Rows - Limit 1000 command to display the data
for the table in a Result tab. To refresh the data in this tab after modifying the
table data, click the Refresh button in the toolbar at the top of the tab.
1. Write an INSERT statement that adds this row to the Terms table:
terms- id: 6
terms_ description: Net due 120 days
terms_due_days: 120
Use MySQL Workbench to review the column definitions for the Terms table,
and include a column list with the required colu1nns in the INSERT statement.
2. Write an UPDATE statement that modifies the row you just added to the
Terms table. This statement should change the terms_description column to
''Net due 125 days'', and it should change the terms_due_days column to 125.
3. Write a DELETE statement that deletes the row you added to the Terrns table
in exercise 1.
4. Write an INSERT statement that adds this row to the Invoices table:
invoice id: The next automatically generated ID
vendor- id: 32
invoice- number: AX-014-027
invoice- date: 8/1/2018
invoice- total: $434.58
payment_total: $0.00
credit total: $0.00
terms id: 2
invoice- due- date: 8/31/2018
payment_date: null
Write this statement without using a column list.
Clzapter 5 How to insert, update, and delete data 165
5. Write an INSERT statement that adds these rows to the Invoice- Line- Items
table:
• •
1nvo1ce_sequence: 1 2
account number: 160 527
line- item- amount: $180.23 $254.35
line_item_description: Hard drive Exchange Server update
Set the invoice_id column of these two rows to the invoice ID that was gener-
ated by MySQL for the invoice you added in exercise 4.
6. Write an UPDATE statement that modifies the invoice you added in exercise
4. This statement should change the credit_total column so it's 10% of the
invoice_total column, and it should change the payment_total column so the
sum of the payment_total and credit_total columns are equal to the
invoice- total column.
7. Write an UPDATE statement that modifies the Vendors table. Change the
default- account- number column to 403 for the vendor with an ID of 44.
8. Write an UPDATE statement that modifies the Invoices table. Change the
terms_id column to 2 for each invoice that's for a vendor with a
defa11lt_terms_id of 2.
9. Write a DELETE statement that deletes the row that you added to the Invoices
table in exercise 4. When you execute this statement, it will produce an error
since the invoice has 1·elated rows in the Invoice_Line_Items table. To fix that,
precede the DELETE statement with another DELETE statement that deletes
the line items for this invoice. (Remember that to code two or more statements
in a script, you must end each statement with a semicolon.)
More SQL skills
as you need them
In section 1, you learned a professio11al subset of SQL skills that you can
use to work with data in an existing database. Now, in this section, you
can add to those skills by learning new skills whenever you need them. To
make that possible, each chapter in this section has been designed as an
independent module. As a result, you can read these chapters in whatever
sequence you prefer.
In chapter 6, you '11 learn how to summarize the data that you retrieve.
In chapter 7, you'll learn more about coding subqueries. In chapter 8,
you'll learn more about the types of data that MySQL suppo11s. And
in chapter 9, you'll learn how to use MySQL functions in your SQL
statements.
How to code summary
•
queries
ln this chapter, you'll learn how to code queries that summarize data. For
example, you can use summary queries to report sales totals by vendor or
state. Similarly, you can use summary queries to get a count of the number
of i11voices that were processed each day of the month. But first, you'll learn
how to use a special type of function called an aggregate function. Aggregate
functions allow you to do jobs like calculate averages, summarize totals, or find
the highest value for a given column, and you 'll use them in summary queries.
A summary query that counts unpaid invoices and calculates the total due
SELECT COUNT{*) AS number_ of_ invoices,
SUM(invoice_ total - payment_ total - credit_total) AS total_due
FROM invoices
WHERE invoice total - payment_ total - credit total> 0
number _of_invokes total_due
•
► 11 32020.42
Description
• Aggregate functions, also called column functions, perform a calculation on the
values in a set of selected rows.
• A sitmmary query is a SELECT statement that includes one or more aggregate
functions.
• The expression you specify for the AVG and SUM functions must result in a
numeric value. The expression for the MIN, MAX, and COUNT ft.1nctions can
result in a numeric, date, or string value.
• By default, all values are included in the calculation regardless of whether they're
duplicated. If you want to omit duplicate values, code the DISTINCT keyword.
This keyword is typically used with the COUNT function.
• All of the aggregate functions except for COUNT(*) ignore null values.
• If you code an aggregate function in the SELECT clause, that clause can include
non-agg1·egate columns from the base table if that column is functionally dependent
on an aggregate column. See figure 6-3 for more information.
A summary query that uses the COUNT(*), AVG, and SUM functions
SELECT 'After 1/1/2018' AS selection_ date,
COUNT(*) AS number_ of_ invoices,
ROUND{AVG{invoice_ total), 2) AS avg_ invoice_ amt,
SUM{invoice_ total) AS total_ invoice_ amt
FROM invoices
WHERE invoice_ date > '2018-01-01'
selection_date number_of_lnvOJces avg_ilvoice_amt total_invoice_amt
► After 1/1/2018 114 1879.74 214290.51
-► -
number _of_vendors
34
number_of_involces
114
avg_invoic:e_amt
1879.74
total_invoice_amt
214290.51
Description
• To cot1nt all of the selected 1·ows, you typically use the COUNT(*) function.
Alternately, you can use the COUNT function with the name of any column that
can't contain null values.
• To cot1nt only the rows with unique values in a specified column, you can code
the COUNT function with the DISTINCT keyword followed by the name of the
column.
► 110 23978.48
72 10963.66
104 7125.34
99 6940.25
119 490 1.26
122 2575.33
86 2433.00
100 2184.50
(8 rows)
Description
• The GROUP BY clause groups the rows of a result set based on one or more columns or
expressions. To include two or more columns or expressions, separate them by commas.
• If you include aggregate functions in the SELECT clause, the aggregate is calculated for
each group specified by the GROUP BY clause.
• If you include two or more colu1nns or expressions in the GROUP BY clause, they form
a hierarchy where each column or expression is subordinate to the previous one.
• The HAVING clause specifies a search condition for a group or an aggregate. MySQL
applies this condition after it groups the rows that satisfy the search condition in the
WHERE clause.
• When a SELECT statement includes a GROUP BY clause, the SELECT clause can
include the columns used for grouping, aggregate functions, and expressions that
result in a constant value.
• The SELECT clause can also include columns that are functionally dependent on a
column used fo1· grouping. To be functionally dependent, the grouping column must
be a primary key of the table that contains the column in the SELECT clause or it
must be unique and not allow null values.
► 34
37
2
3
-
48 1
72 2
(34 rows )
(20 rows)
CA Oxnard 3 188,00
CA Pasadena 5 196. 12
CA Sacramento 7 253.00 \I
(12 rows)
Description
• With MySQL 8.0.12 and earlier, the GROUP BY clause sorted the columns in ascending
sequence by default. Then, to change the sort sequence, you could code the DESC
keyword after the column name in the GROUP BY clause. In addition, to get your results
faster, you cot1ld code an ORDER BY NULL clause to prevent MySQL from sorting the
rows in the GROUP BY clause.
• With MySQL 8.0.13 and later, the columns in a GROUP BY clause are no longer sorted by
default, and you can't code the ASC or DESC keyword on this clause. Instead, you must
use the ORDER BY clause to specify the sort sequence.
Figure 6-4 Queries that use the GROUP BY and HAVING clauses
178 Section 2 More SQL skills cts you need them
(19 rows)
{20 rows)
Description
• When you include a WHERE clat1se in a SELECT statement that uses grouping
and aggregates, MySQL applies the search condition before it groups the rows and
calculates the aggregates.
• When you include a HAVING clause in a SELECT statement that uses grouping
and aggregates, MySQL applies the search condition after it groups the rows and
calculates the aggregates.
• A WHERE clause can refer to any colwnn in the base tables.
• A HAVING clause can only refer to a column included in the SELECT clause.
• A WHERE clause can't contain aggregate ft1nctions.
• A HAVING clause can contain aggregate functions.
Figure 6-5 How the HAVING clause compares to the WHERE clause
180 Section 2 More SQL skills cts you need them
► 2018-05-3 1 2 453.75
2018-05-25 3 220L15
2018-05-23 2 347. 75
2018-05-21 2 8078.44
2018-05-13 3 1888.95
2018-05- 11 2 5009.51
2018-05-03 2 866.87
(7 rows)
Description
• You can use the AND and OR operators to code compound search conditions in a
HAVING clause just as you can in a WHERE clause.
• If a search condition includes an aggregate function, it must be coded in the
HAVING clause. Otherwise, it can be coded in either the HAVING or the WHERE
clause.
(35 rows)
A summary query that includes a summary row for each grouping level
SELECT vendor_ state, vendor_ city, COUNT(*) AS qty_vendors
FROM vendors
WHERE vendor_ state IN ( • IA• , •NJ• )
GROUP BY vendor_ state, vendor_ city WITH ROLLUP
vendor_state vendor_dty qty_vendors
► IA Fairfield 1
IA Washington 1
IA om,, 2
NJ East Brunswick 2
NJ Fairfield 1
NJ Washington 1
NJ HW!I 4
ml 11111!1 6
Description
• You can use the WITH ROLLUP operator in the GROUP BY clause to add
summary rows to the final result set.
• The WITH ROLLUP operator adds a summary row for each group specified in the
GROUP BY clause. It also adds a summary row to the end of the result set that
summarizes the entire result set.
• If the GROUP BY clause specifies a single group, the WITH ROLLUP operator
only adds the fmal summary row.
• With MySQL 8.0.12 and earlier, you couldn' t use the ORDER BY clause with the
WITH ROLLUP operator. Instead, to sort individual columns, you coded the ASC
or DESC keyword after the column in the GROUP BY clause.
• With MySQL 8.0.13 and later, you can't code the ASC or DESC keyword on the
GROUP BY clause. However, you can now include an ORDER BY clause to sort
the result set when the GROUP BY clause includes WITH ROLLUP.
• With MySQL 8.0.12 and earlier, you couldn't use the DISTINCT keyword in any
of the aggregate functions when you used the WITH ROLLUP operator. With
MySQL 8.0.13 and later, you can use the DISTINCT keyword.
A summary query that uses WITH ROLLUP on a table with null values
SELECT invoice_ date, payment_ date,
SUM(invoice_ total) AS invoice_ total,
SUM(invoice_ total - credit_ total - payment_ total) AS balance_ due
FROM invoices
WHERE invoice_ date BETWEEN '2018-07-24' AND 1 2018-07-31 1
GROUP BY invoice_ date, payment_ date WITH ROLLUP
invoice_date payment_date Invoice_total balance_due
0®91
► 2018-07-24 503.20 503. 20
2018-07-24 2018-08-19 3689.99 0.00
2018-07-24 2018-08-23 67.00 0 .00
2018-07-24 2018-08-27 23517.58 0 .00
2018-07-24 HPJII 27777.n 503. 20
2018-07-25 2018-08-22 1000.'16 0 ,00
2018-07-25 l®!I 1000.-46 0 .00
2018-07-28 UQl!I 90.36 90.36
2018-07-28 HW!I 90.36 90.36
2018-07-30 2018-09-03 22. 57 0 .00
2018--0 7-30 ®J!I 22.57 o.oo
2018-07-31 lllij!i 10976.06 10976.06
il®!I 10976.06 10976.06
~&,;8-07-31
HW!I 39867.22 11569.62
Description
• The GROUPING function returns 1 if the expression is null because it's in a
summary row. Otherwise, it returns 0.
Part 2 of figure 6-8 shows another common use for the GROUPING
function. The query in this example is identical to the second one in part 1
of this figure, except that it includes a HAVING clause. This clause uses the
GROUPING function to filter the result set so only the summary rows are
included. To do that, it checks if this function returns a value of 1 for the
invoice_date or payment_date column.
Chapter 6 How to code sum1n.ary queries 187
Description
• The GROUPING function is co1nmo1tly used to replace the nulls that are gener-
ated by WITH ROLLUP with literal values. To do that, you can use it with the IF
function as shown in this figure.
• The IF function evaluates the expression in the frrst argument and returns the
second argument if the expression is true and the third argument if the expression is
false. See chapter 9 for more information on this function.
• If you want to display just the summary rows produced by the WITH ROLLUP
operator, you can include one or more GROUPING functions in the HAVING
clause.
• In addition to the SELECT and HAVINO clauses, you can code the GROUPING
function in the ORDER BY clause.
,-
I vendor_id invoice_date 1nvolce_total total_invoices vendor _total '
-
vendor id
-
invoice date invoice total
- -
total invoices vendor total
-
► 72 2018-06-01 21842.00 155800.00 21842.00
99 2018-06-18 6940.25 155800.00 6940.25
104 2018-05-21 7125.34 155800.00 7125.34
110 2018-07-31 10976.06 155800.00 10976.06
110 2018--07-23 20551.18 155800.00 31527.24
110 20 18-07-24 23517. 58 155800.00 55044.82
110 2018-07-19 26881.40 155800.00 81926.22
110 2018-05-28 37966.19 155800.00 119892.4 1
Description
• The window functions can be used with all of the aggregate functions listed in
figure 6-1 , as well as others.
• Unlike aggregate functions that use GROUP BY, the groups, or partitions, in an
aggregate window function are not collapsed to a single row.
• A window consists of all of the rows that are needed to calculate the aggregate
value for the current row.
• To treat an aggregate function as a window function, you include an OVER clause
that indicates how to partition the rows in the result set.
• If you code an e1npty OVER clause, the entire result set is treated as a single partition.
• If you code an OVER clause with a PARTITION BY clause, the aggregate function
is performed on each partition.
• If you code an ORDER BY clause on the OVER clause, the rows within each parti-
tion are sorted and the values from one row to the next are cumulative.
Another difference between these two result sets are the values in the
vendor_total column for vendor 110. That's because, when you code the
ORDER BY clause, the frame includes all of the rows from the start of the parti-
tion through the current row. You' ll learn more about defining frames explicitly
in the next figure . For now, just realize that a frame consists of one or more rows
within a partition relative to the current row.
For the SUM function, this means that the column contains a cumulative
total for each vendor. To see how this works, you can compare the values in
the vendor- total column with the values in the invoice- total column for vendor
110. Here, the values for the first row are the same. However, the second row
in the vendor_total column contains the value of the first row plus the value of
the second row in the invoice- total colunm. The third row in the vendor- total
column contains the value of the second row plus the value of the thit·d row in
the invoice total column. And so on.
Description
• A frame can be defined as the number of rows before and after the current row
(ROWS) or a range of values based on the value of the current row (RANGE).
• If you specify just the starting row for a frame, the ending row is the current row.
To specify both a starting and ending row, you use the BETWEEN clause. When
you use BETWEEN, the starting row for a frame must not come after the ending
row.
• If an ORDER BY clause is included in the OVER clause and you use the ROWS
keyword, values are accumulated up to and including the current row as shown above.
In that case, the ending row defaults to the cun·ent row. You can also omit the
frame definition entirely, since it's the default when you include ORDER BY on
the OVER clause. You saw how that worked in the previous figure.
Part 2 of figure 6-10 presents two more queries that use frames. The fust
query is almost identical to the one in part 1 of this figure. The only difference is
that it uses the RANGE keyword instead of the ROWS keyword. Because of that,
the frame includes all of the rows within the partition, along with the current row
and any of its peers. In this case, a peer is a row that has the same value as other
rows in the sort column. In this example, for instance, the result set includes
three invoices dated 2018-04-16 for vendor 123. If you look at the vendor_total
column for these rows, you'll see that they all contain the same value. That's
because the value of the invoice total colu1nn for all three of these rows is
included in the accumulation for the rows.
The second example in this figure illustrates a common use for frames.
Here, a moving average is calculated for the invoice totals. A moving average is
an average that's calculated on the current row plus a specified number of rows
before and after the current row. It's particularly useful when working with data
over a period of time to eliminate short-term fluctuations so long-term trends
become more obvious.
In this example, a three-month average is calculated for the sum of invoice
totals. To do that, the RANGE keyword is coded with a BETWEEN clause
that indicates that the invoice total for the current month, one month before the
cun·ent month, and one month after the current month should be used to calcu-
late the average. The three-month average for month 5, for example, is calculated
by adding the values in the invoice_total column for months 4, 5, and 6 and
dividing by 3.
Note that when you calculate a moving average, there isn't a row before
the first row to include in the average. Because of that, the average for that row
includes just the invoice totals for the current row and the next row. Similarly, the
average for the last row includes just the invoice totals for the current row and
the previous row.
This query also uses the MONTH function in the SELECT clause, the
ORDER BY clause for the OVER clause, and the GROUP BY clause. This
function extracts the numeric month from a date. You'll learn about this function
as well as other functions for working with dates in chapter 9.
Chapter 6 How to code sum1ncary queries 193
► 4 5828.18 32212.64
5 58597. 10 39614.34
6 54417.73 69370. 19
7 95095.75 49955.08
8 351.75 4n23.75
Description
• If an ORDER BY clause is included in the OVER clause and you use the RANGE keyword,
values are accumulated up to and including the current row as well as its peer rows. A peer
is a row that's in the same sort sequence as other rows in the partition as shown by the first
example above.
• You can use a frame to calcul ate a moving average. A moving average is calculated by adding
the value of the current row to the values of zero or 1nore preceding and following rows.
• Because there are no preceding rows for the frrst row in a partition, the moving average
for that row consists of the average of the value of the current row plus the values of the
following rows. Similarly, the moving average for the last row consists of the average of
the value of the current row plus the values of the previous rows.
A SELECT statement with four functions that use the same window
SELECT vendor_ id, invoice_ date, invoice_ total,
SUM(invoice_ total) OVER(PARTITION BY vendor_ id) AS vendor_ total,
ROUND(AVG(invoice_ total) OVER(PARTITION BY vendor_ id) , 2) AS vendor_ avg,
MAX(invoice_ total) OVER(PARTITION BY vendor_ id) AS vendor_max,
MIN(invoice_ total) OVER(PARTITION BY vendor_ id) AS vendor_min
FROM invoices
WHERE invoice_ total > 5000
Description
• To define a named window, you code a WINDOW clause. This clause should be coded
after the HAVING clause and before the ORDER BY clause, if those clauses are included.
• To use a named window, you code it on the OVER clause. If you code just the window
name, you don't include parentheses.
• If a WINDOW clause doesn' t include a PARTITION BY or ORDER BY clause or a
frame definition, you can add it to the window when you use it. To do that, you code
the window name and the additional clause in parentheses after the OVER keyword.
Perspective
In this chapter, you learned how to code queries that group and summarize
data. In most cases, you '11 be able to use the techniques presented here to get
the summary information you need.
Terms
scalar function partition
aggregate function window
column function frame
summary query peer
•
functionally dependent column movmg average
aggregate window function named window
Exercises
1. Write a SELECT statement that returns one row for each vendor in the
Invoices table that contains these columns:
The vendor_id column from the Invoices table
The sum of the invoice- total columns in the Invoices table for that vendor
This should return 34 rows.
2. Write a SELECT statement that returns one row for each vendor that contains
these columns:
The vendor_name column from the Vendors table
The sum of the payment_total columns in the Invoices table for that vendor
Sort the result set in descending sequence by the payment total sum for each
vendor.
3. Write a SELECT statement that returns one row for each vendor that contains
three columns:
The vendor name column from the Vendors table
The count of the invoices in the I11voices table for each vendor
The sum of the invoice_total columns in the Invoices table for each vendor
Sort the result set so the vendor with the most invoices appears first.
4. Write a SELECT statement that returns one row for each general ledger
account number that contains three columns:
The account_description column from the General_Ledger_Accounts table
The count of the items in the Invoice- Line- Items table that have the same
account_number
Chapter 6 How to code sum1ncary queries 197
The sum of the line item amount columns in the Invoice- Line- Items table
that have the same account_nu1nber
Return only those rows where the count of line items is greater than 1. This
sl1ould return 10 rows.
Group the result set by the account_description column.
Sort the resL1lt set in descending sequence by the sum of the line item
a1nounts.
5. Modify the solution to exercise 4 so it returns only invoices dated in the
second quarter of 2018 (April 1, 2018 to June 30, 2018). This should still
return 10 rows but with some different line item counts for each vendor. Hint:
Join to tlie Invoices table to code a secirch condition based on invoice_date.
6. Write a SELECT statement that answers this question: What is the total
amount invoiced for each general ledger account nt1mber? Return these
columns:
The account- number column fro1n the Invoice- Line- Items table
The sum of the line_item_amount columns from the Invoice_Line_Items
table
Use the WITH ROLLUP operator to include a row that gives the grand total.
This should return 22 rows.
7. Write a SELECT statement that answers this question: Which vendors are
being paid from more than one account? Return these columns:
The vendor name colL1mn from the Vendors table
The count of distinct general ledger accounts that apply to that vendor's
• •
1nvo1ces
This should return 2 rows.
8. Write a SELECT statement that answers this question: What are the last
payment date and total amount due for each vendor with each terms id?
Return these columns:
The terms id column from the Invoices table
The vendor id column from the Invoices table
The last payment date for each combination of terms id and vendor id in the
Invoices table
The sum of the balance due (invoice_total - payment_total - credit_total)
for each combination of terms id and vendor id in the Invoices table
Use the WITH ROLLUP operator to include rows that give a summa1-y for
each terms id as well as a row that gives the grand total. This should return 40
rows.
Use the IF and GROUPING functions to replace the null values in the terms_id
and vendor_id columns with literal values if they're for st1mmary rows.
198 Section 2 More SQL skills cts you need them
An introduction to subqueries
As you learned in chapter 5, a subquery is a SELECT statement that's coded
within another SQL statement. Since you already know how to code SELECT
statements, you already know how to code subqueries. Now you just need to
learn where you can code them and when you should use them.
( 2 1 rows )
Description
• A subquery is a SELECT statement that's coded within another SQL statement. For
this to work, yo11 m11st enclose the subquery in parentheses.
• A subquery can return a single value, a list of values (a result set that has a single
column), or a table of values (a result set that has multiple columns).
• A subquery can be coded, or introduced, anywhere a single value, a list of values,
or a table is allowed.
• The syntax for a subquery is the same as for a standard SELECT statement.
However, a subquery can't include an ORDER BY clause.
• Subqueries can be nested within other subqueries.
( 40 rows )
Advantages of joins
• The SELECT clause of a join can include columns from both tables.
• A join tends to be more intuitive when it uses an existing relationship between the
two tables, such as a primary key to foreign key relationship.
Advantages of subqueries
• You can use a subquery to pass an aggregate value to the main query.
• A subquery tends to be more intuitive when it uses an ad hoc relationship between
the two tables.
• Long, complex queries can sometimes be easier to code u sing subqueries.
Description
• Like a join, a subquery can be used to code queries that work with two or more
tables.
• Most subqueries can be restated as joins and most joins can be restated as
subqueries.
(34 rows)
(88 rows)
Description
• You can introduce a subquery with the IN operator to provide the list of values that
are tested against the test expression.
• When you use the IN operator, the subquery must return a single column of values.
• A query that uses the NOT IN operator with a subquery can typically be restated
using an outer join.
( 9 rows )
Description
• You can use a comparison operator in a WHERE clause to compare an expression
with the results of a subquery.
• If you code a search condition without the ANY, SOME, and ALL keywords, the
subquery must return a single value.
• If you include the ANY, SOME, or ALL keyword, the subquery can return a list of
values. See figures 7-5 and 7-6 for more information on using these keywords.
(2 5 rows )
Description
• You can use the ALL keyword to test that a comparison condition is true for all of
the values returned by a subquery.
• If no rows are returned by the subquery, a comparison that uses the ALL keyword is
always true.
• If all of the rows returned by the subquery contain a null value, a comparison that
uses the ALL keyword is always false.
Get invoices smaller than the largest invoice for vendor 115
SELECT vendor_ name, invo ice_ number, invoic e _ total
FROM vendors JOIN invoices ON vendors.vendor_ id = invoices.vendor id
WHERE invoic e _ total < ANY
(SELECT invoice_ total
FROM invoices
WHERE vendor_ id = 115 )
( 17 rows )
Description
• You can use the ANY keyword to test that a condition is true for one or more of the
values returned by a subquery.
• If the subquery doesn't return any values, or if it only returns null values, a compar-
ison that uses the ANY keyword evaluates to false.
• The SOME keyword works the same as the ANY keyword.
( 36 rows )
Description
• A correlated subquery is a subquery that is executed once for each row in the
main query. In contrast, an uncorrelated subquery is executed only once. All of the
subqueries in the previous figures are uncorrelated subqueries.
• A correlated subquery refers to a value that's provided by a column in the main
query. For each different value that's returned by the main query for that column,
the subquery returns a different result.
• To refer to a column in the main query, you can qualify the column with a table
name or alias. If a correlated subquery uses the same table as the main query, you
can use table aliases to re1nove ambiguity.
(88 rows )
Description
• You can use the EXISTS operator to test that one or more rows are returned by the
subquery.
• You can use the NOT EXISTS operator to test that no rows are returned by the
subquery.
• When you use these operators with a subquery, it doesn't matter what columns you
specify in the SELECT clause. As a result, you typically just code an asterisk ( * ).
(122 rows)
Description
• When you code a subquery in the SELECT clause, the subquery must return a
single value.
• When you code a subquery in the SELECT clause, you typically use a correlated
subquery.
• A query that includes a subquery in its SELECT clause can typically be restated
using a join instead of the subquery. Because a join is usually faster and easier to
read, subqueries are seldom coded in the SELECT clause.
Get the largest invoice total for the top vendor in each state
SELECT vendor_ state, MAX(sum_ of_ invoices) AS max_ sum_ of_ invoices
FROM
(
SELECT vendor_ state, vendor_ name,
SUM(invoice_ total) AS sum_ of_ invoices
FROM vendors v JOIN invoices i
ON v.vendor_ id = i.vendor_ id
GROUP BY vendor_ state, vendor name
) t
GROUP BY vendor_ state
ORDER BY vendor_ state
(34 rows)
( 10 rows )
Description
• A subquery that's coded in the FROM clause returns a result set that can be referred
to as an inline view.
• When you code a subquery in the FROM clause, you must assign an alias to it.
Then, you can use that alias just as you would any other table name or alias.
• When you code a subquery in the FROM clause, you should use an alias for any
columns in the subquery that perform calculations. Then, the inline view can use
these aliases as the column names of the table, and the main query can refer to the
columns by these names.
(10 rows)
Description
• This query retrieves the vendor from each state that has the largest invoice total. To
do that, it uses three subqueries.
• This query uses comments to clearly identify its three queries.
• The subqueries named tl and t2 return the same result set. This result set includes
the vendor state, name, and sum of invoices.
• The subquery named t3 returns a result set that includes the vendor state and the
largest sum of invoices for any vendor in that state. To do that, this subquery uses a
nested subquery named t2.
• The subqueries named tl and t3 are joined on both the vendor_state and st1m_of_invoices
columns.
(34 rows)
(10 rows)
(10 rows )
Description
• A common table expression (CTE) is a SELECT statement that creates one or
more named temporary result sets that can be used by the query that follows.
• To use a CTE, you code the WITH keyword followed by the definition of the
CTE. Then, iminediately after the CTE, you code the statement that uses it.
• To code multiple CTEs, separate them with commas. Then, each CTE can refer to
itself and any previously defined CTEs in the same WITH clause.
• To code a recursive CTE, include the RECURSIVE keyword after the WITH
keyword. See figure 7-14 for more on recursive CTEs.
• Although you can use CTEs with SELECT, INSERT, UPDATE, and DELETE
statements, you'r·e most likely to use them with SELECT statements.
► 1 Cindy Smith 1
2 Bmer Jones 2
9 Paulo Locario 2
3 Ralph Simonian 3
4 Olivia Hernandez 3
7 Thomas Hardy 3
8 Rhea O'Leary 3
5 Robert Aaronsen 4
6 Denise Watson 4
Description
• A recursive query is a query that can loop through a result set and perform processing
to return a final result set. A recursive CTE can be used to create a recursive query.
• A recursive CTE contains a non-recursive SELECT statement followed by a
recursive SELECT statement, and these two statements must be connected by the
UNION or UNION ALL operator.
Perspective
Subqueries are a powerful tool that you can use to solve difficult problems.
Before you use a subquery, however, remember that a subqt1ery can often be
restated more clearly by using a join. If so, you ' 11 typically want to use a join
instead of a subquery.
If you find yourself coding the same subqueries in multiple places, you
should consider cr·eating a view for that subquery as desc1ibed in chapter 12.
This will help you develop queries more quickly since you can use the view
instead of coding the subquery again. In addition, since views typically execute
more quickly than subqueries, this may improve the performance of your
•
quenes.
Terms
subquery comment
introduce a subquery pseudocode
nested subquery common table expression (CTE)
•
correlated subquery recursive query
uncOI*related subquery recursive CTE
inline view
Exercises
1. Write a SELECT statement that returns the same result set as this SELECT
statement, but don't use a join. Instead, use a subquery in a WHERE clause
that uses the IN keyword.
SELECT DISTINCT vendor name
FROM vendors JOIN invoices
ON vendors.vendor id= invoices.vendor id
ORDER BY vendor_ name
2. Write a SELECT statement that answers this question: Which invoices have
a payment total that's greater than the average payment total for all invoices
with a payment total greater tl1an O?
Return the invoice- number and invoice- total colu1nns for each invoice. This
should return 20 rows.
Sort the results by the invoice_total column in descending order.
3. Write a SELECT statement that returns two columns from the
General_Ledger_Accounts table: account_number and account_description.
Return one row for each account number that has never been assigned to any
line item in the Invoice_Line_Items table. To do that, use a subquery intro-
duced with the NOT EXISTS operator. This should return 54 rows.
Sort the results by the account_number column.
Chapter 7 How to l·ode subqueries 229
Overview
The MySQL data types can be divided into the five categories shown in
figure 8-1. To start, the character data types are intended for storing a string of
one or more characters, which can include letters, numbers, sy1nbols, or special
characters. The terms character, string, and text are used interchangeably to
describe this type of data.
The numeric data types are intended for storing numbers that can be used
for mathematical calculations. As you'll see in this chapter, MySQL can store
numbers in a variety of formats. At a basic level, you can divide numbers into
two categories: integers and real numbers. Integers are numbers that don't have a
decimal point, and real numbers are numbers that have a decimal point.
The date and time data types are intended for storing dates, times, or
both dates and times. These data types are typically referred to as date/time or
temporal data types.
Since the first three categories are the most widely used, this book focuses
on these data types. However, MySQL also provides large object (LOB) data
types that are useful for storing images, sound, video, and large amounts of
character data. In addition, MySQL provides spatial data types that are useful
for storing geographical values such as global positioning system (GPS) data.
These data types are referred to as geometry types because they define a point or
group of points that represent any location or area in the world.
Finally, MySQL provides the ISON data type, which is used to store
JavaScript Object Notation (ISON) documents. Although you can store JSON
documents in a character column, the JSON data type provides two advantages.
First, when you store a JSON document in a JSON column, the document is
automatically validated. Then, if it's invalid, an error occurs. Second, the internal
storage format provides for quick access to the document.
Clzapter 8 How to work with data types 233
Data types
Category Description
Character Strings of character data
Numeric Numbers that don't include a decimal point (integers) and
numbers that include a decimal point (real numbers)
Date and time Dates, times, or both
Large Object (LOB) Large strings of character or binary data
Spatial Geographical values
JSON JSON documents
Description
• MySQL provides data types for storing many types of data.
• Numbers that don' t include a decimal point are known as integers.
• Numbers that include a decimal point are known as real numbers.
• The date and time data. types are often referred to as the date/time or temporal data
type.';.
• The large object (LOB) data types are ·useful for storing images, sound, video, and
large amounts of text.
• The spatial data types are useful for storing geometric or geographical values
such as global positioning system (GPS) data. These data types are referred to as
geometry types.
• The ISON data type is used for storing JavaScript Object Notation (ISON)
documents.
Description
• The CHAR type js t1sed for fixed-length strings. A column with trus type t1ses the
same amount of storage for each value regardless of the actual length of the st1ing.
• The VARCHAR type is used for variable-length strings. A column with this type uses
a varying amount of storage for each value depending on the length of the string.
• By default, MySQL 8.0 and later use the utj8mb4 character set for the CHAR and
VARCHAR types. This character set is a multiple-byte character set. It typically
uses 1 byte per character, but can use up to 4 bytes per character. However, the
utf8mb4 format provides for all characters in most languages by providing support
for all of the characters in the Unicode stan.dard.
• By default, MySQL 5.6 and 5.7 use the utj8mb3 character set for the CHAR and
VARCHAR types, which can use up to 3 bytes per character.
• By default, MySQL 5.5 and earlier use the latinl character set for the CHAR and
VARCHAR types. This character set is a single-byte character set that supports all
of the characters that are used in English and by most western European languages.
• To learn how to change the character set, please see chapter 11 .
In most cases, it makes sense to use the utf8mb4 character set. That way,
your database supports most characters in most languages as well as emojis.
Howeve1·, if you want to use the CHAR type and you only need to support
English and western European languages, you may want to use the latinl
character set to keep storage requirements to a minimum. In chapter 11 , you'll
learn how to change the character set for a database.
Although you typically store numeric values using numeric types, the
character types may be a better choice for some numeric values. For example,
you typically store zip codes, telephone numbers, and social security numbers
in character columns even if they contain only numbers. That's because their
values aren't used in numeric operations. In addition, if you store these numbers
in numeric colun111s, MySQL may strip leading zeros in some situations, which
isn't what you want.
In figure 8-2, the first five examples use single quotes to specify a string
literal. However, the sixth example t1ses double quotes to specify a string literal.
This allows the string literal to include a single quote, and it shows that you
can use single or double quotes for string literals. Although it's common to use
single quotes, double quotes are useful if you need to include a single quote in
the string.
Description
• The integer types store numbers without any digits to the right of the decimal point.
• If the UNSIGNED attribute for the integer is set, it changes the range of acceptable
values. If you try to store a negative integer in a column with the UNSIGNED attri-
bute, an error occurs.
• If the ZEROFILL attribute for the integer is set, MySQL displays the integer with
zeros padded from the left, up to the maximum display size.
• If the ZEROFILL attribute is set, MySQL automatically sets the UNSIGNED
attribute.
• To specify a display size, you can code it in _parentheses after the data type. This
only affects how MySQL displays the value, not how it stores the value.
• The INTEGER type is a synonym for the INT type.
• The BOOL and BOOLEAN types are synonyms for TINYINT(l). You can use
these types to store TRUE and FALSE values, where 1 represents a true value and 0
represents a false value.
Description
• Real numbers can include digits to the right of the decimal point. The precision of
a real n11mber indicates the total number of digits that can be stored, and the scale
indicates the number of digits that can be stored to the right of the decimal point.
• The DECIMAL type is considered an exact numeric type because its precision is
exact.
• The DOUBLE and FLOAT types store floating-point numbers, which have a
limited number of significant digits. These data types are considered approximate
numeric data types because they may not represent a val11e exactly.
• If the UNSIGNED attribute for a real number is set, it prevents storing negative
values in the column but does not affect the range of acceptable values.
• If the ZEROFILL attribute for a real number is set, the number is displayed with
zeros padded from the left, and the UNSIGNED attribute is automatically set.
• The DEC, NUMERIC, and FIXED types are synonyms for the DECIMAL type.
• The REAL and DOUBLE PRECISION types are synonyms for the DOUBLE type.
Description
• A column of TIMESTAMP type is auton1atically updated to the current date and
time when a row is inserted or updated. If a table bas multiple TIMESTAMP
columns, only the first one is updated automatically.
• The TIMESTAMP type can only store dates up to the year 2038. This is known
as the year 2038 problem, the Y2K38 problem, and the Unix Millenn.ium bug. To
fix this problem, use the DATETIME type instead of the TIMESTAMP type and
update the value manually as needed.
• MySQL 5.7 .5 and later support only 4-digit years, which can be defmed as YEAR
and YEAR(4). I-digit and 2-digit years can still be entered but are converted to
4-digit years. Values from Oto 69 are converted to 2000 to 2069, and values from
70 to 99 are converted to 1970 to 1999.
• For a value of O or 00 to be stored as 2000 in a YEAR column, you 1nust enter it as
a string. Otherwise, it's stored as 0000.
When you work with the date and time types, you need to know how to code
date and time literals. Part 2 of figure 8-5 shows how to do that. The default date
fo1mat for MySQL is ''yyyy-mm-dd'', which is why we've used this forn1at in
most of the examples in this book. By default, MySQL doesn 't support other
common date formats such as ''m.m/dd/yy''. If you attempt to use an unsupported
format, MySQL returns an error.
You also need to be aware of the two-digit year cutoff that's defined on your
system. When you code a two-digit year, the two-digit year cutoff determines
bow MySQL interprets the year. By default, MySQL interprets the years 00
through 69 as 2000 through 2069, and it interprets the years 70 through 99 as
1970 through 1999. Usually, that's what you want. However, the two-digit year
cutoff can be modified if necessary. In general, it's considered a good coding
practice to use four-digit years. That way, you can be sure that MySQL is
interpreting the year correctly.
MySQL interprets any punctuation character in a literal as a delimiter
between date parts or time parts. If you don't use any delimiters, you can code
the value as a numeric literal. In that case, you don't need to use single quotes.
When storing a date in a DATE column, the values are loosely checked for
valid data. For instance, months must be in the range 0-12 and days must be
in the range 0-31. For illegal dates, such as February 31, MySQL returns an
error. However, MySQL allows you to store unconventional date values, such as
''2018-12-00'', which represents a month and year without a specific day.
The default time format for MySQL is ''hh:mm: ss'', using a 24-hour clock.
Many of the same rules for coding date literals also apply to time literals. For
instance, you can use any punctuation character as a delimiter. Similarly, for
valid values, you can omit the delimiters. In that case, you can use a numeric
literal (no quotes) instead of a string literal (quotes). Finally, MySQL checks
times for validity. For illegal times, such as ''19:61:11'', MySQL returns an error.
The default date/time format for MySQL is a combination of the date and
time formats. Most of the rules for coding date/time literals ru·e a combination
of the rules for coding date and time literals. In addition, if you don't specify
a time when storing a TIMESTAMP or DATETIME value, the tim.e defaults to
00:00:00, which is midnight.
Clzapter 8 How to work with data types 243
Description
• You can specify date and time values by coding a literal value. In most cases, you
enclose the literal value in single quotes.
• For dates, MySQL uses the ''yyyy-mm-dd'' format. For times, MySQL uses the
''hh:mm:ss'' format, using a 24-hot1r clock.
• By default, MySQL does not support common date formats used by other systems
such as ''mm/dd/yy'' and ''mon/dd/yyyy''.
• By default, MySQL interprets 2-digit years from 00 to 69 as 2000 to 2069 and the
years from 70 to 99 as 1970 to 1999.
• MySQL interprets any punctuation character as a delimiter between date parts. If you
don't use any delimiters, you can code the value as a numeric literal without quotes.
• If you don' t specify a time when storiI1g a DATETIME or TIMESTAMP value,
MySQL stores a time value of 00:00:00 (12:00 midnight).
• If you don 't specify seconds when storing a TIME value, MySQL stores 00 for the
seconds.
• When storing date and time values, MySQL loosely checks the values to make sure they
are valid. For example, months must be in the range 0-12, days must be in the range
0-31, and so on. If MySQL determines that a date or time isn't valid, it returns an error.
• MySQL 5.5 and later are stricter than previous versions of MySQL for storing date
and time values. If MySQL can' t interpret a value, it returns an error or a warning.
Description
• The ENUM and SET types can be used to restrict the values that you store to a
li1nited set of values. Tl1e ENUM column can take on exactly one value, but a SET
colt1mn can take on zero, one, or up to 64 different values.
• You can defme the set of acceptable values for an ENUM or SET column when you
create a table. An ENUM column can have up to 65,535 acceptable values, but a
SET column is limited to 64 acceptable values.
• To specify a value for· an ENUM column, you code a single text string. If the string
contains an acceptable value, that value is stored in the column. Otherwise, the
column is assigned an empty string.
• If you don 't specify a value for an ENUM column when you insert a row, MySQL
assigns a default value that depends on whether the column allows null values. If
the column allows null values, MySQL assigns a null value to the column. If it
doesn't allow null values, MySQL assigns the first value in the set of acceptable
values to the column.
• To specify values for a SET column, you code a single string with the values
separated by commas. Each acceptable value is stored in the column, and any other
values are ignored.
• When you store values in a SET column, MySQL stores the values using the order
specified in the column definition, and it does not store duplicate values.
Description
• The BLOB types store strings of binary data and are referred to as binary large
object (BLOB) types.
• The TEXT types store strings of character data and are sometimes referred to as
character large object (CLOE) types.
SELECT statements that implicitly convert data from one type to another
Number to string
SELECT invoice_ total, CONCAT{'$', invoice_ total)
FROM invoices
invoice_total CONCATCs', invoice_total)
- -
► 3813.33 53813.33
'10.20 s-10.20
I138.75 S138.75
String to number
SELECT invoice_r.n1mh,=ir, 989319 / invoice_ n11mher
FROM invoices
invoice_number 989 319/tnvoice _number
,..
► 989319-457 1
- L
263253241 0.0037580505988908225
1963253234 0.001027060138580 3393
Date to number
SELECT invoice_ date, invoice date+ 1
FROM invoices
.
-
►
invoice_date
2018-08-02
invoice_date
20180803
+1
2018-08-01 20180802
2018-07-31 20180732
Description
• When MySQL automatically converts one data type to another, it's known as an
implicit conversion.
• If you code an expression that involves values with different data types, MySQL
implicitly converts them when it evaluates the expression.
• If you use a string in a numeric expression, MySQL attempts to convert the string
to a nt1mber before evaluating the expression. If the string starts with a letter
or special character, MySQL returns a value of zero. If it starts with a number,
MySQL returns that number and each successive number until it encot1nters a letter
or special character.
• If you add or subtract an integer to or from a DATE value, MySQL implicitly
converts the DATE value to an integer value.
The cast types you can use in the CAST and CONVERT functions
Cast type Description
CHAR [ (N)] A string of characters where N is the maximu1n number of characters.
DATE A DATE value.
DATETIME A DATETIME value.
TIME A TIME value.
SIGNED [ INTEGER] A signed INT value. The INTEGER keyword is optional.
UNSIGNED [INTEGER] An unsigned INT value. The INTEGER keyword is optional.
DECIMAL [ (M [, D] ) l A DECIMAL value where M specifies the precision and D specifies
the scale.
Description
• You can use the CAST or CONVERT function to perform an explicit conversion.
This allows you to convert, or cast, an expression from one data type to another.
• CAST is an ANSI-standard function and is used more frequently than CONVERT.
Figure 8-9 How to convert data using the CAST and CONVERT functions
252 Section 2 More SQL skills cts you need them
us Postal Service
Attn: Supt. Window Services
Madison, WI 53707
Description
• The CHAR function is typically used to insert control characters into a character
string.
Figure 8-10 How to convert data using the FORMAT and CHAR functions
254 Section 2 More SQL skills cts you need them
Perspective
In this chapter, you learned about the different MySQL data types. In
addition, you learned how to use some functions to convert data from one type
to another. In the next chapter, you'll learn some of the additional functions for
working with data.
Terms
data type latin I character set
character data types integer types
string fixed-point number
text scale
• •
numeric data types prec1s1on
integer floating-point number
real number significant digits
date and time data types single-precision number
date/time data types double-precision number
temporal data types scientific notation
large object (LOB) data types exact numeric types
spatial data types approximate numeric types
global positioning system (GPS) year 203 8 problem
geometry types Y2K38 problem
JSON data type Unix Millennium bug
JavaScript Object Notation (JSON) BLOB (Binary Large Object)
fixed-length string character large object (CLOB)
variable-length string implicit conversion
utf8mb4 character set explicit conversion
multiple-byte character set cast
Unicode standard ASCII (American Standard
utf8mb3 character set Code for Infor1nation
single-byte character set Interchange)
Clzapter 8 How to work with data types 255
Exercises
1. Write a SELECT statement that returns these columns from the Invoices
table:
The invoice- total column
A column that t1ses the FORMAT function to return the invoice total
column with 1 digit to the right of the decimal point
A column that uses the CONVERT function to return the invoice total
column as an integer
A column that uses the CAST function to return the invoice total column
as an integer
2. Write a SELECT statement that returns these columns from the Invoices
table:
The invoice- date column
A column that uses the CAST function to return the invoice_date column
with its full date and time
A column that uses the CAST function to return the invoice- date column
with just the year and the month
How to use functions
In chapter 3, you we1·e introduced to some of the scalar functions that you
can use in a SELECT statement. Now, this chapter expands on that coverage
by presenting many more of the scalru: functions, as well as some specialized
window functions. When you complete this chapter, you' ll have a thorough
understanding of the functions that you can use with MySQL.
LOCATE('SQL', I MySQL') 5
LOCATE ( ' - ' , 1
( 5 5 9 ) 5 5 5 -1212 1
) 10
► 1 Lizbeth Darien
17 Lance Pinos-Potter
2 Darnell O'Sullivan
20 Jean Paut Renard
3 Alisha von Strump
Sorted by the emp_id column after it has been padded with leading zeros
SELECT LPAD(emp_ id, 2, '0') AS emp_ id, emp_ name
FROM string_ sample
ORDER BY emp_ id
emp_id emp_name
-
► 01 Uibeth Darien
-
02 Darnen O'SUUivan
03 Atisha von Strump
17 l ance Pinos-Pott.er
20 Jean Paul Renard
Description
• The emp_id column in the String_Sarnple table used i11 the examples above is
defined with the type VARCHAR(3). However, this column contains numeric
values.
Description
• If a string consists of two or more components, you can parse it into its individual
components. To do that, you can use the SUBSTRING_INDEX, SUBSTRING, and
LOCATE functions.
CEILING ( 12.5 ) 13
CEILING ( -12.5 ) -12
FLOOR(-12.5 ) - 13
FLOOR ( 12.5 ) 12
ABS ( -1. 2 5) 1. 2 5
ABS ( l.25 ) 1. 2 5
SIGN ( -1.25 ) -1
SIGN ( l.25 ) 1
RAND () 0 . 2444132019248
Note
• If an error occurs, each of the numeric functions returns a null value.
6 24.04849
...
-
.I
A search for an exact value that doesn't include two approximate values
SELECT*
FROM float _ sample
WHERE float_ value = 1
I float_id float_value
► r2 1
- -
float id float_value
-
1
► 0.999999999999999
2 1
3 LOOOOOOOOOOOOOO 1
► 1 0. 999999999999999
2 1
3 1.00000000000000 l
Description
• Becat1se floating-point values are approximate, you'll want to search for approximate
values when working with floating-point data types such as the DOUBLE and FLOAT
types.
Examples
Function Result
NOW() 2018-12-06 14:12:04
SYSDATE() 2018-12-06 14:12:04
CURDATE() 2018-12-06
CURTIME() 14:12:04
Description
• Parentheses are required after the NOW, SYSDATE, CURDATE, and CURTIME
functions.
• Parentheses are optional after the UTC_DATE, UTC_TIME,
CURRENT_TIMESTAMP, CURRENT_DATE, and CURRENT_TIME functions.
Examples
Function Result
DAYOFMONTH('2018- 12 - 03') 3
MONTH('2018-12-03') 12
YEAR ( '2018 - 12 - 03') 2018
HOUR ( 'll:35:00') 11
MINUTE('ll:35:00') 35
SECOND ( 'll:35:00') 0
DAYOFWEEK ( '2018-12-03' ) 2
QUARTER ( '2018-12-03') 4
DAYOFYEAR('2018-12-03') 337
WEEK ( '2018-12-03') 48
LAST_ DAY('2018-12-03' ) 31
DAYNAME('2018-12-03') Monday
MONTHNAME('2018-12-03 ' ) December
Description
• The argument for the date functions can be either a DATE value or a DATETIME
value.
• The argument for the time functions can be either a TIME value or a DATETIME
value.
Figure 9-8 How to parse dates and times with date/time functions
274 Section 2 More SQL skills cts you need them
Date/time units
Unit Description
SECOND Seconds
MINUTE Minutes
HOUR Hours
DAY Day
MONTH Month
YEAR Year
MINUTE_ SECOND Minutes and seconds
HOUR_ Ml:NUTE Hour and minutes
DAY_ HOUR Day and hours
YEAR_ MONTH Year and mo11th
HOUR_ SECOND Hours, min·utes, and seconds
DAY_ MINUTE Day, hours, and minutes
DAY_ SECOND Day, hours, minutes, and seconds
Figure 9-9 How to parse dates and times with the EXTRACT function
276 Section 2 More SQL skills cts you need them
Examples
Function Result
DATE_ FORMAT('2018-12-03', •~om/9--od /%y') 08/03 / 18
DATE_ FORMAT('2018-12-03', %Y') Monday, December 3rd, 2018
DATE_ FORMAT('2018-12-03', I %e-9--ob-%y t ) 3-Dec-18
DATE_ FORMAT('2018-12-03 16:45', ' %r') 04:45:00 PM
TIME_ FORMAT('16:45', 1
%r 1
) 04:45:00 PM
TIME_ FORMAT('l6:45', ' %1: %i %p') 4:45 PM
Examples
Function Result
DATE_ ADD('2018-12-31', INTERVAL 1 DAY} 2019-01-01
DATE_ ADD('2018-12-31', INTERVAL 3 MONTH} 2019-03-31
DATE_ ADD('2018-12-31 23:59:59', INTERVAL 1 SECOND) 2019-01-01 00:00:00
DATE_ ADD('2019-01-01', INTERVAL -1 DAY) 2018-12-31
DATE_ SUB('2019-01-01', INTERVAL 1 DAY) 2018-12-31
DATE_ ADD('2016-02-29', INTERVAL 1 YEAR) 2017-02-28
DATE_ ADD('2018-02-29', INTERVAL 1 YEAR) NULL
DATE_ ADD('2018-12-31 12:00', INTERVAL '2 12' DAY_ HOUR) 2019-01-03 00:00:00
DATEDIFF('2018-12-30', '2018-12-03') 27
DATEDIFF('2018-12-30 23:59:59', 1
2018-12-03') 27
DATEDIFF('2018-12-03', '2018-12-30') -27
Description
• If the expression you specify in the DATE_ADD function is a negative integer, the
interval is subtracted from the date.
• If the expression you specify in the DATE_SUB function is a negative integer, the
interval is added to the date.
6 2019-03-0109:02:25
...
-
.I
Description
• You can search for a date in a DATETIME column by searching for a range of
dates, by using functions to specify the month, day, and year of the date, or by
searching for a formatted date. Of these techniques, searching for a range of dates
is the most efficient.
Description
• You can search for a ti1ne in a DATETIME column without specifying a date by
using date/time functions to get the time part of the DATETIME value. Then, you
can use the time parts in your WHERE clause.
2018-08·11 2018-08·11
2018-08· 11
20 18-08·11
No Payment
2018-08·11
•
V
I
Description
• The IF function lets you test an expression and return one value if the expression is
true and another value if the expression is false.
• The IFNULL and COALESCE functions let you substitute non-null values for null
values.
• The IFNULL function returns the first expression if it isn' t null. Otherwise, it
returns the replacement value you specify.
• The COALESCE function returns the first expression in the list that isn't null. If all
of the expressions are nL1ll, this function returns a null value.
Figure 9-1 5 How to use the IF, IFNULL, and COALESCE functions
288 Section 2 More SQL skills cts you need them
Description
• The regular expression functions use a string pattern to search a string expression . These
patterns can use special characters and constructs, which are case-insensitive by default.
To help you understand how you can use the regular expression functions
in SQL statements, part 2 of figure 9-16 presents three SELECT statements that
use them. The first example uses the REGEXP_INSTR function in the SELECT
clause to return the index of the first space in the vendor_city column. The same
REGEXP_INSTR function is also used in the WHERE clause so only the cities
that have a space in their names are included in the result set.
The second example uses the REGEXP_SUBSTR function in the SELECT
clause to get the substring ''San'' or ''Los'' that appears at the beginning of the
vendor_city column. Then, it uses the same function in the WHERE clause so
if the function returns a null value, the row isn't included in the result. In other
words, only the cities that start with ''San'' or ''Los'' are included.
The third example uses the REGEXP_REPLACE function in the SELECT
clause to replace the value ''Street'' that occt1rs anywhere in the vendor_address I
column with the value ''St''. Note that because patterns are case-insensitive by
default, the pattern STREET will match both uppercase and lowercase letters
as shown here. This example also uses the REGEXP_LIKE function in the
WHERE clause so only vendors with a vendor_address l column that contains
the pattern are included in the result set. As you saw in chapter 3, this WHERE
clause can also be coded using the REGEXP operator like this:
WHERE vendor addressl REGEXP 'STREET'
Although these examples are relatively simple, they should give you an idea
of what you can do with the regular expression functions. For more information
on these functions and the special characters and constructs you can use with
them, see the documentation for MySQL.
Chapter 9 How to use functions 291
( 17 rows)
(12 rows)
( 4 rows)
Description
• The REGEXP_LIKE function works just like the REGEXP operator that you
learned about in chapter 3.
• The REGEXP_REPLACE function replaces the occurrences of the regular expres-
sion pattern only in the result set. The database table re1nains unchanged.
Description
• The ROW_NUMBER, RANK, DENSE_RANK, and NTILE functions were
introduced with MySQL 8.0. They are sometimes referred to as ranking
functions.
• The ORDER BY clause determines the sequence of the rows within the
partitions.
• The optional PARTITION BY clause specifies the column that's used to divide
the result set into groups called partitions.
• The ROW_NUMBER function returns the number of the current row within its
partition, starting at 1 for the first row in each partition.
The first example in part 2 of figure 9-17 shows how the RANK and
DENSE_RANK functions work. You can use these functions to rank the rows in
a result set. In this example, both the RANK and the DENSE_RANK functions
sort all invoices in the Invoices table by the invoice_total column. Since the
first three rows have the same invoice total, both of these functions give these
three rows the same rank, 1. However, the fourth row has a different value. To
calculate the value for this row, the RANK function adds 1 to the total number
of previous rows. In other words, since the frrst three rows are tied for first place,
the fourth row gets fourth place and is assigned a rank of 4.
The DENSE_RANK function, on the other hand, calculates the value for the
fotuth row by adding 1 to the rank for the previous row. As a result, this function
assigns a rank of 2 to the fourth row. In other words, since the first three rows are
tied for first place, the fourth row gets second place.
The second example shows how the NTILE function works. You can use
this function to divide the rows in a pattition into the specified number of
groups. When the rows can be evenly divided into groups, this function is easy
to understand. For example, if a result set returns 100 rows, you can use the
NTILE function to divide this result set into 10 groups of 10. However, when the
rows can't be evenly divided into groups, this function is a little more difficult to
understand.
In this figure, for example, the NTILE function is used to divide a result set
that contains 5 rows. Here, the first NTILE function divides this result set into
2 groups with the first having 3 rows and the second having 2 rows. The second
NTILE function divides this result set into 3 groups with the first having 2 rows,
the second having 2 rows, and the third having 1 row. And so on. Although this
doesn't result in groups with even numbers of rows, the N'l'ILE function creates
the number of groups specified by its argument.
In this figure, the examples for the RANK, DENSE_RANK, and NTILE
functions don't include PARTITION BY clauses. As a result, these functions
are applied to the entire result set. However, whenever necessary, you can use
the PARTITION BY clause to divide the result set into groups as shown by the
second example for the ROW_NUMBER function.
Although it's not shown here, you should know that you can also code a
frame clause on the OVER clause for any of the ranking ft1nctions. However,
you're not likely to do that. If you haven't already read chapter 6 and you want to
learn more about how frames work with window functions, though, you can refer
back to that chapter.
Chapter 9 How to use functions 295
Description
• The RANK and DENSE_RANK functions both return the rank of each row within
the partition of a result set.
• If there is a tie, both of these function s give the same rank to all rows that are tied.
• To determjne the rank for the next distinct row, the RANK function adds 1 to the
total number of rows, while the DENSE_RANK function adds 1 to the rank for the
.
previous row.
Description
• The NTILE function divides the rows in a partition into the specified number of
groups and returns the group number of each row.
• If the rows can' t be evenly divided into groups, the later groups may have one less
row than the earlier groups.
► 2016 Jonathon lhomas 1274856.38 Jonathon Thomas Andrew Markasian Sonja Martinez
2016 Andrew Markasian 1032875.48 Jonathon lhomas Andrew Markasian Sonja Martinez
2016 Sonja Martinez 978'165.99 Jonathon lhomas Andrew Markasian Sonja Martinez
2017 AndrewMarkasian 1132744.56 Andrew Markasian Sonja Martinez Lydia Kramer
2017 Sonja Martinez 974853.81 Andrew Markaslan Sonja Martinez Lydia Kramer
2017 Jonathon Thomas 9237'16.85 Andrew Markasian Sonja Martinez Lydla Kramer
2017 Phillip Winters 655786.92 Andrew Markasian Sonja Martinez Lydia Kramer
2017 Lydia Kramer 422847,86 Andrew Markasian Sonja Martinez Lydia Kramer
2018 Jonathon Thomas 998337.46 Jonathon Thomas Sonja Martinez Lydia Kramer
2018 Sonja Martinez 887695.75 Jonathon Thomas Sonja Martinez Lydia Kr-amer
2018 Phiffip Winters n443.37 Jonathon lhomas Sonja Martinez Lydia Kramer
2018 Lydia Kramer 45182.44 Jonathon lhomas Sonja Martinez Lydia Kramer
Description
• The FIRST_ VALUE, LAST_ VALUE, NTH VALUE, LEAD, LAG, PERCENT_RANK,
and CUME_DIST functions are sometimes referred to as analytic functions. They were
introduced with MySQL 8.0.
• The FIRST_VALUE, LAST_VALUE, and NTH_VALUE functions return the first,
last, and nth value in a sorted set of values. When you use the PARTITION BY
clause with LAST_VALUE or NTH_VALUE, you typically include the ROWS or
RANGE clause as well to defme a subset of the current partition.
The LEAD and LAG functions let you refer to values in other rows of the
result set. The LAG function is illustrated by the first exa1nple in part 2 of figure
9-18. Here, the OVER clause is used to group the result set by the rep_id column
and sort it by the sales_year column. Then, the LAG function in the fourth
column gets the sales total from one row prior to the current row (the offset).
Since the rows are sorted by year for each sales rep, that means that the function
retrieves the sales rep's sales for the previous year. The ftfth column uses the
same function, but it subtracts the result of this function from the current sales to
show the change in sales from the previous year. The LEAD function is similar,
but it lets you refer to values in fo]Jowing rows rather than previous rows.
Notice that the value of the LAG function for the first row for each sales rep
is 0.00. That's because there isn't a row for the prior year. By default, this value
is null. Because I wanted to calculate the change for each row in the result set,
though, I used the third argument of the LAG function to set the default to 0.
The second example shows how to use the PERCENT_RANK and
CUME_DIST functions. Both of these functions groups the rows by year and
sorts them by sales total in ascending sequence.
The PERCENT_RANK function calculates a percent that indicates the
rank of each row within a partition. The result of this function is always a value
between O and 1. If you study the results in this example, you shouldn' t have any
trouble understanding bow this function works.
The CUME_DIST function is similar, but it calculates the percent of values
that are less than or equal to the current value. This function represents the
cumulative distribution of the values. The cumulative distribution is calculated
by dividing the number of rows with the current value or a lower value by the
total number of rows in the partition.
Chapter 9 How to use functions 299
A query that uses the PERCENT_ RANK and CUME_ DIST functions
SELECT sales_year, rep_ id, sales_ total,
PERCENT_ RANK() OVER (PARTITION BY sales_year ORDER BY sales_ total)
AS pct_ rank,
CUME_ DIST ( ) OVE.R ( PARTITION BY sales_year ORDER BY sales total)
AS 'cume_ dist'
FROM sales_ totals
sales_year rep_ld sales_total pct_rank a.une_dist
► 2016 2 978465.99 0 0.3333333333333333
2016 3 1032875.'iS 0.5 o.--- -- -- ·---
2016 1 127'18 56. 38 1 1
2017 5 422847.86 0 0. 2
2017 4 655786.92 0.25 0.4
2017 l 923746.85 0. 5 0.6 l
2017 2 974853.81 0 .75 0.8 l
2017 3 1132.744.56 1 1 '
Description
• The LEAD function retrieves data from a following row in a result set, and the
LAG function retrieves data from a previous row in a result set.
• The PERCENT_RANK function calculates the rank of the values in a sorted set of
values as a percent. The CUME_DIST ft1nction calculates the percent of the values
in a sorted set of values that are less than or equal to the current value.
Perspective
In this chapter, you learned about the different functions that you can use
to operate on M ySQL data. At this point, you have all of the skills you need to
develop SQL code at a professional level.
However, there's a lot more to learn about MySQL. In the next section of
this book, then, you'll learn the basic skills for designing a database. Even if you
never need to design your own database, understanding this material will help
you work more efficiently with databases that have been designed by others.
Terms
string pattern
regular expression
regular expression functions
specialized window functions
ranking functions
partition
analytic functions
cumulative distribution
Exercises
1. Write a SELECT staten1ent that returns these columns from the Invoices table:
The invoice total column
A column that uses the ROUND function to return the invoice total
column with 1 decimal digit
A column that uses the ROUND function to return the invoice_total
column with no decimal digits
A column that uses the TRUNCATE function to return the invoice_total
column with no decimal digits
2. Write a SELECT statement that returns these columns from the Date_Sample
table in the EX database:
The start_date column
A column that uses the DATE_FORMAT function to return the start_date
column with its month name abbreviated and its month, day, and two-digit
year separated by slashes
A column that uses the DATE- FORMAT function to return the start- date
column with its month and day returned as integers with no leading zeros, a
two-digit year, and all date parts separated by slashes
A column that uses the DATE_FORMAT function to return the start_date
column with only the hours and minutes on a 12-hour clock with an am/pm
indicator
Chapter 9 How to use functions 301
3. Write a SELECT statement that returns these columns from the Vendors table:
The vendor name column
The vendor_name column in all capital letters
The vendor_phone column
A column that displays the last four digits of each phone number
When you get that working right, add the columns that follow to the result set.
This is more difficult because these columns require the use of functions within
functions.
The vendor_phone column with the parts of the number separated by dots,
as in 555.555.5555
A column that displays the second word in each vendor name if there is one
and blanks if there isn't
4. Write a SELECT statement that retUI·ns these columns from the Invoices table:
The invoice- number column
The invoice date column
The invoice_date column plus 30 days
The payment_date column
A colt1mn named days_to_pay that shows the number of days between the
invoice date and the payment date
The number of the invoice date's month
The four-digit year of the invoice date
When you have this working, add a WHERE clause that retrieves just the
invoices for the month of May based on the invoice date, not the number of
the invoice month.
5. Write a SELECT statement that returns these columns from the String_Sample
table of the EX database:
The emp_name column
A column that displays each employee's first name
A column that displays each employee's last name
Use regular expression functions to get the first and last name. If a name
contains three parts, everything after the first part should be considered part of
the last name. Be sure to provide for last names with hypens and apostrophes.
Hint: To include an apostrophe in a pattern, you can code a\ in front of it or
you can enclose the pattern in double quotes.
6. Write a SELECT statement that returns these columns from the Invoice table
of the AP database:
The invoice- number column
The balance due for each invoice with a balance due greater than zero
A column that uses the RANK() function to rank the balance due in
descending sequence
Database design
and implementation
For large applications, a developer who specializes in database design
may be responsible for designing and creating the databases that are
used by production applications. This developer may also be responsible
for designing and creating the databases that are used for testing those
applications. Then, a database administrator (DBA) may be responsible for
maintaining these databases. For smaller applications, programmers are
often asked to fill one or both of these roles. In other words, programmers
often need to design, create, and maintain the databases that are used for
testing and production.
So, whether you 're a database designer, a database administrator, or
a SQL programmer, you need the skills and knowledge presented in this
section. That's true even if you aren't ever called upon to design, create, or
maintain a database. By understanding what's going on behind the scenes,
you'll be able to use SQL more effectively.
In chapter 10, you'll learn how to design a database. In chapter 11,
you'll learn how to use the Data Definition Language (DDL) statements to
create and maintain databases, tables, and indexes. Finally, in chapter 12,
you '11 leam how to create and maintain views, which are database objects
that provide another way to look at tables.
How to design a database
In this chapter, you'll learn how to design a new database. This is useful
information whether or not you ever design a database on your own. To illus-
trate this process, I' ll use the accounts payable (AP) database that you've seen
throughout this book.
People
Documents
Columns
Facilities
--=.,......■
; ■••·
Other ~--··
·••r-
systems
·-·
--
The six basic steps for designing a data structure
Step 1: Identify the data elements
Step 2: Subdivide each element into its smallest useful components
Step 3: Identify the tables and assign column.s
Step 4: Identify the primary and foreign keys
Step 5: Review whether the data structure is normalized
Step 6: Identify the indexes
Description
• A relational database system should model the real-world environment where it's
used. The job of the designer is to analyze the real-world system and then map it
onto a relational database system.
• A table in a relational database typically represents an object, or entity, in the real
world. Each column of a table is used to store an attribute associated with the
entity, and each row represents one instance of the entity.
• To model a database and the relationships between its tables after a real-world
system, you can use a technique called entity-relationship (ER) modeling. Some of
the diagrams you'll see in this chapter apply the basic elements of ER modeling.
Description
• Depending on the nature of the system, you can identify data elements in a variety
of ways, including interviewing users, analyzing existing systems, and evaluating
comparable system s.
• The documents used by a real-world system, such as the invoice shown above, can
often help you identify the data elements of the system.
• As you identify the data elements of a system, you should begin thinking about
the entities that those elements are associated with. That will help you identify the
tables of the database later on.
Vendor sales contact first name Vendor sales contact last name
Ruben Goldberg
An address that's divided into street address, city, state, and zip code
Vendor address
1234 West Industrial Way, East Los Angeles, California 90022
Description
• If a data element contains two or more components, you should consider subdi-
viding the element into those components. That way, you won't need to parse the
element each time you use it.
• The extent to which you subdivide a data element depends on how it will be used.
Because it's difficult to predict all future uses for the data, most designers subdivide
data elements as much as possible.
• When you subdivide a data ele1nent, you can easily rebuild it when necessary by
concatenating the individt1al components.
Description
• After you identify and subdivide all of the data elements for a database, you should
group them by the entities with which they 're associated. These entities will later
become the tables of the database, and the elements will become the columns.
• If a data element relates to more than one entity, you can include it under all of the
entities it relates to. Then, when you normalize the database, you may be able to
remove the duplicate elements.
• As you assign the elements to entities, you should omit elements that aren't needed,
and you should add any additional elements that are needed.
Description
• Each table should have a primary key that uniquely identifies each row. If possible,
you should use an existing column for the primary key.
• The values of the primary keys should seldom, if ever, change. The values should
also be short and easy to enter correctly.
• If a suitable column doesn 't exist for a p1imary key, you can create an ID column
that is incremented by one for each new row as the primary key.
• If two tables have a one-to-many relationship, you may need to add a foreign key
column to the table on the ''many'' side. The foreign key column must have the
same data type as the primary key colum11 it's related to.
• If two tables have a many-to-many relationship, you'll need to define a linking
table to relate them. Then, each of the tables in the many-to-many relationship will
have a one-to-many relationship with the linking table. The linking table doesn't
usually have a primary key.
• If two tables have a one-to-one relationship, they should be related by their primary
keys. This type of relationship is typically used to improve performance. Then,
columns with large amounts of data can be stored in a separate table.
The third example in figure 10-5 illustrates two tables that have a one-to-one
relationship. With this type of relationship, both tables have the same primary
key, which 1neans that the information could be stored in a single table. This
type of relationship is often used when a table contains one or more columns
with large amounts of data. In this case, the Employee_Photos table contains a
large binary column with a photo of each employee. Because this column is used
infrequently, storing it in a separate table will make operations on the Employees
table more efficient. Then, when this column is needed, it can be combined with
the columns in the Employees table using a join.
Description
• Referential integrity means that the relationships between tables are maintained
correctly. That means that a table with a foreign key doesn't have rows with foreign
key values that don' t have matching primary key values in the related table.
• In MySQL, you can enforce referential integrity by using declarative referential
integrity.
• To use declarative t·eferential integrity (DRI), you define foreign key constraints.
You 'll learn how to do that in the next chapter.
• When you define foreign key constraints, you can specify how referential integrity
is enforced when a row is deleted from the primary key table. The options are
to return an error, to delete the related rows in the foreign key table, or to set the
foreign key values in the related rows to null.
• If referential integrity isn't enforced and a row is deleted from the primary key
table that has related rows in the foreign key table, the rows in the foreign key table
are said to be orphaned.
Description
• Normalization is a formal process you can use to separate the data in a data struc-
ture into related tables. Normalization reduces data redundancy, which can cause
storage and maintenance problems.
• In an unnormalized data structure, a table can contain information about two or
more entities. It can also contain repeating columns, columns that contain repeating
values, and data that's repeated in two or more rows.
• In a normalized data structure, each table contains information about a single
entity, and each piece of inforrnation is stored in exactly one place.
• To normalize a data structure, you apply the normal forms in sequence. Although
there are a total of seven normal forms, a data structure is typically considered
normalized if the first three nor1nal forms are applied.
Description
• MySQL automatically creates an index for primary and foreign keys.
• An index provides a way for a database management system to locate information
more quickly. When it uses an index, the database management syste1n can go
directly to a specific row rather than having to search through all the rows until it
finds it.
• Indexes speed performance when searching and joining tables.
• You can create composite indexes that include two or more columns. You should
use this type of index when the columns in the index are updated infrequently or
when the index covers almost every search condition on the table.
• Because indexes must be updated each time you add, update, or delete a row, you
shouldn 't create more indexes than you need.
Description
• Each normal form assumes that the design is already in the previous normal form.
• A database is typically considered to be normalized if it is in third nor1nal form.
The other four forms are not commonly used and are not covered in detail in this
book.
Figure 10-9 also lists the benefits of normalizing a data structure. To summa-
rize, no1malization produces smaller, more efficient tables. In addition, it reduces
data redundancy, which makes the data easier to maintain and reduces the
amount of storage needed for the database. Because of these benefits, you should
always consider normalizing your data structures.
You should also be aware that the subject of normalization is a contentious
one in the database community. In the academic study of computer science,
normalization is considered a form of design perfection that should always be
strived for. In practice, though, database designers and DBAs tend to use normal-
ization as a flexible design guideline.
Description
• For a table to be in first normal for1n, its columns must not contain repeating
values. Instead, each column must contain a single, scalar value. In addition, the
table must not contain repeating columns that represent a set of values.
• A table in first normal form often bas repeating valt1es in its rows. This can be
resolved by applying the second normal form.
► 1
'
invoice_id
1
•
inv01ce _sequence item_description
Android ad
1 2 MySQLad
1 3 Library directcry
2 1 catalogs
2 2 MySQL flyer
3 1 Card revision
.,
Description
• For a table to be in second nonnal form, every non-key column must depend on the
entire primary key. If a column doesn't depend on the entire key, it indicates that
the table contains information for more than one entity. This can happen if the table
contains a composite primary key.
• To apply second normal form, you move columns that don' t depend on the entire
primaiy key to another table and then establish a relationship between the two
tables.
• Second normal form helps remove redundant row data, which can save storage
space, make maintenance easier, and reduce the chance of storing inconsistent data.
term s id
terms_description
terms_due_days
Description
• For a table to be in third normal form, every non-key column must depend only on
the primary key.
• If a column doesn't depend only on the primary key, it implies that the colu1nn is
assigned to the wrong table or that it can be computed from other columns in the
table. A column that can be computed from other columns contains derived data.
and keep just the line_item_amount column. That's what I did in the data struc-
ture shown in this figure. The solution you choose, however, depends on how the
data will be used .
In contrast, although the invoice_due_date column could be calculated from
the invoice_date column in the Invoices table and the terms_due_days column
in the related row of the Terms table, the system also allows this date to be
overridden. Because of that, the invoice_due_date column should not be omitted.
If the system didn' t allow this value to be overridden, however, this column
could be safely omitted.
zip_codes
general_ledger_accounts
zip_codes
city accou nt - no
state account_ description
' terms
area codes
- terms- id
area code id
-
area code
- terms_description
- terms_due_d ays
When to denormalize
• When a column from a joined table is used repeatedly in search criteria, you should
consider moving that column to the primary key table if it will eliminate the need
for a join.
• If a table is updated infrequently, you should consider denormalizing it to improve
efficiency. Because the data remains relatively constant, you don' t have to worry
about data redundancy errors once the initial data is entered and verified.
• Incl11de columns with derived values when those values are used frequently in
search conditions. If yo11 do that, you need to be sure that the column value is
always synchronized with the value of the columns it's derived from.
Description
• Data structures that are normalized to the fourth normal form and beyond typically
require more joins than tables normalized to the third normal fo1m and can there-
fore be less efficient.
• MySQL statements that work with tables that are normalized to the fourth normal
for111 and beyond are typically more difficult to code and debug.
• Most designers denormalize data structures to some extent, usually to the third
normal form.
• Denormalization can result in larger tables, redundant data, and reduced
performance.
• Only denormalize when necessary. It is better to adhere to the normal fonns unless
it is clear that perfor111ance will be improved by deno1m alizing.
Models 0@ 0
om ap
c::I C;\mur~ch\mysql c::l C:\mu~ch\mysql
_ om - ap
- 12 Dec 18, 12:28 - 12 Dec 18, 10:48
Description
• MySQL Workbench allows you to create an enhanced entity-relationship 1nodel
(EER niodel). This type of model extends the original entity-relationship model (ER
model).
• Once you have created or opened an EER model, you can work with one or 1nore
EER diagrams· that are associated with that model.
• To open a recently used existing EER model, click on the model in the list of
models.
• To open any EER model, click the@) icon to the right of the Models heading, or
select the File ➔ Open Model item. Then, use the resulting dialog box to select the
file for the model.
• To create a new EER model that's blank, click the ® icon to the right of the Models
heading, or select the File ➔ New Model item.
• To create an EER model from an existing database, click the 0 icon to the right of
the Models heading, select the ''Create EER Model fi·om Database'' item, and use
the resulting dialog boxes to connect to the server and select the database.
• To create an EER model from a SQL creation script, click the 0 icon to the right of
the Models heading, select the ''Create EER Model from Script'' item, and use the
resulting dialog box to select the script file.
• To remove an existing model from the list of recently used models, right-click on
the model and select the ''Remove Model File from List'' item.
IJ□
Descnllbot' Ea,toi Mooel C>,et111eA
¢ --'
vendcn: MySQL Table V
Add Diagram EER CXagam
Y Physical Schemas
00
00
•••
:::
=
= + -
G
Tables ,.. .-,,
Descnpbon
- !;- ----------------- TablcName: ~ s Schema: ap
-□ □
- D -□ -□ -□ □
- D
vendo r_addri!5S2 VARCHAR(SO) NULL V
- -
Ready
Description
• An EER model is a representation of the entities, or objects, of the database
including the tables, views, and stored programs.
• To edit a table, double-click on it. Then, use the tabs that appear across the bottom
of the window to modify the table's columns, indexes, and foreign keys.
• To add a new table, double-click on the Add Table icon. Then, use the tab that
appears to define the table.
• To delete a table, right-click on it and select the Delete item.
• The skills for working with tables also apply to other database objects such as
views and stored programs.
• The EER model typically includes at least one diagram named EER Diagram.
• To open a diagram, double-click on the name of the diagram.
• To create a new diagram, double-click on the Add Diagram icon or select the
Model ➔ Add Diagram item.
• To expott a database creation script from the model, select the File ➔ Export➔ Forward
Engineer SQL CREATE Script item.
>vendor_address2 VARCHAR(SO) ,H -
lnvolce_number VMCHAA(SO) . • ao:ount_number INT(lll
Description
• An EER diagram is a visual representation of an EER model. As a result, when you
modify the tables in the diagram, yot1 also modify the model.
• To add a table that already exists in the model to the diagram, drag the table from
the Catalog Tree window onto the diagram.
• To add a new table to the diagram, click the Place a New Table button in the
vertical toolbar at the left edge of the diagram. Then, click on the diagram where
you want to add the table.
• To display the model for a table, double-click on the table. Then, a tab is displayed
for the table, and you can use the techniques you learned in the previous figure to
edit the table.
• To define the relationship between two tables, click one of the relationship buttons
in the vertical toolbar. Then, click on the column in each table that defines the
relationship.
• To edit or delete a relationship, right-click on the relationship icon and select the
appropriate item.
• To remove a table from the diagram but keep it in the model, right-click on the
table and select the Remove Figure item.
• To remove a table from the diagram and delete it from the model, right-click on the
table and select the Delete item.
Perspective
Database design is a complicated subject. Because of that, it's impossible
to teach you everything yot1 need to know in a single chapter. With the skills
you've learned in this chapter, though, you should now be able to design simple
databases of your own. More impo11antly, you should be able to evaluate the
design of any database that you work with. That way, you can be sure that the
queries you code will be as efficient and as effective as possible.
In the next chapter, you' 11 learn how to implement the database designs you
develop using DDL statements. As you read that chapter, though, keep in mind
that you can also implement a database design by generating a SQL creation
script from an BER model and then executing that script. Even so, you'll want
to be sure you unde1·stand the DDL statements the generated script contains.
Terms
data structure unnormalized data structure
entity normalized data structure
attribute normal forms
instance index
entity-relationship (ER) modeling table scan
CASE (computer-aided software composite index
engineering) derived data
linking table Boyce-Codd nonnal form
connecting table transitive dependency
associate table multivalued dependency
referential integrity domain-key normal form
declarative referential integrity (DRI) denormalization
foreign key constraint entity-relationship (ER) model
orphaned row enhanced entity-relationship (BER)
normalization model
data redundancy BER diagram
Chapter 10 Hovv to design a database 339
Exercises
1. Use MySQL Workbench to create an EER diagram for a database that stores
information about prodt1cts.
Each product must have a product name, description, and price.
Each product must belong to one category.
Each category must have a category name and description.
Each category can include multiple products.
2. Use MySQL Workbench to create an EER diagram for a database that stores
infor1nation about customers.
Each customer must have an email address, first name, and last name.
Each customer can have two or more addresses.
Each customer can have a default billing address and a default shipping
address.
Each address must have a street address, city, state, postal code, and
country.
Each country name should be stored in one place only. In other words, you
shouldn't store the name of the country, which may be many characters, in
the address.
3. Use MySQL Workbench to create an EER diagram for a database that tracks
the memberships for an association and for the groups within the association.
Each member must have an email address, fit·st name, and last name.
Each member can belong to any number of groups.
Each group must have a name.
Each group can have any number of members.
How to create databases,
tables, and indexes
Now that you've learned bow to design a database, you're ready to learn how to
implement your design. To do that, you use the set of SQL statements that are
known as the data definition language (DDL). In this chapter, you'll learn how
to use DDL statements or MySQL Workbench to work with databases, tables,
and indexes. In addition, you '11 learn how to change the character set, collation,
and storage engine if you need to do that.
Description
• The CREATE DATABASE statement creates a database with the specified nan1e on
the sen ·er.
• The DROP DATABASE staten1ent delete the database \Vith the specified name
fron11 the server. Thi deletes all of the table and data that are stored in the
database.
• The USE staten1ent selects the pecified database and n1ak.e it the current database.
L
Before I continue, you should realize that if you run the statements shown in
this figure against the AP database, the statements will fail. That's because the
AP database already contains tables named Vendors and Invoices. A s a result,
if you want to test these statements, you can run them against the EX database.
Then, the Vendors and Invoices tables will be created in that database.
In its simplest form, the CREATE TABLE statement consists of the name
of the new table followed by the names and data types of its columns. This is
illustrated by the first example in this figure. However, in most cases, you'll code
one or more attributes for each column as illustrated by the second example. For
instance, to indicate that a column doesn't accept null values, you can code the
NOT NULL attribute. If you omit this attribute, the column allows null values.
To indicate that each row in a column must contain a unique value, you can
code the UNIQUE attribute. Since two null values aren' t considered to be the
same, a unique colurm1 can contain null values. However, it's common to u se the
NOT NULL and UNIQUE attributes to define a column that can't contain null
values and where each value in the column must be unique.
To generate unique numbers in sequence, you use the AUTO_INCREMENT
attribute. This attribute can only be specified for one column in a table, and that
column must be defined as either the primary key or a unique key. When you
define a column with theAUTO_INCREMENT attribute, MySQL automati-
cally generates the next number in sequence for the column if you don' t specify
a value. By default, MySQL starts numbering with 1, but you ca11 start with a
value other than 1 by coding an option like this at the table level:
AUTO_ INCREMENT = 3
Finally, to specify a default value for a column, you can use the DEFAULT
attribute. This value is used if another value isn ' t specified when a row is added
to the database. The default value you specify must correspond to the data type
for the column. For example, the default value for the payment_total column
is set to a value of zero. With MySQL 8.0.13 and later, you can also specify a
default value as an expression. For example, you could specify a default value
for the invoice- date column as the CURRENT- DATE function.
Chapter 11 How to create databases, tables, and indexes 345
Description
• To test the code in this figure and in the figures that follow, you can select the EX
database.
• The CREATE TABLE statement creates a table based on the column names, data
types, and attributes that you specify. In addition, it allows you to specify some
attributes and constraints at the table level as described later in this chapter.
Description
• Constraints are used to enforce the integrity of the data in a table by defining rules
about the values that can be stored in the columns of the table.
• You code a column-level constraint as part of the definition of the column it
constrains. You code a table-level constraint as if it is a separate column definition,
and you name the columns it constrains within that definition.
• A not null constraint prevents null values from being stored in the column. A
unique constraint requires that each row has a unique value in the column but
allows null values to be stored in the column.
• A primary key constraint requires that each row has a unique value for the column
or columns for the primary key, and it does not allow null values.
Description
• Aforeign key constraint requires values in one table to match values in another
table. This defines the relationship between two tables and enforces referential
integrity.
• To define a relationship that consists of two or more columns, you must define the
constraint at the table level.
Description
• You can use the ALTER TABLE statement to add, drop, or modify the columns of
an existing table.
• MySQL won't allow you to change a column if that change would cause data to be lost.
Warning
• You should never alter a table or other database object in a production database
without first consulting the DBA.
Description
• You can use the ALTER TABLE statement to add or drop the constrain ts of an
existing table.
• To drop a foreign key constraint, you must know its name. If you don't know its
name, you can use M ySQL Workbench to look up the name as shown later in this
chapter.
Description
• You can use the RENAME TABLE statement to change the name of an existing
table.
• You can use the TRUNCATE TABLE statement to delete all data from a table
without deleting the definition for the table.
• You can use the DROP TABLE statement to delete a table from the current
database.
• To rename, truncate, or drop a table from another database, you must qualify the
table naine with the database 11ame.
• You can't truncate or drop a table if a foreign key constraint in another table refers
to that table.
• When you drop a table, all of its data, constraints, and indexes are deleted.
Warning
• You shouldn't use these statements on a production database without first
consulting the DBA.
Description
• MySQL automatically creates an index for primary key, foreign key, and unique
constraints.
• You can use the CREATE INDEX statement to create other indexes for a table. An
index can improve performance when MySQL searches for rows in the table.
• You can use the DROP INDEX statement to drop an index from a table.
For most of the columns in these tables, I coded a NOT NULL constraint
or a DEFAULT attribute. In general, I only allow a column to accept null values
when I want to allow for unknown values . If, for example, a vendor doesn' t
supply an address, the address is unknown. In that case, you can store a null
value in the vendor- address 1 and vendor- address2 columns.
Another option is to store an empty string for these columns. To do that, I
could have defmed the vendor address columns like this:
vendor_ addressl VARCHAR(SO} DEFAULT 1 ' ,
vendor_ address2 VARCHAR(SO) DEFAULT'',
In this case, empty strings will be stored for these columns un]ess other values
are assigned to them.
In practice, a null value is a 1nore intuitive representation of an unknown
value than a default value is. Conversely, it makes sense to use a default value
like an empty string to indicate that a value is known but the column is empty.
For example, an empty string might indicate that a vendor hasn 't provided its
street address. Although how you use nulls and empty strings is largely a matter
of personal preference, it does affect the way you query a table.
When a primary key consisted of a single column, I coded the PRIMARY
KEY constraint at the column level. Similarly, I coded the UNIQUE constraint
at the column level. As a result, I didn't provide names for these constraints.
However, whenever I coded a primary key or foreign key constraint at the
table level, I followed a convention that begins with the name of the table or an
abbreviated name for the table.
As you know, when MySQL creates a table, it automatically creates indexes
for the primary key, foreign keys, and unique keys. MySQL uses the name
''PRIMARY'' for the name of the index for a table's p1imary key. It uses the
name of the column for the name of the index for a unique key. And it uses the
name of the foreign key for the name of the index for a foreign key column.
For the Invoices table, for example, MySQL automatically creates an index
named ''PRIMARY'' for the invoice_id column, it creates an index named
invoices_fk_ vendors for the vendor_id column, and it creates an index named
invoices_fk_terrns for the terrns_id column.
In addition to the indexes that are created automatically, I used a CREATE
INDEX statement to create an index for the invoice date column in the Invoices
table. Since this column is frequently used to search for rows in this table,
this index should improve performance of the database. To name this index, I
followed the naming conventions presented earlier in this chapter. As a result,
when you view the name of an index, you can easily identify the table and
column that's being indexed.
Chapter 11 How to create databases, tables, and indexes 361
-- create an index
CREATE INDEX invoices_ invoice date ix
ON invoices (invoice_ date DESC);
T'al Tables
► Iii general_ledg,r_accounts
► i1 invoice_1rchlve Cooments:
► iii lnvolce_hne_items
► ii Invoices ColumnName Datatype PK ~ UQ 8 LN 1r Al G Oefautft=xpresslon
► ii terms
► Iii vendor_contacts
,nvoic,_ld INT{ll) E2l E2l □ □ □ □ E2l □
► El vendors
vendor_icf INT{l 1)
□ E2l □ □ □ □ □ □
loJ Viev.-s
lnvofce_number VARCHAR(SO)
□ E2l □ □ □ □ □ □
'ell stored Procedures
involce_d1te DATE
□ E2l □ □ □ □ □ □
lc)l Functions
lnvoice_total OECIMAL(9,2)
□ E2l □ □ □ □ □ □ y
< >
► ex
► om
V
.. =• Cdl.lm Name: ,__l
1nv_oice_1c1_ _ _ _ __. Data Type: IINT(ll)
Adminlstntlon Schemas
Olarsetft:;olaban: L
--~ Default Cobb OefcNJt:
lnformabon
C0!!1!lents: SU>rage: Virtual Stured
Tab~ 1nll0lces
E2l Pnmary Key E2l NotNul □ lhque
Columns:
in • . 1d nt{U) Al PK □ Binary □ Unsigned D ZeroAII
v~ id nt{ll)
lnvoice_runber varctw(SO)
invoice date date
E2) Aull> Increment 0 Gerle'ated
nvoice_liita!
payment_tutal
deornel{9,
~9,2
2l
aedit_tutal deo 9,2 Columns Indexes Foreign IC~~ Tng11ers Partitioning Optiom
ternts_id r,t{U) V
- - - .-1.,- Aat. "4:ata
ObJ,c: Info Session Revert
Description
• To view the columns for a table, right-click on the table in the Navigator window,
select the Alter Table item, and click on the Columns tab.
• To rename a column, double-click on the column name and enter the new name.
• To change the data type for a column, click on the data type in the Datatype
colt1mn. Then, select a data type from the drop-down list that's displayed.
• To change the default value for a column, enter a new default valt1e in the Default
column.
• To change other attributes of the column, check or uncheck the attribute check
boxes to the right of the column.
• To drop a column, right-click on the column name and select the Delete Selected
item.
• To move a column up or down, right-click on the column name and select the Move
Up or Move Down item. You can also use the Up and Down keys on the keyboard.
• To add a new column, double-click in the Column Name column below the last
column and type in a new name. Then, specify the attributes for the new column.
• To apply the changes to the table, click the Apply button. To reverse the changes,
click the Revert button.
=
Columns:
nvoke_runber
invoic~ date.
~ ~~i~j Al PK
vardw(SO)
dare
nvoice.Jiital drotN,1{9,2) < >
payment_total deomal(9,2)
aedit_total deomo1(9,2J Columns Ind~ Foreio11 Keys Tnogers Partrtionlng OptioM
te.rms_id nt(U) V
- - - ~.., Aa♦a .-.st.
Ob)ea Info S5SIOO Revert
Description
• To view the indexes for a table, right-click on the table in the Navigator window,
select the Alter Table item, and click on the Indexes tab.
• To rename an index, double-click on the name and enter the new name.
• To change the type of an index, click on the Type column. Then, select a type from
the drop-down list that appears.
• To change the colu1nn that's indexed, select the index and then select its column in
the list of columns that appears. You can also change the sort order of the index by
clicking in the Order column and then selecting ASC or DESC from the drop-down
list that appears.
• To drop an index, right-click on the index name and select the Delete Selected item.
• To add a new index, double-click below the last index name and type in a new
name. Then, specify the type, column, and order for the index.
• To apply the changes to the table, click the Apply button. To reverse the changes,
click the Revert button.
ouerv 1 il:1·\Hftlffll,;i
■ iiL ______________________
SCHEMAS
~ 1Ft11er abjects j Table Name: fi±es,___
_______ _,I Schema: ap
T Tables
► □ oeneral_ledoer_accounts
C«nments:
► il invoice_archlve
► Ii lnvolce_hne_1tems
► 0 Invoice. Foreq1 Key Name Qiunn Refereoced Cobl Foreign Key Options
Referenced Table
► Eil terms
lnvolce~_fk_terrm · ap· : terms · D invoice_id On ~ate: RESTRICT
► Iii vendor_contaas
► D vendors
invoices_flc_ve:ndcn · ap · : vendors · D vendor_id -------=:::::
On Delete: R.ESTRrCT
Vlev.s
D lnvolce_number
'ell stored Procedures D invoice_date
Functions
D invo1ce_total D Slap In SQl gener-ation
► ex
D payme:nt_total
D aed1t_t otal
► om .., 0 terms_id terms_id
.. =• For~ Kev Comme-tt ----
Administration Schemas D invo1ce_due_date
D payment_date
Inform<lbon
Columns:
~~ ~ ~~~~ Al PK
lnvoice_runber vardl.Y(SO)
invoice date date
rwoice_lotal deomlll(9,fil < > < >
payment_total deomal(9,2
aedit_total deomal(9, Columns lndexes Fore19n Keys Tnggl!TS Partitioning Optioro
terms_id nt(U) ..,
- - - _,._ Aa ♦• ris.,_
Objea Info Sess-lon
Description
• To view the foreign keys for a table, right-click on the table in the Navigator
window, select the Alter Table item, and click on the Foreign Keys tab.
• To rename a foreign key, double-click on the name and enter the new name.
• To change the referenced table, click on the table name in the Referenced Table
colt1m.n and select a table from the drop-down }jst that appears.
• To change the colu1nn or referenced column for a foreign key, select the foreign key
and then select the column or referenced column in the list that appears.
• To drop a foreign key, right-click on its name and select the Delete Selected item.
• To add a new foreign key, double-click below the last foreign key name and type in
a new name. Then, specify the referenced table, foreign key column, and referenced
column.
• To apply the changes to the table, click the Apply button. To reverse the changes,
click the Revert button.
Description
• The character set that's used by a database, table, or column determines which
characters can be stored and how many bytes are used to store the characters.
• Every character set has a corresponding collation that determines how the characters
within the set are sorted.
• If the name of a collation ends with ci, the collation is case-insensitive. If the name
of a collation ends with cs, the collation is case-sensitive.
• If the name of a collation includes ai, the collation is accent-insensitive. If the name
of a collation includes as, the collation is accent-sensitive.
• If the name of a collation ends with bin, the collation is binary, which means that the
characters are sorted according to the binary numbers that correspond to each character.
If MySQL isn' t sorting characters the way you want, you can use another
character set and collation. If you're using utf8mb3, for example, you can use the
utf8_unicode_ci collation instead of the default of utf8_general_ci. This colla-
tion provides more correct sorting, although it isn 't as fast as utf8_general_ci.
Remember, though, that the utf8mb3 character set is deprecated, so you
should use utf8mb4 instead for new development. In that case, the default colla-
tion of utf8mb4_0900_ai_ci usually works the way you want. However, if you
want to use a case-sensitive sort, you can use a collation with a name that ends
with cs. Or, you can use a collation with a name that ends with bin, which stands
for binary. This sorts characters by their nu1neric values instead of by their
character values. Finally, if you want to use an accent-sensitive sort, you can use
a collation that includes as.
How to view the character set and collation for all the tables in a database
SELECT table_ name, table_ collation
FROM information_ schema.tables
WHERE table_ schema = •ap'
TABLE_NAME TABLE_COLLATION "'
invoice_line j terns
- utf8mb4_0900 _ai_d -
. .
1nv01ces utf8mb4_0900 _ai_ci
terms utf8mb4_0900_ai_o \I
How to view the storage engine for all the tables in a database
SELECT table_ name, engine
FROM information schema.tables
WHERE table_ schema = 'ap'
- -
TABlE NAME
- ENGINE
invoice_lineJtems Inno06
• • I
1nVOtCeS InnoDB
terms lnnoDB
Description
• The storage engine determines how MySQL stores data and which database
features are available to you .
• You can use multiple storage engines on the same server and within the same
database.
How to set the default storage engine for the current session
SET SESSION default_ storage_ engine = Inno DB
Description
• To specify a storage engine for a table, you can use the ENGINE clause.
• To change the default storage engine for the cun·ent session, you can use the SET
SESSION statement to set the storage_engine variable for the current session.
• To permanently change the default storage engine for a server, you can modify the
configuration file for the server. For more infor1nation about how to do this, see
chapter 17.
Perspective
Now that you 've completed this chapter, you should be able to create and
modify the tables of a database by coding DDL statements. In addition, you
should be able to use a graphical tool like MySQL Workbench to work with the
tables of a database.
Before you move on, though, take a moment to consider the advantages
and disadvantages of using M ySQL Workbench to work with database objects.
The advantage, of course, is that MySQL Workbench provides a graphical user
interface that 1nakes it easy to view and work with database objects. The disad-
vantage is that no record is kept of any changes that you make to the database.
For example, if you add a column to a table, that change isn ' t stored anywhere
for future use.
In contrast, if you use a script to add a column to a table, that change is
stored for future use. This makes it easy to recreate the database if you ever
need to do that. And that's why it's common to use scripts to make any changes
to the structure of a database. On the other hand, MySQL Workbench is an
excellent tool for quickly viewing the objects of a database or for quickly
creating temporary tables or other objects that won't need to be recreated later.
Terms
attribute
constraint
column-level constraint
table-level constraint
not null constraint
unique constraint
prin1ary key constraint
foreign key constraint
reference constraint
cascading delete
index
script
character set
collation
sto1·age engine
Chapter 11 How to create databases, tables, and indexes 379
Exercises
1. Write a script that adds an index to the AP database for the zip code field in
the Vendors table.
2. Write a script that contains the CREATE TABLE statements needed to imple-
ment the following design in the EX database:
members members- committees committees
member id ••----
- ◄ member id
- committee id
-
fi rst name comm ittee id committee name
-
last- name
- -
address
city
state
phone
These tables provide for members of an association, and each member can be
registered in one or more committees within the association.
The member_id and committee_id columns are the primary keys of the
Members and Committees tables, and these columns are foreign keys in the
Members_Committees table.
Include any constraints or default values that you think are necessary.
Include statements to drop the tables if they already exist.
3. Write INSERT staten1ents that add rows to the tables that are created in
exercise 2.
Add two rows to the Members table for the first two member IDs.
Add two rows to the Committees table for the first two committee IDs.
Add three rows to the Members- Committees table: one row for member 1 and
committee 2 ; one for member 2 and committee 1; and one for member 2 and
committee 2.
Write a SELECT statement that joins the three tables and retrieves the
committee name, member last name, and member first name. Sort the results
by the com1nittee name, member last name, and member first name.
4. Write an ALTER TABLE statement that adds two new columns to the Members
table created in exercise 2.
Add one column for annual dues that provides for three digits to the left of the
decimal point and two to the right. This column should have a default value of
52.50.
Add one column for the payment date.
5. Write an ALTER TABLE statement that modifies the Committees table created
in exercise 2 so the committee name in each row has to be unique. Then, use an
INSERT statement to attempt to insert a duplicate name. This statement should
fail due to the unique constraint.
How to create views
As you've seen throughout this book, SELECT queries can be complicated,
particularly if they use multiple joins, subqueries, or complex functions .
Because of that, you may want to save the queries you use regularly. One way
to do that is to store the statement in a script. Another way is to create a view.
Unlike scripts, which are stored in files, views are stored as part of the
database. As a result, they can be used by SQL programmers and by custom
applications that have access to the database. This provides some advantages
over using tables directly.
An introduction to views
Before you learn the details for \a.'orking \\rith vie\\'S. it's helpful to get a
general idea of how views \vork. ln addition~ it' helpful to consider ome of the
benefits of ,,ie,vs o you can deternune wl1ether you want to use them.
To drop a view. you can u.. e the DROP VIEW . tatement as ho\\.rn in this
figure. This \.\t'orks imilarly to tl1e DROP tatements for tables and indexes that
you learned about in the pre\'ioru chapter.
Because a view i. stored a an object in a database. it can be u ed by atl}'One
who has appropriate pri\•ilege . That may include user who ba\·e acces to tl1e
database through applications thal provide for ad hoc querie. and report genera-
tion. In addition. that ma)' include cu tom applications that are ,vritten specifi-
cally to \Vork ,vith the data in the database. In t·ac~ vie, are otten de igned to
be u ed \ViU1 the e l}rpe. ot· application .
Chapter 12 How to create views 383
( 122 rows)
( 75 rows )
Description
• A view consists of a SELECT statement that's stored as an object in the database.
The tables referenced in the SELECT statement are called the base tables for the
•
view.
• When you create a view, you can refer to the view anywhere you wo11ld normally
use a table in a SELECT, INSERT, UPDATE, or DELETE statement.
• Although a view behaves like a virtual table, it doesn't store any data. Instead, a
view always refers back to its base tables.
• A view can also be referred to as a viewed table because it provides a view to the
underlying base tables.
Description
• You can create a view based on almost any SELECT statement. That means that
you can code views that join tables, summarize data, and use subqueries and
functions.
A view that names all of its columns in the CREATE VIEW clause
CREATE OR REPLACE VIEW invoices_ outstanding
(invoice_nwnber, invoice_ date, invoice_ total, balance_ due)
AS
SELECT invoice n11mher, invoice_ date, invoice_ total,
invoice_ total - payment_ total - credit_ total
FROM invoices
WHERE invoice_ total - payment_ total - credit_ total > 0
A view that names just the calculated column in its SELECT clause
CREATE OR REPLACE VIEW invoices_ outstanding AS
SELECT invoice_ n11mher, invoice_ date, invoice_ total,
invoice_ total - payment_ total - credit_ total AS balance_ due
FROM invoices
WHERE invoice total - payment_ total - credit_ total > 0
The example in part 2 of figu1·e 12-3 creates a view that summarizes the
rows in the Invoices table by vendor. This shows that a view can use agg1·egate
functions and the GROUP BY clause to summarize data. In this case, the rows
are grouped by vendor name, and a count of the invoices and the invoice total are
calculated for each vendor.
When you create a view, the SELECT statement you code within the defini-
tion of the view can refer to another view instead of a base table. In other words,
views can be nested. In theory, nested views can make it easier to present data to
your users. In practice, using nested views can make the dependencies between
tables and views confusing, which can make your code difficult to maintain. As a
result, if you use nested views, you should use them careful!y.
Chapter 12 How to create views 389
Description
• You use the CREATE VIEW statement to create a view.
• If you include the OR REPLACE keywords, the CREATE VIEW statement will
replace any existing view that has the same name. Otherwise, you must specify a
name that doesn't already exist for the view.
• If you name the columns of a view in the CREATE VIEW clause, you have to name
all of the columns. By contrast, if you name the columns in the SELECT clause,
you can name just the columns you need to rename.
• You can create a view that's based on another view rather than on a table. This is
known as a nested view.
Description
• An updatable view is a view that can be used in an INSERT, UPDATE, or DELETE
statement to update the data in the base table. If a view isn't updatable, it's called a
read-only view.
• Tl1e requirements for coding updatable views are more restrictive than for coding
read-only views. That's because MySQL must be able to unambiguously determine
which base tables and columns are affected.
Description
• If you don' t include a WITH CHECK OPTION clause when you create a view, a
change you make through the view can cause the modified rows to no longer be
included in the view.
• If you specify a WITH CHECK OPTION clause when you create a view, an en·or
will occur if you try to modify a row in such a way that it would no longer be
included in the view.
An INSERT statement that fails due to columns that don't have values
INSERT INTO ihm_ invoices
(invoice_numher, invoice_ date, invoice_ total)
VALUES
( 'RA23988', '2018-07-31', 417 .34)
Description
• You can use the INSERT statement to insert rows into a base table through a
view. To do that, you name the view in the INSERT clause. Both the view and the
INSERT statement must include all of the columns from the base table that require
a value.
• If the view names more than one base table, an INSERT statement can insert data
into only one of those tables.
• You can use the DELETE statement to delete rows from a base table through a
view. To do that, you name the view in the DELETE clause. For this to work, the
view must be based on a single table.
Description
• To alter a view, use the CREATE OR REPLACE VIEW statement to replace the
existing view with a new one.
• To delete a view from the database, use the DROP VIEW statement.
Perspective
In this chapter, you learned how to create and use views. A s you've seen,
views provide a powerful and flexible way to predefine the data that can be
retrieved from a database. By using them, you can restJ.ict the access to a
database while providing a consistent and simplified way for end t1sers and
application programs to access that data.
Terms
•
view nested view
base table updatable view
viewed table read-only view
Exercises
1. Create a view named open_items that shows the invoices that haven't been
paid.
This view should return four columns from the Vendors and Invoices tables:
vendor_ name, invoice_number, invoice_ total, and balance_ due
(invoice_total - payment_ total - credit_total).
A row should only be returned when the balance due is greater than zero, and
the rows should be in sequence by vendor_name.
2. Write a SELECT statement that returns all of the columns in the open_items
view that you created in exercise 1, with one row for each invoice that has a
balance due of $1000 or more.
3. Create a view named open_items_summary that returns one summary row for
each vendor that has invoices that haven't been paid.
Each row should include vendor_name, open_item_count (the number of
invoices with a balance due), and open_item_total (the total of the balance
due amounts)
The rows should be sorted by the open item totals in descending sequence.
4. Write a SELECT statem ent that returns just the first 5 rows from the
open_items_summary view that you created in exercise 3.
5. Create an updatable view named vendor_address that returns the vendor_ id
column and all of the address columns for each vendor.
6. Write an UPDATE statement that changes the address for the 1·ow with a
vendor ID of 4 so the suite number (Ste 260) is stored in the vendor_address2
column instead of the vendor- address 1 column.
Stored program development
This section presents the essential skills for using MySQL to create stored
programs. These are the skills that will take your SQL capabilities to
the next level. In chapter 13, you'll learn the language basics for writing
procedural code within sto1·ed programs. In chapter 14, you '11 learn how
to manage transactions and locking from within stored programs. In
chapter 15, you'll learn how to create two types of stored programs: stored
procedures and functions. And in chapter 16, you'll learn how to create two
more types of stored programs: triggers and events.
Language skills
for writing stored programs
This chapter presents the basic language skills that you need to write stored
programs. With the skills presented in this chapter, you'll be able to code
stored programs that provide functionality similar to procedural programming
languages like Python, PHP, Java, C++, C#, and Visual Basic.
If you have experience with another procedural language, you shouldn't
have any trouble with the skills presented in this chapter. However, you should
know that the programming power of MySQL is limited when compared to
other languages. That's because MySQL is designed specifically to work with
MySQL databases rather than as a general-purpose programming language.
For its intended use, however, MySQL is both powerful and flexible.
CALL test( ) ;
Description
• A stored program consists of one or 1nore SQL statements stored in the database
for later use.
• Within a stored program, you can write procedural code that controls the flow of
execution. That inclt1des if/else constructs, loops, and error-handling code.
data types that are used for the invoice_total, payment_ total, and credit_total
columns of the Invoices table. Then, a SELECT statement sets the value that's
stored in this variable. To do that, the SELECT statement returns a single value
and includes an INTO clause that specifies the name of the variable. As a result,
the SELECT statement selects the value into the variable.
After the first SELECT statement, the script uses an IF statement to test the
value of the variable. If the variable is greater than zero, the statement in the
THEN clause uses a SELECT statement to return a result set that indicates the
balance that is due. Otherwise, the statement in the ELSE clause uses a SELECT
statement to return a result set that indicates that the balance is paid in full.
After the stored procedure has been created, this script uses the DELIMTER
state1nent to change the delimiter back to the default deli1niter of a se1nicolon
(;). Then , it uses a CALL statement to call the stored procedure. This executes
the code stored within the procedure. You'll learn 1nore about how the CALL
statement works in chapte1· 15.
For now, don' t won)' if you don't understand the coding details for this
script. Instead, focus on the general ideas. Later in this chapter, you '11 leru·n the
details that you need to use the procedural language that's provided by MySQL.
Then, in chapter 15, you' ll learn more about the details of creating stored
procedures.
A summary of statements
for coding stored programs
Figure 13-2 begins by summarizing the SQL statements for controlling the
flow of execution within stored programs. These statements can be used to add
functionality that's similar to the functionality provided by procedural languages.
After the SQL statements for writing procedural code, this figure presents
one SQL statement that you're already familiar with that's commonly used
within stored programs: the SELECT statement. When working with stored
programs, you can use the SELECT statement to return a result set to the calling
program. This is often used to display messages that can help the programmer
develop and debug a stored program.
In addition, you can use the SELECT staten1ent with an INTO clause to
retrieve data from the database and store it in one or more variables. You saw
an example of this in the previous figure, and you'll learn more about how this
works as you progress through this chapter.
Chapter 13 Language skills for writing stored progra,ns 405
Description
• MySQL provides statements that can be used within scripts to add functionality
similar to that provided by procedural programming languages.
► This is a test.
Description
• To display a message from a stored program, you can use the SELECT statement to
retu1n a result set.
Description
• A variable stores a value that can change as a stored program executes.
• A variable must have a name that's different from the names of any columns used
in any SELECT statement within the stored program. To distinguish a variable from
a column, you can add a suffix like ''_var'' to the variable name.
You can also nest one IF statement within another like this:
IF first_ invoice_ due_ date <= NOW() THEN
SELECT 'Outstanding invoices are overdue!';
IF first_ invoice_ due_ date = NOW() THEN
SELECT I TODAY! I ;
END IF;
END IF;
In this case, the outer IF statement is executed when the oldest invoice due date
is less than or equal to the current date. However, the nested IF statement is only
executed when the oldest invoice due date is equal to the current date. In other
words, if the current date equals the oldest invoice due date, this code returns
two result sets instead of one. As you'll see later in this chapter, you can also
nest an IF statement within other types of statements such as loops.
Chapter 13 Language skills for writing stored progra,ns 411
Description
• You can use an IF statement to execute one or more statements depending on one
or more Boolean expressions. A Boolean express·ion is an expression that evaluates
to true or false.
• You can nest an IF statement within another IF statement or within other SQL state-
ments such as the statements for coding loops.
• You can also code parentheses around the Boolean expressions in an IF statement
like this:
IF (first_ invoice_ due_ date < NOW()) THEN •••
Description
• You can use a simple CASE statement or a sea,·ched CASE statement to execute one
or more statements depending on a value that's returned by an expression.
WHILE i < 4 DO
SET s = CONCAT(s, I
-
1,' - I
, •
1., I
I I ) ;
SET i = i + 1;
END WHILE;
SELECT s AS message;
END/ /
A REPEAT loop
REPEAT
SET s = CONCAT ( s, Ii= I, i , I I I);
SET i = i + 1;
UNTIL i = 4
END REPEAT;
A simple loop
testLoop: LOOP
SET s = CONCAT(s, 'i=', i, ' I ');
SET i = i + 1;
IF i = 4 THEN
LEAVE testLoop;
END IF;
END LOOP testLoop;
Description
• To execute a SQL statement repeatedly, you can use a loop. MySQL provides for
three types of loops: a WHILE loop , a REPEAT loop, and. a simple loop.
• You can use the LEAVE statement to go to the end of a loop.
• You can use the ITERATE statement to go to the beginning of a loop.
The syntax
Declare a cursor
DECLARE cursor_ name CURSOR FOR select_ statement;
Declare an error handler for when no rows are found in the cursor
DECLARE CONTINUE HANDLER FOR NOT FOUND handler_ statement;
Get column values from the row and store them in a series of variables
FETCH cursor_ name INTO variablel[, variable2] [, variable3] .•. ;
Description
• You can use the DECLARE .. . HANDLER statement to declare a handler for errors
that may occur. In MySQL, this is refe1Ted to as a condition handler.
• To continue execution when an error occurs, use the CONTINUE keyword. To exit
the current block of code when an error occurs, use the EXIT keyword.
• For a complete list of the MySQL erro1· codes and their corresponding SQLSTATE
codes, you can search the MySQL Reference Manual for ''Server error codes''.
The first stored procedure in part 2 shows how to exit the current block
of code as soon as an error occurs. To start, this stored procedure begins by
declaring a variable named duplicate_entry_for_key just like the stored proce-
dure in part 1. Then, it uses the BEGIN and END keywords to nest a block of
code within the block of code for the procedu1·e. Within the nested block of code,
the frrst statement declares a condition handler for the MySQL error with a code
of 1062. This handler uses the EXIT keyword to indicate that it should exit the
block of code when this error occurs. Then, the second statement executes the
INSERT statement that may cause the error. If no error occurs, the third state-
ment in the block displays a message that indicates that the row was inserted.
If an error occurs, however, the duplicate_entry _for_key variable is set to
TRUE. In addition, code execution exits the block of code and jumps to the IF
statement that's coded after the block. This statement displays a message that
indicates that the row was not inserted because of a duplicate key.
So, when should you use a CONTINUE handler and when should you use an
EXIT handler? 111 general, it's a matter of personal preference. However, if you
want to allow MySQL to attempt to execute statements in a block of code even
after it encounters an error, you should use a CONTINUE handler. On the other
hand, if allowing MySQL to continue to execute statements in the block causes
problems, you should use an EXIT handler.
The last stored procedure in this figure shows how to use a named condition
to handle the error that occurs when a row can't be inserted. In this case, the
stored procedure uses the SQLEXCEPTION condition. When this condition
occurs, the stored procedure displays a message that indicates that the row was
not inserted because of a SQL exception.
When handling the SQLEXCEPTION condition, many programmers
make the mistake of displaying a generic message like this: ''An unexpected
error occurred." Although this message is user-friendly, it doesn' t provide any
information that can help a programmer find and fix the error. As a result, it's
often better not to handle this exception at all. In that case, the stored procedure
displays an error as shown in the first example in part 1 of this figure.
Chapter 13 Language skills for writing stored progra,ns 423
SELECT 1
1 row was inserted.' AS message;
END;
Description
• If you want MySQL to exit the current block of code as soon as it encounters an
error, use an EXIT handler.
BEGIN
DECLARE E.X IT HANDLER FOR 1062
SET duplicate_ entry_ for_ key = TRUE;
DECLARE EXIT HANDLER FOR 1048
SET colwnn_ cannot_ be_ null = TRUE;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
SET sql_ exception = TRUE;
·- --
►
message
Row was not inserted -column cannot be null.
Description
• You can declare multiple condition handlers for a single stored program. If you do
that, the most specific error handlers are executed first and the least specific error
handlers are executed last.
• The MySQL en·or codes and the NOT FOUND condition identify specific errors.
The SQLSTATE codes identify less specific ANSI-standard errors. And the
SQLEXCEPTION and SQLWARNING conditions identify general errors.
Perspective
In this chapter, you were introduced to stored programs, and you learned
how to use MySQL to write procedural code. In the next three chapters, you'll
learn more about writing stored programs. In chapter 14, you '11 leam how to
manage transactions and locking. In chapter 15, you'll learn how to code stored
procedures and functions. And in chapter 16, you'll learn bow to code triggers
and events.
Terms
stored program searched CASE statement
stored procedure loop
stored function WHILE loop
stored routine REPEAT loop
trigger simple LOOP
event counter
block of code cursor
variable condition handler
Boolean expression error handler
nested statement exception handler
simple CASE statem.e nt nained condition
Exercises
Each of the scripts that you create in the following exercises should use the
same general structure as the script presented in figure 13-1.
1. Write a script that creates and calls a stored procedure named test. This
stored procedure should declare a vaiiable and set it to the count of all rows
in the Invoices table that have a balance due that's greater than or equal to
$5,000. Then, the stored procedure should display a result set that displays the
vai·iable in a message like this:
3 invoices exceed $5,000.
2. Write a script that creates and calls a stored procedure named test. This stored
procedure should use two variables to store ( 1) the count of all of the invoices
in the Invoices table that have a balance due and (2) the sum of the balances
due for all of those invoices. If that total balance due is greater than or equal
to $30,000, the stored procedure should display a result set that displays the
values of both variables. Otherwise, the procedure should display a result set
that displays a message like this:
Total balance due is less than $30,000.
3. Write a script that creates and calls a stored procedure named test. This proce-
dure should calculate the factorial for the number 10. (To calculate a factorial,
you multiply an integer by every positive integer less than itself.) Then, it
should display a string that includes the factorial like this:
The factorial of 10 is: 3,628,800.
Chapter 13 Language skills for writing stored progra,ns 427
4. Write a script that creates and calls a stored procedure named test. This proce-
dure should create a cursor for a result set that consists of the vendor_name,
invoice_number, and balance_due columns for each invoice with a balance
due that's greater than or equal to $5,000. The rows in this result set should
be sorted in descending sequence by balance due. Then, the procedure should
display a string variable that includes the balance due, invoice number, and
vendor name for each invoice so it looks something like this:
16896.06IP-0608IMalloy Lithographing Inc//9878.4SI0-2436IMalloy
Lithographing Inc//
Here, each column is separated by a pipe character (I) and each row is
separated by two front slashes (//).
5. Write a script that creates and calls a stored procedure named test. This
procedure should attempt to update the invoice_due_date column so it's equal
to NULL for the invoice with an invoice ID of 1. If the update is successful,
the procedure should display this message:
1 row was updated.
If the update is unsuccessful, the procedure should display this message:
Row was not updated - column cannot be null.
6. Write a script that creates and calls a stored procedure named test. This proce-
dure should identify all of the prime numbers less than 100. (A prime number
is an integer that can't be divided by another integer other than I and itself.)
Then, it should display a string variable that includes the prime numbers like
this:
2 I 3 I s I 1 I 11 I 13 I 11 I 19 I 23 I 29 I 31 1 - - ·
Hint: To get this to work, you will need to nest one loop within ariother loop.
In addition, you will need to code an IF statement within the inner loop.
7. Enhance your script for exercise 4 so it shows the invoice data in three groups
based on the balance due amount with these headings:
$20,000 or More
$10,000 to $20,000
$5,000 to $10,000
When you're done, the string variable that's returned should be in this format:
$20,000 or More: $10,000 to $20,000: 16896.06IP-0608IMalloy
Lithographing Inc//$5,000 to $10,000: 9878.4Sj0-2436IMalloy
Lithographing Inc//
To accomplish this, you can loop through the cursor three times by opening
and closing the cursor for each loop. Hint: For each group of invoices, you
can code a separate block of code that contains an EXIT handler for the NOT
FOUND condition.
How to use transactions
and locking
If you've been working with MySQL on your own computer, you've been the
only user of your database. In the real world, though, a database may be used
by thousands of users at the same time. Then, what happens when two users
try to update the same data at the same time? In this cha.pter, you' ll learn how
MySQL handles this situation. But first, you' ll learn how to combine multiple
SQL statements into a single logical unit of work known as a transaction.
START TRANSACTION;
Description
• By default, MySQL runs in autocommit mode, which automatically commits
changes to the database immediately after each INSERT, UPDATE, or DELETE
statement is executed. If that's not what you want, you can group statements into a
logical unit of work called a transaction.
• To start a transaction, code the START TRANSACTION statement. This turns off
autocommit mode until the staten1ents in the transaction are committed or rolled
back. To com,nit the changes, code a COMMIT statement. To roll back the changes,
use a ROLLBACK statement.
• MySQL automatically commits changes after a DDL statement such as a CREATE
TABLE statement. As a result, you shouldn't code a DDL statement within a
transaction unless you want to comm.it the changes and end the transaction.
START TRANSACTION;
COMMIT;
Description
• When you use save points, you can roll back a transaction to the beginning of the
transaction or to a particular save point.
• You can use the SAVEPOINT statement to create a save point with the specified
name.
• You can use the ROLLBACK TO SAVEPOINT statement to roll back a transaction
to the specified save point.
• Save points are useful when a single transaction contains so many SQL statements
that rolling back the entire transaction would be inefficient.
Two transactions that retrieve and then modify the data in the same row
Transaction A
-- Execute each statement one at a time.
-- Alternate with Transaction Bas described.
START TRANSACTION;
UPDATE invoices SET credit_ total = credit_ total + 100 WHERE invoice_ id = 6;
COMMIT;
Transaction B
-- Use a second connection to execute these statements!
-- Otherwise, they won't work as described.
START TRANSACTION;
UPDATE invoices SET credit_ total = credit_ total + 200 WHERE invoice_ id = 6;
COMMIT;
Description
• Concurrency is the ability of a system to support two or more transactions working
with the same data at the same time.
• MySQL can automatically prevent some concurrency problems by using locks. A lock
stops the execution of another transaction if it conflicts with a transaction that is already
•
running.
• Concun·ency is a problem only when the data is being modified. When two or more
SELECT statements read the same data, the SELECT statements don' t affect each
other.
Description
• In a large system with many users, you should expect for these ki11ds of problems
to occur. In general, you don't need to take any action except to anticipate the
problem. In many cases, if the SQL statement is resubmitted, the problem goes
away.
• On some systems, if two transactions overwrite each other, the validity of the
database is compromised and resubmitting one of the transactions won't eliminate
the problem. If you 're working on such a system, you must anticipate these concur-
rency problems and account for them in your code.
• If one of these problems could affect the data integrity of your system, you can
change the default locking behavior by setting the transaction isolation level as
shown in the next figure.
Figure 14-4 The four concurrency problems that locks can prevent
438 Section 4 Stored prvgram development
Set the transaction isolation level to READ COMMITTED for all sessions
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED
Description
• The transaction isolation level controls the degree to which transactions are isolated
from one another. At the more restrictive isolation levels, concurrency problems are
reduced or eliminated. However, at the least restrictive levels, performance is enhanced.
• To change the transaction isolation level, you use the SET TRANSACTION
ISOLATION LEVEL statement.
• If you include the GLOBAL keyword, the isolation level is set globally for all new
transactions in all sessions. If you include the SESSION keyword, the isolation level
is set for all new transactions in the current session. If you omit both GLOBAL and
SESSION, the isolation level is set for the next new transaction in the current session.
• The default transaction isolation level is REPEATABLE READ. This level places
locks on all data that's used in a transaction, preventing other users fro1n updating that
data. However, thls isolation level still allows inserts, so phantom reads can occur.
• The READ UNCOMMITTED isolation level doesn't set any locks and ignores
locks that are already held. This level results in the highest possible performance
for your query, but at the risk of every kind of concurrency problem. For this
reason, you should only use this level for data that is rarely updated.
• The READ COMMITTED isolation level locks data that has been changed but not
committed. This prevents dirty reads but allows all other types of concurrency problems.
• The SERIALIZABLE isolation level places a lock on all data that's used in a
transaction. Since each transaction must wait for the previous transaction to commit,
the transactions are handled in sequence. This is the most restrictive isolation level.
Figure 14-5 How to set the transaction isolation level
440 Section 4 Stored prvgram development
Description
• If you add the FOR SHARE clause to the end of a SELECT statement, the selected rows
are locked so other transactions can read those rows but can't modify them until the
transaction commits.
• If you add the FOR UPDATE clause to the end of a SELECT statement, the selected
rows and any associated indexes are locked so other transactions can't read or modify
them until the transaction commits. This works the same as the locks for an UPDATE
statement.
• If a SELECT ... FOR SHARE statement attempts to read any rows that have been locked
for update by another transaction, it waits until that transaction commits so it can use the
most current values.
• If a SELECT ... FOR UPDATE statement attempts to read any rows that have been
locked for share or for update by another transaction, it waits until that transaction
commits so it can use the most current values.
• When the NOWAIT option is included on a FOR SHARE or FOR UPDATE clause, the
statement doesn't wait for a lock to be released. Instead, it returns an error immediately.
This allows a developer to handle the error instead of waiting for the lock to release.
• When the SKIP LOCKED option is included on a FOR SHARE or FOR UPDATE
clause, the statement doesn't wait for a lock to be released. Instead, it skips the locked
rows and returns any rows that are not locked.
Figure 14-6 How to lock selected rows
442 Section 4 Stored prvgram development
Make large changes when you can be assured of nearly exclusive access
• If you need to change millions of rows in an active table, don't do so during hours
of peak usage.
• If possible, give yourself exclusive access to the database before making large
changes.
Description
• A deadlock occurs when neither of two transactions can be committed because
each transaction has a lock on a resource needed by the other transaction.
Perspective
In this chapter, you learned the ways that MySQL protects your data from
the problems that can occur on a real-world system. Since the failure of one
or more related SQL statements can violate data integrity, you learned how
to prevent these problems by grouping the statements into transactions. SiI1ce
multiple transactions can simultaneously modify the same data, you learned
how to prevent concurrency problems by setting the transaction isolation level
to change the default locking behavior. And since changing the isolation level
can increase the chances of deadlocks, you learned defensive programming
techniques to prevent deadlocks.
Terms
transaction dirty read
commit a transaction nonrepeatable read
roll back a transaction phantom read
save point transaction isolation level
concurrency deadlock
locking deadlock victim
lost update
Exercises
1. Write a script that creates and calls a stored procedure named test. This
procedure should include a set of three SQL statements coded as a transaction
to reflect the following change: United Parcel Service has been purchased by
Federal Express Co1-poration and the new company is named FedUP. Rename
one of the vendors and delete the other after updating the vendor_id column
in the Invoices table.
If these statements execute successfully, commit the changes. Otherwise, roll
back the changes.
2. Write a script that creates and calls a stored procedure named test. This
procedure sho11ld include a set of two SQL statements coded as a transaction
to delete the row with an invoice ID of 114 from the Invoices table. To do this,
you must first delete all line item s for that invoice from the
Invoice- Line- Items table.
If these statements execute successfully, commit the changes. Otherwise, roll
back the changes.
How to create
stored procedures
and functions
In chapter 13, you learned how to create a stored procedure that didn't accept
any parameters. Now, you'll learn how to create stored procedures that accept
parameters. In addition, you'll learn how to code stored functions.
As you'll see, stored procedures allow you to store procedural logic such
as data validation in a central location. In addition, they provide a powerful
way to control how users are allowed to access the database.
START TRANSACTION;
Description
• You use the CREATE PROCEDURE statement to create a stored procedure. A
stored procedure is an executable database object that contains procedural SQL
code. A stored procedure can also be called a sp,vc or a procedure.
• You can use parameters to pass one or more values from the calling program to the
stored procedure or fron1 the procedure to the calling program. For more infor1na-
tion on working with parameters, see figures 15-2 and 15-3.
• To declare a parameter within a stored procedure, you code the name of the param-
eter followed by its data type. If you declare two or more parameters, you separate
the parameters with commas.
• You can use the CALL statement to call a procedure. When a procedure accepts
parameters, you pass them to the procedure by coding them within the parentheses
that follow the procedure name, and by separating the parameters with commas.
<lures that perform all of the types of data manipulation that you want to allow
within your database. Then, you can grant privileges to execute these stored
procedures. For systems where security is critical, this can be an excellent way
to prevent both accidental errors and malicious damage to your data.
START TRANSACTION;
UPDATE invoices
SET credit total= credit_ total_param
WHERE invoice id= invoice_ id_param;
A script that calls the stored procedure and uses the output parameter
CALL update_ invoices_ credit_ tota1(56, 200, @row_ count);
SELECT CONCAT('row count: ', @row_ count} AS update_ count;
Description
• Input parameters accept values that are passed from the calling program. These
values cannot be changed by the body of the stored procedure. By default, param-
eters ai·e defined as input parameters. As a result, the IN keyword is optional for
identifying input parameters.
• Output para,neters store values that are passed back to the calling progra1n. These
values must be set by the body of the stored procedure. To identify an output
parameter, yot1 must code the OUT keyword.
• Input/output parameters can store an initial value that's passed from the calling
program. However, the body of the stored procedure can change this parameter. To
identify an input/output parameter, you must code the INOUT keyword.
• When you work with output parameters or input/output parameters, the calling
program typically passes a user variable to the parameter list. For more information
about t1ser variables, see figure 15-6.
START TRANSACTION;
UPDATE invoices
SET credit_ total = credit_ total_param
WHERE invoice id= invoice_ id_param;
Description
• You can provide a default value for a parameter so that if the calling program
passes a null value for the parameter, the default value is used instead.
• To set a default value for a parameter, you can use an IF statement to check if the
parameter contains a null value. If it does, you can assign a default value to the
parameter.
• It's a good programming practice to code your CREATE PROCEDURE statements
so they list parameters that require values first, fallowed by parameters that allow
null values.
UPDATE invoices
SET credit_ total = credit_ total_param
WHERE invoice_ id = invoice_ id__param;
END//
Description
• It's generally considered a good practice to validate the data within a stored proce-
dure before using the data. This is referred to as data validation.
• The SIGNAL statement raises an error. When you raise an error, you must specify
a SQLSTATE code as specified in chapter 13. In addition, you can optionally
specify an error message or MySQL error number.
• When you raise an error, MySQL returns the error to the caller in the same way that
it returns errors that are raised by the database engine. Then, the calling program
can handle the error.
After the values have been set for the variables for the terms- id and
invoice_due_date columns, this procedure executes an INSERT statement. If this
statement executes successfully, the row is inserted into the database.
In most cases, a stored procedure like this is called from an application
program. However, to test a procedure before it's used by an application
program, you can use CALL statements like the ones in part 2 of figure 15-5.
The first two CALL statements provide valid values that successfully insert
a new row. Of these statements, the frrst supplies non-null values for all of the
parameters for the procedure. The second supplies non-null values for the first
four parameters, but not for the last two. This shows that the frrst four parameters
are the only parameters that require non-null values.
The third CALL state1nent provides a negative nwnber for the invoice total
parameter. As a result, this CALL statement causes the stored procedure to raise
an error. Since the CALL statement doesn' t handle this error, an error message
like the one shown in this figW"e is displayed. However, if you call the stored
procedure from another stored procedure or from an application, you can include
code that handles the error.
Chapter 15 How to create stored prvcedures and functions 457
Description
• If the data for each of the columns of the row is valid, the procedru·e executes an
INSERT statement to insert the row. Otherwise, the procedure or database engine
raises an error and exits the procedure.
• If an application program calls this procedure, it can handle any errors that are
raised by the procedure or by the database engine.
Two stored procedures that work with the same user variable
DELIMITER //
Description
• A user variable is a special type of MySQL variable that's globally available to the
current user.
• A user variable is only available to the cun·ent user ai1d cannot be seen or accessed
by other users.
• A user variable is available as long as the user remains connected to the server, but
it is released when the user disconnects.
• A user variable can store various data types including string, numeric, and
date/time types . However, you don' t have to declare a data type for a user vaiiable.
• A user variable is available from statements coded both inside and outside of stored
programs.
Description
• You can use a stored routine to build a string variable that contains a SQL
statement. Then, you can use the PREPARE, EXECUTE, and DEALLOCATE
PREPARE statements to execute the statement contained in the string. This is
known as dynamic SQL.
Description
• To drop a stored procedure from the database, t1se the DROP PROCEDURE
statement.
SELECT vendor_ id
INTO vendor id var
FROM vendors
WHERE vendor name= vendor_ name_param;
Description
• A stored function, or justfunction, is an executable database object tl1at contains
procedural SQL code.
• With MySQL, you can only create scalar functions, which return a single value.
• To identify the data type that's returned by a function, you use the RETURNS
keyword in the declaration for the function. Then, in the body of the function, you
use the RETURN keyword to specify the value that's returned.
• A fu nction can accept input parameters that work like the input parameters for a
stored procedure.
• When you create a function , you can include one or more characteristics that
describe the function . See figure 15-10 for more information on these characteristics.
• To call a stored function, you can use it in any expression j ust like a built-in function.
Figure 15-9 How to create and call a function
466 Section 4 Stored prvgram development
Description
• If binary logging is enabled, which it is by default with MySQL 8.0, each function
must include the DETERMINISTIC, NO SQL, or READS SQL DATA characteristic.
To override this requirement, you can set the log_bin_ trust_function_creators system
variable to 1 (ON). For more information on working with system variables, see
chapter 17.
• The binary log contains a record of all the changes that have been made to the
contents of a database. It can be used for replication between two servers.
• Unless you code the DETERMINISTIC keyword, a function is considered to be
non-dete1·ministic. This affects the type of information that's stored in the binary log.
• It's more common to use a stored procedure rather than a function to modify a database.
Description
• This function accepts a single parameter that specifies the ID for an invoice, and it
returns the balance due for that invoice.
Description
• To delete a function from the database, use the DROP FUNCTION statement. If
you want to check whether the function exists before you drop it, add the optional
IF EXISTS keywords.
• The function in this figure uses the get_balance_due function that's presented in the
previous figure. As a result, if you drop the get_balance_due function, the function
in this figure won't work.
03
Nav19at0f
SCl1£MAS
Name:
a. 1Ftier ob)eCs
DOI.:
., J ap ,. Q l ~ O.lj[l~
► Tables 1 • - CREATE DEFINER=·root· @·localhost· PROCEDURE ·insert_invoice' (
► Views 2 vendor_id_param INT,
., Stored Procedures 3 invoice_number_param VARCHAR( ) ,
0 set_global_coirt 4 invoice_date_parani DATE,
D selec:t_lnvolcz:s 5 invoice_tot al_parani OEOMAL( , ),
CJ lnsert_invoice 6 terms_id_paran, INT,
7 invoice_due_date_param DATE
~ increment_global_count
8 )
[ D test 9 - BEGIN
update_ln Copy to aipboard ►
10 DECLARE t enas id var INTJ
., Functions Send to SQL EditOf ► 11 DECLARE invoi ce_due_date_var DATE;
fO get_balan 12 DECLARE tenas_due_days_var INT;
f() get_sum_
Crea!e Stored Procedure
13
f() get_vend, Alter S!ored Procedure. 14
► ar 15 IF invoice_total_param < THEN
[)fop Stored Procedure.
Adm,nistrllbon Schem 16 SIGNAL SQLSTATE '22083
Refresh All 17 SET MESSAGE_TEXT = The invoice_total col~ 111Jst ~ a posi1
Wormatton 18 MYSQL_ERRNO = ;
19 ELSEIF invoice_total_par11.111 >~ ~iOO THEN
Procedure: test
20 SIGNAL SQLSTATE 22003'
21
22
- -
SET MESSAGE TEXT = • The invoice total colu,nn eust be less ti
MYSQL_ERRNO = ,
23 END IF;
,,. V
< >
Routine
Description
• To view the stored procedures and functions for a database, you can expand the
node for the database. Then, you can expand the Stored Procedures 01· Functions
node.
• To view the code for an existing procedure or function, right-click on its name and
select the appropriate Alter item.
• To create a new stored procedure, right-click on the Stored Procedures node and
select the Create Stored Procedure item.
• To create a new function, right-click on the Functions node and select the Create
Function item.
• After you create a new procedure or function, you can refresh the Navigator
window to include it in the list of stored procedures or functions. To do that, click
the Refresh button near the upper right corner of the Navigator window.
• To drop a procedure or function, right-click on its name and select the Drop item.
Then, use the resulting dialog box to confir1r1 the drop.
• You can use the SHOW PROCEDURE STATUS and SHOW FUNCTION STATUS
statements to display information about the stored procedures and functions on a
server. For more information, see the MySQL Reference Manual.
Figure 15-1 3 How to create, view, and drop stored procedures and functions
474 Section 4 Stored prvgram development
Perspective
In this chapter, you learned how to create two types of stored programs:
procedures and functions. The focus of this chapter has been on the skills that
SQL developers typically need for working with procedures and functions.
However, you should know that there's a lot more to coding procedures and
functions than what this chapter has shown. With this chapter as background,
though, you should be able to learn whatever else you need on your own.
Terms
stored procedure input/output parameter
sproc user variable
procedure data validation
• •
parameter raising an error
compiling a procedure dynamic SQL
calling a procedure stored function
passing parameters by position function
input parameter scalar function
output parameter
Chapter 15 How to create stored prvcedures and functions 475
Exercises
1. Write a script that creates and calls a stored procedure named
insert_glaccount. First, code a statement that creates a procedure that adds a
new row to the General_Ledger_Accounts table in the AP schema. To do that,
this procedure should have two parameters, one for each of the two columns
in this table. Then, code a CALL statement that tests this procedure. (Note
that this table doesn ' t allow dttplicate account descriptions.)
2. Write a script that creates and calls a stored function named
test_glaccounts_description. First, create a function that tests whether an
account description is already in the General_Ledger_Accounts table. To do
that, this function should accept one parameter for the account description,
and it should return a value of 1 if the account description is in the table or
0 if it isn't. (Note: If a SELECT statement doesn't return any data, it raises a
NOT FOUND condition that your function ca.n handle.)
3. Modify the script that you created in exercise 1 so it creates and calls a stored
procedure named insert_glaccot1nt_ with_test. This procedt1re should t1se the
function that you created in exercise 2 to test whether the account description
is a duplicate before it issues the INSERT statement. If the account descrip-
tion is a duplicate, this procedure should raise an error with a SQLSTATE
code of 23000, a MySQL code of 1062, and a message that says ''Duplicate
account description."
4. Write a script that creates and calls a stored procedure named insert_ terms.
First, code a statement that creates a procedure that adds a new row to the
Terms table in the AP schema. To do that, this procedure should have two
parameters: one for the ter1ns_due_days column and another for the
terms_description column.
If the value for the description column is nt1ll, the stored procedure should be
able to create a default value for the description column based on the value of
the due days column. For example, for a due days column of 120, the descrip-
tion column should have a default value of ''Net due 120 days''. Then, code a
CALL statement that tests this procedure.
How to create triggers
and events
Now that you've learned bow to work with stored procedures and functions,
you're ready to learn about two more types of stored programs: triggers and
events. Triggers can be executed before or after an INSERT, UPDATE, or
DELETE statement is executed on a table. As a result, they provide a powerful
way to enforce data consistency, log changes to the database, and implement
business rules. Events can be executed at a schedt1led time. As a result, they
provide a convenient way to automatically perform any task that needs to be
run regularly, such as scheduled maintenance of tables.
,_ vendor_name vendor_state I
I
► US Postal Service WI
Description
• A trigger is a named database object that executes, or fires, in response to an
INSERT, UPDATE, or DELETE statement.
• You can fire a trigger before or after an INSERT, UPDATE, or DELETE statement
is executed on a table.
• You must specify a FOR EACH ROW clause. This creates a row-level trigger that
fires once for each row that's modified.
• You can use the OLD and NEW keywords to get and set the values for the columns
that are stored in the old row and the new row.
Since the body of this trigger executes a single statement, it could also be
coded without specifying a block of code like this:
CREATE TRIGGER vendors_ before_ update
BEFORE UPDATE ON vendors
FOR EACH ROW
SET NEW.vendor_ state = UPPER(NEW.vendor_ state);
The advantage of not specifying a block of code is that you don' t have to change
the delimiter or identify the start and end of the block of code. The disadvantage
is that it's more difficult to add statements to the trigger if you later decide that
you want the trigger to do more work.
Although it's not mentioned in chapter 15, stored procedures and functions
that execute a single statement can also be coded without specifying a block of
code. If you look back at figure 15-8, for example, you'll see a stored procedure
whose body consists of a single UPDATE statement. Because of that, the body
of this procedure could be rewritten without specifying a block of code. In 1nost
cases, though, you'll want to code the body of a stored procedure or function
within a block.
Description
• Triggers can be used to enforce rules for data consistency that can't be enforced by
constraints.
A statement that creates an audit table for actions on the invoices table
CREATE TABLE invoices_ audit
(
vendor_ id INT NOT NULL,
invoice_ nwnber VARCHAR ( 5 0) NOT NULL,
invoice_ total DECIMAL(9,2) NOT NULL,
action_ type VARCHAR ( 5 0) NOT NULL,
action_ date DATETIME NOT NULL
)
Two AFTER triggers that insert rows into the audit table
DELIMITER//
Description
• You can use an AFfER trigger to insert rows into an audit table.
► jinvolces_after_insert INSERT invoices BEGIN INSERT INTO invoices_audit VALUES ... AFTER 2018-12-28 ll:
invoices_befure_upda te UPDATE Invoices BEGIN DEa.ARE sum_line_jtem_amou,t DEO ... BEFORE 20 18-12-28 11:
involces_after _delete DaETE Invoices BEGIN INSERT INTO invoices_audlt VALUES •.• AFTER 2018-12-28 11:
vendors_before_update UPDATE vendors BEGIN SET NEW. vendor _sta te = UPPER{NEW•... BEFORE 2018-12-28 11:
< >
A statement that lists all triggers in a database that begin with ''ven''
SHOW TRIGGERS IN ap LIKE 'ven%'
► vendors_before_update UPDATE vendors BEGIN SET NE¥J.vendor_state = UPPER{NEW .... BEFORE 2018-12-28 11:
>
Description
• To view triggers, use the SHOW TRIGGERS statement. To filter the result set
that's returned, include an IN clause or a LIKE clat1se.
• To drop a trigger, use the DROP TRIGGER statement. To be sure a trigger exists
before it's dropped, include the IF EXISTS keywords.
Description
• An event, or scheduled event, is a named database object that executes, or fires,
according to the event scheduler.
• Before you begin working with events, you need to be sure that the event scheduler
is on. With MySQL 8.0 and later, it's on by default. With MySQL 5.7 and earlier,
it's off by default.
• To check the status of the event scheduler, you can use the SHOW VARIABLES
statement to view the variable named event scheduler.
• To turn the event scheduler on or off, you can use the SET statement to set the
value of the event_scheduler variable to ON or OFF. Here, the ON and OFF
keywords are synonyms for the INT values of 1 and 0.
• An event can be a one-time event that occurs once or a recurring event that occurs
regularly at a specified interval.
A statement that lists all events in a database that begin with ''mon''
SHOW EVENTS IN ap LIKE 1
mon% 1
Description
• To view events, use the SHOW EVENTS statement. To filter the result set that's
returned, include an IN clause or a LIKE clause.
• To enable or disable an event, use the ALTER EVENT statement with the ENABLE
or DISABLE keyword.
• To rename an event, use the ALTER EVENT statement with the RENAME TO
keywords, followed by the new name.
• To drop an event, use the DROP EVENT statement. To be sure an event exists
before it's dropped, include the IF EXISTS keywords.
Perspective
In this chapter, you learned how to use triggers to perform tasks that would
be difficult or impossible to perforn1 with other features like constraints. At this
point, you should be able to create and use triggers that enforce data consis-
tency, implement business rules, and log changes to the database. In addition,
you should be able to use events to automatically perform tasks according to a
schedule.
Although this is more than the typical SQL developer needs to know, this
gives you the perspective that you need when you encounter triggers that have
been created by others. This also provides the background that you need for
learning more about triggers on your own.
Terms
trigger
fire a trigger
row-level nigger
event
scheduled event
fire an event
event scheduler
one-time event
recurring event
Exercises
1. Open the trigger named invoices_before_update that was shown in figure
16-2. Then, modify it so it also raises an error whenever the payment total
plus the credit total becomes larger than the invoice total in a row. Then, test
this trigger with an appropriate UPDATE statement.
2. Create a trigger named invoices_after_update. This trigger should insert
the old data about the invoice into the Invoices Audit table after the row is
updated. Then, test this trigger with an appropriate UPDATE statement. If the
Invoices_Audit table doesn' t exist, you can use the code shown in figure 16-3
to create it.
3. Check whether the event scheduler is turned on. If it isn't, code a statement
that turns it on. Then, create an event that inserts a test row that contains test
values into the Invoices_Audit table every minute. To make sure that this
event has been created, code a SHOW EVENTS statement that views this
event and a SELECT statement that views the data that's inserted into the
Invoices_Audit table. Once you're sure this event is working correctly, code a
DROP EVENT statement that drops the event.
Database administration
If you want to become a database administrator, this section should get you
started. Although it doesn 't show you everything there is to know about
database administration, it does get you started by presenting the skills you
need to be the database administrator for a MySQL database that runs on
a single server. This should be enough for many types of projects, such as
a database that's used by a medium-sized website or a database that's used
for a departmental system.
In chapter 17, you' ll get an overview of database administration. In
addition, you'll learn some practical skills that you can use to monitor
and configure a server and work with its logs. In chapter 18, you'll learn
how to secure a database and work with user accounts. Finally, in chapter
19, you'll learn how to back up and restore a database. At this point, you
should have a solid foundation in database administration.
An introduction
to database administration
This chapter begins by presenting an overview of database administration,
including the responsibilities of a database administrator and the various types
of files that are used by a database. Then, this chapter presents some practical
skills that you can use to get started with database administration. These skills
include monitoring the server, configt1ring the server, and working with the
server's logs.
Description
• A database administrator (DBA) has many responsibilities that vary depending on
the database.
• Chapter 2 describes how to start and stop the server.
• Chapters 10 through 12 describe the skills that a OBA typically uses to design and
create databases.
• Chapters 17 through 19 focus on the skills that a OBA needs to administer a
database that's running on a single server.
• Database replication involves setting up two or more MySQL servers, usually
running on different machines, where one server is the master and the other servers
are the slaves. Then, any changes made to databases on one server are auto1nati-
call y propagated to the databases on the other servers.
Description
• The database ser ver uses several types of files including configuration files, data
files, and log files .
• By default, MySQL's data directory is hidden. As a result, you need to be able to
view hidden files to see this directory.
Connec1lon Name
Local instance MySQL80
Host: Anne-2015-PC CPIJ/loao Cclnnecuons
Sodcet: MVSQL Running 31% 4
Port 3306
My O
8.0.13
Server MySQl Commuruty Se~r • GPL
Coo1)11edFor: Win64- (x86_64}
Confi!;µ-ation Fie: C:\PtognimData\ MySQL\ MVSQL ~ t t 8.0\ myJnl Traffic Key Effc,er,cy
Rl.n'wlg Sr=; Sat Jan 1219:22:.55 2019 ( 1 day 19:11) 0.0%
4.65 KB/ s
Refresh
..,
Available Server Features Seleds per Second lnnoOfl Buff~ Usage
~ Schena: On Windows Aulhen1lcabon: Off 0 51.6%
Thread Pool: n/a PasS'i\onl Valdaboo: n/a
'4emcad1ed l'k,gJ'l: n/a AUcitlo!j: n/a
Semsync~bon~ n/a Arewal: n/a
SSL Avlliahity: On Arewal Trace: n/a
lnno06 ~ads per Second lnno08 Wries per Second
Server Directories 0 0
8a2 Directxry: C:\Program files\ MySQL \ HySQL Sol!crver IIJI\
Data Oiredxry: C:\ProgramData\MVSQL\ MVSQJ. Serva 8.0\ Data \
Disk So«e in Data Dir: 539.07 6 8 of 674.66 68 ava;Jable
Description
• To view the server status, you can sta1t MySQL Workbench and open a connection
to the server. Then, you can select the Server➔ Server Status item from the menu
system. Or, you can select the Server Status item from the Administration tab of the
Navigator window.
• By viewing the se1~er status window, you can get an idea of whether the server has
enough resources to handle its connections and traffic.
oJ
Local Instance MySQl.80
d ient Connections
Threitds Connected: 6 Threitds Running: 2 Threitds Created: 8 Thre.a ds Cached: 2 Rejected (over limit): O
Total Connections: 83 Connection Limit 151 Aborted Clieflts: 0 Aborted Connections: 6 Errors: 0 0
td User Host DB r,me State Thre-,... Type Nilme Par-en ..• lnslnJmented Info
'Ievent_sched... N4ne None Sleep 1119077 Waibn9 for.. '13 FOREGROUND thread/ sqVe... 1 YES NULL
6 None None None Daemon 1192068 Suspending 4'1 FOREGROUND thread/sql,lc. .. 1 YES NULL
7-'I
root localhost ap Sleep 3-49 None 113 FOREGROUND thread/ sq/o O YES NUU
75 root localhost ap Sleep 3'19 Nome 114 FOREGROUND thread/ sq/o ... 0 YES NULL
79 root localhost None Query O Sending data 11B FOREGROUND thread/ sq/o a YES SELE
80 root localhost None Sleep 3 None 119 FOREGROUND thread/sq/a ..• O YES NULL
82 jim localhost None Sleep 6 None 121 FOREGROUND thread/ sq/a 0 YES NULL
83 Jrm localhost None Sleep 6 None 122 FOREGROUND thre.ad/ scNo ... 0 YES NULL
< >
~-----;:====:;--------------------:===-=-=-=-=-=--.:::;--:::::=========-------:...::::..._..,
Refresh Rate: IDonl Refresh v I I Refresh I
D fide sleeping CDmeCtlons 0 tide backgroi.nd IIYeads 0 Don't load ful thre-,d rifo Show Detats J
Ready
Description
• A process is a connection to the database.
• To view the processes that are running, you can start MySQL Workbench and open
a connection to the server. Then, you can select the Server➔ Client Connections
item. Or, you can select the Client Connections item from the Administration tab of
the Navigator window.
• If the Refresh Rate option is set to Don't Refresh, you will need to click on the
Refresh button to display the process list.
• To stop a query, you can select it and click the Kill Query button.
• To stop a process, you can select it and click the Kill Connection button.
• To manually view a list of processes, you can use the SHOW PROCESSLIST state-
ment. To manually stop a process, you can use the KILL statement. For more infor-
mation about these statements, you can refer to the MySQL Reference Manual.
Status variables
■ MySQl. Workbench D X
6 Local instance MySQLSO x
Rle Edit Vtf!!W Query Database Sefver Tools Scripting Help
61 am @l &J @ rai
Admil'istrabon • Status and Sys
I Name
Aborted_conn~
Value
6
DesoiPbon
Number of failed attempts to connect to MySQL server
Category ,., Connection_errors_accept 0 Number of errors calling accept on the llstenlng port
All Connection_errors_internal 0 Number of connections refused due to internal errors
Altered Connection_errors_max_connections 0 Number of connections rHUsed due to themax_connections limlt
Binlog Connection_emirs_peer_address 0 Number of errors searchrng for connection d1ent IP addresses
Commands/Admin Connectlon_errors_seled 0 Numberof errors calling s~ectfpoll on the listening port
Commands/DDL Connection_errors_tcpwrap 0 Number of connections refused by libwrap
Commands/DML Connections 83 Number of connecbon attempts
Commands/G~eral locked_conneds 0 Number of attempts to connect to locked accounts
Commands~ared statement Max_used_connections 8 The maximum number of connt,ctions that have been In use slmultaneou~
Commands/Replication Max_used_connedions_tlme 201~01-10 10:55:11 The tlme at which Max_used_connedions reached Its current value
Commands/Show Mysqlx_ronnedion_accept_errors 0 The number of connecttons which have caused accept errors
Commands{Tl'llnsacbon Mysqlx_connect,on_errors 0 The number of connections which have been dos,d
Arewall MYsqlx_connections_acceptM 0 The number of connections which have been accepted
G~eral Mysqlx_connections_dos!d 0 The number of connections which have b~ dosed
Handler Mysqlx_connecbons_reiected 0 The number of connt,cbons wluch have been reiected
InnoOB/Buffer pool Performance_schema_sesslon_Cllll 125 The slze of the longest valid connection attnbute buffer seen
Performance_schema_session_coo... 0 The number of connections for whidl 41:tnbute strings could not be ueal
InnoOB/Dm
InnoDB/General
.., Ssl client connects 0 Number of SSL connection atte1111>ts to an SSl~nabled master "
< > < >
Copy Global Status and v ~ to Clipboard
Description
• A status variable is a va1iable that contains information about the status of the
MySQL server.
• To view status variables, select the Server➔ Status and System Variables item. Or,
select the Status and System Variables item from the Admini stration tab of the
Navigator window. If necessary, click the Status Variables tab. From that tab, you
can click one of the categories to display different status variables.
• To search for one or more status variables, type a search string in the Search box at
the top of the tab. This displays all status variables whose name contains the search
string.
• To manually view status variables, you can use the SHOW STATUS statement.
For more information about this statement, you can refer to the MySQL Reference
Manual .
System variables
■ MySQl. Workbench D X
,A Local instance MySQLSO x
File Edit View Query Database Server Tools Scripting Help
6l
sa•~---------------------------------
Loe.al Instance MySQl.80
Server Variables
Status Variables Systen Variables
<
General!Trans actions
> <
□ binloCJ oroup commit sync no dela... 0 rrwlSets the maximum numberof trans "
Description
• A system variable is a variable that stores a setting for the current configuration of
the MySQL server.
• To view server variables, select the Server➔ Status and System Variables item.
Or, select the Status and System Variables item from the Administration tab of the
Navigator window. If necessary, click the System Variables tab. From that tab, you
can click one of the categories to display the variables in that category. You can also
enter a search string in the Search box above the category names.
• If you don't have access to MySQL Workbench, you can use the SHOW
VARIABLES statement to view the system variables. For more information about
this statement, you can refer to the MySQL Reference Manual.
llir«tDrics "
□ basedr parent of"' Path of ristalabon mectory
System
D awid_te,p,ral_uw-ade Whethl!f' AlTER TABLE snould ~ pre-5.6. -I b!mporal counns
D ccre-file Vt'nte an file on servl!f' crans
1:2] lower_case_table_names If Sf!t to 1, tal:e names Me stored In lowercase on disk and tal:)je names wil be case nsensatiVe.
V
ShotJd be siet to 2 If I/OU are USi'lo a case~tive file svstem.
Configurabon File: C:V'r09f'Ml{)ata'f,tySQI. 'MySQL Servi!!' 8,0'vny.lnl ~Im_ysq_ld_ _. .,~I._ Otsc;yd
Description
• When MySQL starts, it reads the server configuration file and uses it to set system
variables.
• To use MySQL Workbench to change the server configuration file, select the
Server➔ Options File item. Or, select the Options File item from the Admini sn·ation
tab of the Navi gator window. Then, click an appropriate tab and use it to change
options. Fi11ally, click the Apply button to write the changes to the configuration
file.
• To use MySQL Workbench to change the server configuration file, you may need to
run it as an administrator. To do that on a Windows system, you can right-click the
MySQL Workbench icon and then select the ''Run as administrator'' or ''Open as
ad1ninistrator'' command.
• To use MySQL Workbench to change the server configuration file , you may need to
edit your connection so it points to the correct configuration file . To do that, open
the connection, display the Navigator window, click the wrench icon to the right of
the Instance category, and use the Configuration File option to select the correct file.
• On macOS, the configuration file isn 't created when you install MySQL. Instead,
it is created when you use Workbench to apply changes to the default system
variables. It's often stored in the /private/etc directory with a name of my.en£.
• The MySQL server only reads the configuration file when it starts. As a resul~ your
changes won't go into effect until you restart the server.
Instead, Workbench creates this file only after you use the Options File window
to apply changes to the configuration file.
Description
• To edit the configuration file directly, use a text editor. This file is named my.ini
(Windows) or my.cnf (macOS or Unix/Linux).
• With Windows, you may need to start your text editor as an administrator. To do
that, yot1 can right-click the icon that starts your text editor and then select the ''Run
as administrator'' or ''Open as administrator'' command.
• With macOS, you may need to use Finder to give yourself permission to read and
write the my.cnf file with a text editor. To do that, go to the /private/etc directory,
Ctrl-click on the my.cnf file, select the Get Info item, click the lock icon, and
modify the per1nissions. When you're done editing the file, revoke your write
• •
pefffilSSlOil .
• When specifying a number of bytes, you can add a suffix to a number to specify
kilobytes (K), megabytes (M), or gigabytes (G).
Session variables
SET [SESSION] var_ name = var_ value;
Session variables
@@[SESSION.]var_name
Description
• You can use the SET statement to set the values of system variables dynamically.
• If you don't specify the GLOBAL or SESSION keywords when setting the value of
a system variable, MySQL always attempts to set the session variable.
• If you don't specify the GLOBAL or SESSION keywords when getting the value
of a system variable, MySQL returns the session value if it exists. Otherwise, it
returns the global value.
• The LOCAL keyword is a synonym for the SESSION keyword.
• You can use the DEFAULT keyword to set the value of a variable to the default
value that's compiled into MySQL.
• When specifying a number of bytes, you can't use suffixes (K, M , G), but you can
•
use expressions.
Figure 17-9 How to set system variables using the SET statement
512 Section 5 Database administration
oJ
Query l Administration - Options File x
Geom) LOQOnO lmcOB Net.worlang Advana-d Other Seax1ty Repbbon MylSAM Perlormana
D generalbJ Enaiill!lcJisableoe,enilog
E2] 1og~tput lhe destriabon for general ~ log and ,dew query log output
0 log-queries-oot-using-nlexes log queries that are executrd wlihout beiefit of arr, ndex 1P the slow query log tf it is open
log_ error = 11
/ rnurach/ mysql / error . log"
slow_ query_ l o g
slow_ query_ log_ file = "/ murach / mysql / slow.log"
Description
• Logs can help you monitor the database, find and fix errors, restore data, and optimize
your database.
• Log files can take a significant amount of disk space, and logging can compromise
the security of yow· data if you don't secure the log files properly.
• If you don't specify a directory for a log file, the file is stored in MySQL's data directory.
To specify a drive on a Windows system, you just code the drive letter at the
beginning of the path like this:
log_bin="c:/murach/mysql/bin-log"
To specify a drive on a Unix/Linux system, you code the Volumes directory and
the name of the drive at the beginning of the path like this :
log_bin="volumes/archive/murach/mysql/bin-log"
In this example, Archive is the name of the drive.
Unfortunately, you can't specify a directory for the binary log on a macOS
system. If you attempt to do that, the server won't start. As a result, if you're
using macOS, you must store your binary log files in the default directory.
# deletes binary log files that are more than 7 days old
expire_ logs_ days = 7
# writes queries to the slow query log if they take longer than 5 seconds
long_ query_ time = 5
Description
• You can use any of the techniques for setting global system variables that are
described in this chapter to set logging options.
1 1
l¼ i1ifi'sl1·':¥1thii-i·}""l~-------------------------------
::
Q All O lnnoOB
Tlmestarrc> Thread Type ~~ ~
2018· l 1--06Tl8:S8:44 0 Warning) [MY-0. 'NO_ZERO_OATF, NO_ZBlO_IN_OATE' and 'EAAOR_FOR_DMSION_BY_ZERO' sql modes shou. ..
2018· 11-06TI8;58:44 0 System] [MY·OL
Warning) {MY--0.
C:\Program RlesV,,ySQL\MySQL Server8.0\bln\mysqld.exe (mysqld 8.0.13) starting as process
CA cert1fiate ca.pem ls self signed.
L
2018· 11-06T18:58:58 0
2018·11·06T18:58:S8 0 System) {MY--OL_ C:\Program FilesV,,ySQL\MySQl Server S.O\b111\mysqld.exe: recady for connections. Version: '8.0....
2018· 11~06TI8:58:58 0 System} {MY·Ol. XPlugfn ready for connections. Bind-address: '::' port: 33060
2018-11- 08T20:42;05 0 SyS"tem) (MY·Ol._ C:\Program Rles\MySQL\MySQL Server 8.0\brn\mysqld.exe: Normal shutdovm.
2018·11-08T20:42!32 0 System) [MY-0 L_ C:\Program Files\MySQL\MySQL Serrer 8.0\bin\mysqld.exe: Shutdown complete (mysqld 8.0.13..
2018·11--08T20:44:09 0 Warning) [MY--0... 'NO_ZERO_OATE', 'NO_ZERO_IN_OATc aod 'EAAOR_FOR_OIVISION_BY_ZERO' sq! modes shou...
2018·11--08120:44: U 0 9;stem} (MY-Ot C:\Prooram Files\MySQL\MYSQL Server8.0\bm\mysqld.exe (mysqld 8.0.13) rtartlng 1s process
2018· 11-08120:'17: 16 0 Warning} (MY--0... CA certiflcate ca.pem ts self signed.
How to view the log files when they are written to tables
The general log
SELECT*, CHAR(argument) AS argument_ text FROM mysql.general_ log
event_time user_host thread_id server_id command_type argument argument_text
,• • •
2019-01-10 11:47:25.763313 [root] @localhost [:: 1] 15 1 Comect
■
Description
• By default, the general, error, and slow query logs are stored in text files. As a
result, you can use any text editor to open them and view them.
• You can also use MySQL Workbench to view logs. To do that, select the
Server➔ Server Logs item from the menu system. Or, select the Server Logs item
from the Administration tab of the Navigator window. Then, click the tab for the
log file.
• If you configure your system so it stores the general and slow query logs in tables,
you can use MySQL Workbench to view these tables, just as you would use it to
view a log file. In addition, you can use a SELECT statement to view them.
DELI MITER //
Description
• It's generally considered a good practice to disable any logs that you don 't need.
• You can manually manage the text-based log files (general, error, and slow query) by
deleting and renaming log files.
• You can automatically manage text-based log files (general, error, and slow query)
by creating batch files (Windows) or bash files (macOS or Unix/Linux) that run on a
specified schedule.
• If you send the output of the general and slow query logs to a table, you can create
an event that uses SQL statements to manage the log tables.
• You can' t just delete files from the binary or relay log, since an index is used to keep
track of the files in these logs. However, you can set the expire_logs_days system
variable to delete files from the binary log after a specified number of days.
Perspective
In this chapter, you were introduced to the responsibilities of a database
administrator. In addition, you learned how to perform some of these respon-
sibilities. For example, you learned how to monitor the server, configure the
server, and work with log files.
In the next two chapters, you'll learn how to perform two more critical
responsibilities of a DBA. First, in chapter 18, you'll learn how to secure
a database. Then, in chapter 19, you'll learn how to backup and restore a
database.
Although this isn' t everything a DBA needs to know, this is enough to
get started with the administration of many types of databases. In addition,
it provides the background that you need for learning more about database
administration on your own.
Terms
database administrator (DBA) slow query log
database replication binary log
master relay log
slave process
configuration ftle mysqld program
data file MySQL daemon
log ftle status variable
general log system variable
error log
Exercises
1. Start MySQL Workbench and open the Client Connections window. If the
process list isn't displayed, click on the Refresh button in the lower right
corner to display it. Review the list to see that it includes two processes for
the current database. Then, return to the Home tab, open another connection
for the root user, and select a different database as the current database. Next,
return to the Client Connections window to see that it includes two additional
processes for the new connection.
2. Use Workbench's Server Variables window to view these status variables:
connections, threads_connected, bytes_received, and bytes_sent. Read the
descriptions for these variables to get an idea of what they do.
3. Use Workbench's Se1-ver Variables window to view the system variables
named basedir and datadir. Note the paths to these di1·ectories. Then, view
the system variables named log_error and log_bin. Note whether the log_bin
variable is set to a value of ON or OFF and whether the log_error variable is
set to the name of an error log, indicating that it is on.
Chapter 17 An. introduction to database administration 521
GRANT ALL
ON ap.*
TO ap_ admin@localhost;
Description
• You use the CREATE USER statement to create a user that has no privileges.
• You use the GRANT statement to grant p1ivileges to a user.
• You use the SHOW GRANTS statement to view the privileges for a user.
• For a partial list of privileges that can be granted, see figure 18-2.
A summary of privileges
Figure 18-2 summarizes some of the common privileges that a database user
can have. To strut, a user can have privileges to work with the data that's stored
in a database . These privileges allow a user to execute DML statements, such
as the SELECT, UPDATE, INSERT, and DELETE statements. They also allow
a user to execute stored procedures and functions. These are the most common
types of privileges, since most users need to be able to work with the data that's
stored in a database.
A user can also have privileges to modify the definition of a database. These
privileges allow a user to execute DDL statements such as the CREATE TABLE,
ALTER TABLE, DROP TABLE, CREATE INDEX, and DROP INDEX state-
ments. These privileges are common for administrative users of a database such
as database administrators and programmers, but they aren't commonly granted
to the end users of a database.
In addition, a user can have privileges to work with the stored programs of a
database. These privileges allow a user to execute the statements that you learned
about in chapters 15 and 16. For example, the CREATE ROUTINE privilege
allows a user to execute the CREATE PROCEDURE and CREATE FUNCTION
statements.
Chapter 18 How to secure a database 527
Description
• The privileges a user has to work with a database control the operations that the
user can perfonn on the database.
• Privileges for working with the data in a database are typically given to all users of
the database, include end users.
• P1ivileges for modifying the structure of a database are typically given to database
administrators and programmers.
The privileges you learned about in part 1 of figure 18-2 are called obj ect
privileges because they allow the user to create and work with database objects,
such as tables, views, and stored procedures. The exact privileges that are avail-
able for an object depend on the type of object. In contrast to object privileges,
administrative privileges allow the user to create new user accounts and roles,
show the databases available from the server, shut down the server, and reload
the tables that store the privileges for users. These privileges are listed in the first
table in part 2 of this figure.
The second table lists some other privileges you '11 use frequently. The ALL
privilege grants all privileges available at the specified level except the GRANT
OPTION privilege. In general, you only grant the ALL privilege to users like
database administrators or programmers. In some cases, you may also want
to grant these users the GRANT OPTION privilege. If yot1 do, they can grant
privileges to other t1sers.
The USAGE privilege doesn't grant any privileges to a user. In most cases,
you'll use this privilege when you want to give a user the ability to grai1t privi-
leges to other users. In that case, this privilege indicates that the existing privi-
leges for the user shouldn't be changed. You' 11 see an example of how this works
later in this chapter.
Before you go on, you should know that MySQL provides many privileges
other than the ones shown here. As a result, if the privileges presented in this
chapter aren' t adequate for your security needs, you can refer to the MySQL
Reference Manual for more information. To get started, you can search for
''privileges provided'' or ''privileges''. You can also use the SHOW PRIVILEGES
statement to view a list of all the privileges that are available.
Chapter 18 How to secure a database 529
Administrative privileges
Privilege Description
CREATE USER Create new user accounts.
CREATE ROLE Create a new role.
RELOAD Reload the tables that store the privileges for the users of the
database. This refreshes these tables if they have been modified.
SHOW DATABASES Show the names of all databases on the server.
SHUTDOWN Shut down the server.
Other privileges
Privilege Description
ALL [PRIVILEGES] All privileges available at the specified level except the
GRANT OPTION privilege.
GRANT OPTION Allows a user to grant his or her privjleges to other users.
USAGE No privileges. It can be t1sed to modify existing accounts
without changing the privileges for that account.
Description
• Object privileges allow the user to create and work with database objects such as
tables, views, and stored procedures. The privileges that are available for an object
depend on the type of object.
• Administrative privileges allow the user to create users, grant privileges, and
manage operations on the server. They are not specific to a particular database.
• To see a list of available privileges and their definitions, use the SHOW
PRIVILEGES statement.
Description
• You can use MySQL to grant privileges at four different levels, as shown in the first
table above.
• MySQL stores all users for the server and their privileges in grant tables in an
internal database named mysql.
Description
• You use the CREATE USER statement to create a user that has no privileges.
• When you code a username, you can specify the host that a user can connect from.
For more information, see figure 18-5.
• The PASSWORD EXPIRE clause determines how often the specified password
needs to be changed. If no option is coded, the password expires immediately.
• The PASSWORD HISTORY clause determines how many of the most recent
passwords can't be reused.
• The PASSWORD REUSE INTERVAL clause deter1nines the number of days after
which a previously used password can be used again.
• You can use the RENAME USER statement to change the name of a user.
• You can use the DROP USER statement to drop a user.
After you use the CREATE USER statement to create a user, the user has no
privileges. However, you can use the GRANT statement to assign privileges to
the user. You'll learn more about using this statement in figure 18-6.
The sixth example in figure 18-4 uses the RENAME USER statement to
change the name of the user namedjoel @localhost to joelmurach @localhost. If
this user has privileges, the privileges are transferred to the new name.
The last two examples use the DROP USER statement to drop the users
namedjoelmurach@localhost andjane@ %. These statements delete the user
accounts and their privileges from the mysql database. Of these statements,
the second includes the IF EXISTS clause. That way, if the user doesn't exist,
the statement generates a warning instead of an error. This allows a script to
continue executi11g instead of being stopped. Before dropping users, remember
that they are for al] databases on the server. As a result, you should check with
anyone else who is using the server to make sure that the user isn' t needed.
A user that can only connect from the same server as MySQL
john@loca1host
The same user but with the wildcard character explicitly coded
john@ '% '
Description
• If you want to specify the host that a user can connect from, you can code the
username, followed by the @ character, followed by the hostname.
• If you specify a user without specifying a hostname, MySQL uses a percent sign
(%) as a wildcard character to indicate that the user can connect from any host.
• The use1name and hostname do not need to be quoted if they are legal as unquoted
identifiers. Quotes are necessary to specify a usemame string containing special
characters such as a dash ( - ), or a hostname string containing special characters or
wildcard characters such as a percent sign(%).
• To quote a usemame or hostname, you can enclose it in single quotation marks ( ' ),
double quotation marks("), or backticks ( ' ).
A statement that gives a user the ability to grant privileges to other users
GRANT USAGE
ON*.*
TO anne@localhost
WITH GRANT OPTION
Description
• You use the GRANT statement to grant privileges to a user.
• With MySQL 5.7 and earlier, a user account was created if it didn't already exist
and a passwo1·d was specified using the IDENTIFIED BY clause. With MySQL 8.0
and later, a user must already exist before privileges can be granted.
• The ON clause determines the level at which the privileges are granted. You can use
the asterisk(*) to specify all databases or tables. If you don't specify a database,
MySQL uses the current database.
• The WITH GRANT OPTION clause allows the user to grant their privileges to other users.
the first example that uses this clause, though, the USAGE privilege is speci-
fied. As a result, no additional privileges are given to the user. If you want to
grant additional privileges to a user, you can code those privileges instead of the
USAGE privilege.
A statement that shows the privileges for a user from any host
SHOW GRANTS FOR jim
--
►
Grants fur jirn@o/o
GRANT SELECT, INSERT, UPDATE, DEl.ETE, CREATE, DROP, R.a.OAD, SHUTDOWN, •..
GRANT BACKUP_AOMIN,BINLOG_ADMIN,CONNECTION_ADMIN,ENCRYPTION_m_...
A statement that shows the privileges for a user from a specific host
SHOW GRANTS FOR ap_ user@localhost
Grants for ap_user@localhost
► GRANT USAGE ON • .•To ·ap_user · @' localhost·
GRANT SELECT, INSERT, UPDATE, Da.ETE ON · ap ·. *TO · ap_user@·locathost·
Description
• You can query the User table in the mysql database to get a list of users for the
current MySQL server.
• You can use the SHOW GRANTS statement to display the privileges for a user.
Description
• You can use the REVOKE statement to revoke privileges from a user.
• To revoke all privileges, you m ust have the global CREATE USER privilege.
• To revoke specific privileges, you must have the GRANT OPTION p1·ivilege and
you must have the privileges that you are revoking.
Note
• To completely delete a user account, use the DROP USER statement described in
figure 18-4.
A SELECT statement that selects all users that don't have passwords
SELECT Host, User
FROM mysql.user
WHERE authentication_ string = ••
Host User
-;; - - ii(!t!i I
Description
• You can use the ALTER USER statement or the SET PASSWORD statement
to change a password. ALTER USER became available with MySQL 5.6 and
is prefe1Ted over SET PASSWORD because it's more widely used across other
database platforms and can be used to control the expiration and reuse of passwords.
• To change the password for another user's account using the ALTER USER state-
ment, you must have the CREATE USER privilege or the UPDATE privilege for
the mysql database. With the SET PASSWORD statement, you must have the
UPDATE privilege for the mysql database.
• You can change the current user's password by using the ALTER USER statement
with a USER function or the SET PASSWORD statement without a FOR clause.
• The PASSWORD EXPIRE, PASSWORD HISTORY, and PASSWORD REUSE
INTERVAL clauses of the ALTER USER statement work just like they do for
the CREATE USER statement.
• To be sure you 've assigned passwords to all users, you can select data from the
User table of the mysql database for all users without authentication strings
(MySQL 5.7 and later) or passwords (MySQL 5.6 and earlier).
Description
• A role is a collection of privileges that you can assign to one or more users. R oles
were introduced with MySQL 8.0.
• You t1se the CREATE ROLE statement to create one or more roles. For this to work,
the user 1nust have the CREATE USER or CREATE ROLE privilege.
• If you code the [F NOT EXISTS clause on the CREATE ROLE statement, a warning is
generated instead of an error if the role already exists.
• You use the GRANT statement to grant privileges to a role. The syntax of this
statement is the same as for granting privileges to users except that yotLname one or
more roles.
• You also use the GRANT statement to assign users to roles. When you assign a user to
a role, the user is granted all the privileges of that role. If you code the WITH ADMIN
OPTION clause, the user can also grant the roles to other users.
• You use the SHOW GR ANTS statement to display the privileges associated with a
role. The syntax of this statement is the same as for displaying the privileges for a
user, except that you name a role.
Part 2 of figure 18-11 presents some additional statements for working with
roles. To start, it shows how to use the SET DEFAULT ROLE statement to set
the roles that are activated by default when a user connects to the se1·ver. If you
specify NONE on this statement, none of the roles that the user is assigned to
are activated. In that case, the user only has the privileges that he or she has
been assigned directly. If you specify ALL, the user is given all of the privileges
of all of the roles that he or she has been assigned. And if you specify one or
more roles, the user is given the privileges of all those roles. In the example
in this figure, the users named john and jane are assigned a default role of
invoice_entry.
Note that you can also assign one or more default roles to a user when you
create the user. To do that, you use the DEFAULT ROLE clause of the CREATE
USER statement.
The SET ROLE statement allows a user to change the roles that are currently
active during a session. This is particularly useful if yot1 need to try different
roles during testing to be sure they provide the privileges a user needs. You
can code the NONE or ALL option or a list of user roles on this statement just
like you can on the SET DEFAULT ROLE statement. You can also code the
DEFAULT option to change the active roles to the defaults specified by the
SET DEFAULT ROLE statement. And you can code the ALL EXCEPT option
followed by the names of one or more roles to activate all of the roles that a user
is assigned to except for the ones you name. In this figure, the SET ROLE state-
ment si1nply sets the active role to the invoice_entI-y role.
If you change the active roles during a session, you may at some point
want to display the roles that are currently active. To do that, you can use the
CURRENT_ROLE function as shown in this figure.
To revoke privileges from one or more roles, you use the REVOKE
statement just like you do to revoke privileges from users. In this figure, the
REVOKE statement revokes the UPDATE privilege on the Invoice_Line_Items
table from the invoice_entry role.
You also use the REVOKE statement to remove users from roles. On this
statement, you name the roles that you 're removing the users from, and you
name the users you're removing on the FROM clause. In the REVOKE state-
ment in this figure, the user named john is removed from the invoice_entry role.
To drop one or more roles, you list the1n on the DROP ROLE statement. In
this figure, the invoice_entry role is dropped. You can also code the IF EXISTS
clause on this state1nent. Then, if the role doesn't exist, a warning is generated
instead of an error.
Chapter 18 How to secure a database 549
Description
• You use the SET DEFAULT ROLE statement to name the default roles for a user.
These roles are activated by default when the user connects to the server. To set the
default role for another user, you must have the CREATE USER privilege.
• A user can use the SET ROLE statement to change the active role for a session.
• You use the REVOKE statement to revoke privileges from a role or to remove users
from a role.
• You use the DROP ROLE statement to delete one or more roles. To use this state-
ment, you must have the DROP ROLE or CREATE USER privilege.
• If you code the IF EXISTS clause on the DROP ROLE statement, a warning is
generated instead of an error if the role doesn't exist.
Figure 18-11 How to create, manage, and drop roles (part 2 of 2)
550 Section 5 Database administration
Note
• Some versions of Workbench 8.0 may identify the first SET DEFAULT ROLE
statement in this script as a syntax error. However, the syntax for this statement is
correct, and it should run correctly.
El(Jwe Password
(j]
Workbench provides some predefined administrative roles that you can use
to quickly set up privileges for database administrators, managers, and designers.
Before you begin working with these roles, you should know that they are not
the same as the roles that you learned how to create with SQL statements earlier
in this chapter. In other words, they aren't roles that are stored in the mysql
database, and they can't be manipulated using SQL statements. Instead, they are
a Workbench feature that allows you to quickly assign privileges to users.
To view the Workbench roles for a user, you select the user from the
Administrative Roles tab of the Users and Privileges window as shown in the
screen in part 2 of figure 18-13. Then, you can select the roles that you want to
assign the user to, and the privileges assigned by those roles will be selected at
the right side of the tab. Note that these are global privileges, so they apply to
all databases on the server. Because of that, you'll want to be careful who yot1
assign to these roles.
Chapter 18 How to secure a database 555
ljJ
J.
Use-Accou"lts
Local instance MySQl.80
Users and Privileges
~tails for 1t000Untjoel@localbost
User
- -From
-Host
----, Logn Account Llnits AdmirutratiVe Roles Schema Pnvteges
anne localko,;t
ap_ddmln Joca host Role Description Globall'nvleges
a1>_tester toca host 0 OBA grants the rights to oerform all task.s r;;?j JILTER
&p_USl!f loca bo£t 0 MaintenanceAdmln grants rights needed to mail\tain server E2J ALTER ROUTINE
lnvo1te_ei,irv % 0 Proc.essAdmin rights needed to assess, monitor, and loll arry 11s er proc 0 CREATE
Jane •4 0 UserAdm1n grants rights to create users logins and rts~r passwords f;2J CREATEROUTINE
Jim % 0 SecurltyAdmin rights to manage logins and Qtfnt and re,,oke server an 0 CREATETABLESPACE
Joel loca host 0 MomtorAdmin mln,mum set of rlghts needed to morutor server 0 CREATETEMPORARYTABLES
John % 0 DBManager grants full nohts on all databases E2J CREATE USER
mysolJnfoschVM tocalhost 0 DBDesigner rights to create and reverse engineer arry database sd,e r;;?J CREJITE VIE\V
mvsot.sess,on Jocalhost 0 RephcabonAdmln rights needed to setup and manage repllutlon 0 DELETE
rnysql.sys localhost 0 BackupAdm.n rrummal rights needed to backup arry database 0 DROP
root toca'host 0 EVENT
St~ve. % 0 EXECUTE
0 Fllf
E2J GRANT OJ7TION
E2J INDEX
E2J INSERT
E2J LOCK TABLES _ v
< > < >
Description
• To display the Users and Privileges window, select the Users and Privileges ite1n
from the Navigator window. If necessary, click the Administration tab to display
this item.
• To change a user's name, password, or host access options, use the Login tab. You
can also use this tab to add or remove a user account, to expire a user's password,
or to revoke al I privileges for a user.
• To view the database privileges for a user, use the Schema Privileges tab. You can
also use this tab to change privileges and to add and remove host/schema access
options.
• To view the administrative roles that a user is assigned to and the global p1ivileges
granted to those roles, use the Administrative Roles tab. You can also use the check
boxes on this tab to assign or revoke the privileges of the administrative roles.
These roles are defmed by Workbench and are not stored as roles in the m ysql
database.
WE ~~: I:=JMI!I:....__-.=.;::........:=============:!
Ca• o«ton Method: St:anda rd (TCP/IP) v
Typeanarnef'Or thecomedlon
Method to use lo ~ 1o the RDBMS
p ~ SSL Advatnd
Hostname:
...__ _ _ _ _ ___.
Pot 1.__
3306
_
I
Name or IP address Qf1he server host - and
_ ___._ TCP/lPport.
MySQLCo
Local insta
root
localhost33<
Description
• To create a connection for a user, display the Home tab, click the (±) icon to the
right of MySQL Connections, and enter the connection information in the resulting
dialog box. This includes a name for the connection and a name for the user.
• To connect as a user, click on the connection for the user in the list of connections,
and enter the password for the user if necessary.
When you connect as a user, the name for the connection is displayed in
the tab for the connection. Then, you can only use that connection to view the
databases and tables that the user has privileges to view. In part 2 of figure
18-14, for example, you can see that the user namedjane only has access to five
tables in the AP database. In addition, you can only 1nodify the databases and
tables that the user has privileges to modify.
To make sure that the user's privileges are working correctly, you can run
SQL statements. In this figure, for example, I tried to insert a row into the Terms
table. Because the user only has the SELECT privilege on this table, though,
MySQL Workbench displayed an error indicating that the statement was denied.
Chapter 18 How to secure a database 559
Nav19ator
SCHEMAS
6] ·,; @} &1 @ I@ ' -
,.,,.._____________________________
8 - 'i P. ~ I 1.Jmi to lOOOrows
q_ IF,J!!,r obJKl5 frusERT TIITO te1"111S
VALUES ( , 'net due 120 days' , );
• i;} ap
't' Tables
► 9ffleral_ted9er_accounts
► lnvola_archlve
► Ii 1nvo1ce_J1ne_1tems
Connection name
► ■ invokes
► ii terms
► vendor_contacts
► El vffldois
Vlew5
Stored Procedures
f11nctlons
<
(Mp,.,
Admlnlstnrtion Sd>i!mas
(j Action Ol.tpu
Jnformation ~ T- AalDn Mtiwg• OuriitlOn / ktcl>
0 1 15 31 20 INSERT JNTOll!nns VALUES (6. 'net cile 120days'. EirorU>de· 1142- INSERT canmand denied to U9et '. 0 000 see
Description
• When you connect as a user, the name for the connection is displayed in the SQL
Editor tab.
• When you connect as a user, you can only view the databases and tables that the
user has privileges to view, and you can only modify the databases and tables that
the user has privileges to modify.
Perspective
Although managing security can be complex, MySQL provides tools to
simplify the job. In this chapter, you learned how to manage security by writing
SQL statements, and you learned how to use MySQL Workbench to work
with users and manage privileges. Once you 're familiar with both of these
techniques, you can use the one that's easiest for the security task at hand.
In addition to the skills presented in this chapter, you may also need to
secure MySQL's file system if the server is running on a computer that has
multiple users. That way, other users who log in on that computer can't access
any of the MySQL files that may contain sensitive data. That includes the data,
log, and configuration files you learned about in chapter 17. Because the proce-
dure for securing the file system varies depending on the operating system, this
information isn't presented in this book.
You may also need to use SSL to secure the usemames and passwords
of users who are allowed to connect remotely. In most cases, users connect
locally. For example, a web server often runs on the same machine as the
MySQL server. As a result, users of the website use a local connection to
connect to MySQL. If the MySQL server is on a different machine, though,
you can learn about providing secure connections by looking up ''Using
Encrypted Connections'' in the MySQL Reference Manual .
Terms
privilege
object privileges
administrative privileges
global privileges
database privileges
table privileges
column privileges
grant tables
role
Chapter 18 How to secure a database 561
Exercise
In this exercise, you will create two users and a role. You will grant privileges
directly to the first user, but you will grant privileges to the second user by granting
privileges to the role and then assigning the user to that role. In addition, you will
use MySQL Workbench to connect as the two users and test their privileges.
1. Use MySQL Workbench to connect as the root user.
2. Write a script that creates a user named ray@localhost with a password
of ''temp'' that the user must change every 90 days. This user should have
SELECT, INSERT, and UPDATE privileges for the Vendors table of the AP
database; SELECT, INSERT, and UPDATE privileges for the Invoices table;
and SELECT and INSERT privileges for the Invoice_Line_Items table. This
user should also have the right to grant privileges to other users. Run the
script in MySQL Workbench.
3. Check the privileges for ray@localhost by using the Users and Privileges
window of MySQL Workbench.
4. Use MySQL Workbench to create a connection for the user named
ray@localhost and then connect as that user. Use the Navigator window
to see which databases and tables this user can view.
5. Run a SELECT statement that selects the vendor id column for all rows in the
Vendors table. This statement should succeed.
6. Write a DELETE statement that attempts to delete one of the rows in the
Vendors table. This statement should fail due to insufficient privileges.
7. Switch back to the tab for the connection for the root user.
8. Grant the UPDATE privilege for the Invoice_Line_Items table to ray @local-
host, and give the user the right to grant the same privilege to other users.
9. Write a script that creates a user named dorothy with a password of ''sesame''.
Then, create a role named ap_user, and grant this role privileges to select, insert,
and update data from any table in the AP database. However, don't grant this role
privileges to delete any data from the database. Assign the user named dorothy to
this role.
10. Check the privileges for dorothy by using the SHOW GRANTS statement
11 . Use MySQL Workbench to create another connection for the user named
dorothy and then connect as that user.
12. Run a SELECT statement that displays the active roles for the current user. This
should display NONE.
13 . Close the tab for the connection for the user named dorothy, and switch back to
the tab for the connection for the root user.
14. Set the default role for the user named dorothy to ap_user.
15. Connect as do1·othy again and then display the active roles using the same
statement as in exercise 12. This time, the ap_user role should be displayed.
How to back up
and restore a database
When you work with a database that stores important data, you should have
a plan for backing up that database regularly. Then, you need to execute that
plan. That way, if the hard drive that stores the database fails, you can restore
the database and minimize the amount of data that's lost. In this chapter, you '11
learn how to back up and restore a database.
You'll also learn some skills that are related to backing up and restoring
a database. For example, you'll learn how to import data from a text file and
export data to a text file. In addition, you'll learn how to check and repair
tables, which can save you from having to restore a table or database.
A backup strategy
Figure 19-1 starts by presenting a strategy for backing up databases. MySQL
provides for two types of backups. A full backup includes the structure and data
of a database. To create a full backup, you can use the mysqldump program as
described later in this chapter. This creates a SQL script file that can be used to
recreate the database. You should create a full backup at regular intervals. For a
medium-size database fo1· a website, for example, you might want to create a full
backup once a week.
When you use the mysqldump program, it locks all tables so other users
can't update the database while it's being backed up. As a result, it's a good
practice to schedule this backup at a time of low traffic for the database.
An inc,·ementctl backup contains changes that have been made since the last
full backup. With the backup strategy shown in this figure, the binary log must
be enabled as described in chapter 17 to create the incremental backups.
When you use this strategy, you shouldn't store you1· backup files (SQL
scripts or log files) on the same hard drive where the MySQL server is running.
If you do, those backup files will be lost if that hard drive fails. As a result, it's a
good practice to configure the binary log so it writes to a directory on a different
hard drive. This has the added benefit of balancing the load between two hard
drives.
When you create a backup strategy, don't forget that the database named
1nysql stores information about the users and privileges for all databases on the
server. As a result, you typically want to include this database in your backups.
A restore strategy
The goal of backing up your databases is to allow you to restore them to
theu: exact state at any specified point in time. This is known as a point-in-time
recovery (PITR). To restore a database to a point in time, you can use the last full
backup as described in figure 19-1. Then , you can use the binary log to restore
the database from the time of the last full backup to the specified point in time.
CJ1,111ter 19 Hol,. lo back 11p w1d re.r;tore a dc1tabase 565
2. Use the my qlbinlog program to execute all tatements in the binary log that
occurred afler the last full backup.
Description
• It ·s in1portant for the databa..4ie administrator to regularly ba,ck 11p the databa e.
Then. u· the database becon1es corrupted tl1e databru e admini. trator can u e the
backup to restore U1e database.
• Afi,ll backltp includes the tructure and content ot· a database. You hould perform
full backups acc,o rding to a regular schedule.
• An i1Jl·re111e111al bal·kup onl)1 contains changes that have been made to r.he tructt1re
and content of a databru e ince the last full backup.
• You otten want to include the database nan1ed n1ysql iI1 )'Our backups. since thi
database stores inforn1atioo about the users and privileges f'or all d3tabase on the
senfer.
• You houldn 't tore your backup files (SQL cripts o r log files) on tl1e ame l1ard
drive v.rhere the ~{ySQL en'er is running. If you do tho e back'Up file will be lost
along with the database if that hard dri,,e 1·ai1s.
• A JJOi11t-in-ri1t1e reco,·ery· (Pl TR allo\V you to re tore the data up to n.D}' pecified
point in time.
Description
• You can use the mysqldump program to back up, or dump, one or more databases
into a SQL script file.
• If you get an error that indicates that access is denied, you may need to start the
command prompt as an administrator. In Windows, you can do that by
right-clicking on the icon that you use to start the Command Prompt window and
selecting the ''Run as administrator'' command.
• If a fu·ewall is running on your computer, it may attempt to block the mysqldump
program. However, if you allow the mysqldump program to access the database, it
should work proper!y.
• On a macOS system, you typically need to code a dot and slash (./) before the name
of the mysqldump program to specify that it's in the ct1rrent directory (the bin
directory).
select the databases you want to back up on the Object Selection tab, select the
''Export to Self-Contained File'' option, enter the path and name for the backup
file, and click the Start Export button. Note, however, that earlier releases of
Workbench had some bugs that sometimes prevented this feature from working
correctly. As a result, I recommend using the mysqldump program.
Another advantage of using the mysqldump program is that it's easier to
automate. Although the details for doing this vary depending on the operating
system, the same general principles apply to all operating systems. To start,
you create a script file that executes the mysqldump command. Then, you use
the operating system's task scheduler to execute that script file at a specified
interval. For more inforrr1ation on using the task scheduler with your operating
system, you can search the Internet.
--
-- Current Database: ' ap '
--
CREATE DATABASE /*!32312 IF NOT EXISTS*/ ' ap ' /*!40100 DEFAULT CHARACTER SET
utf8mb4 COLLATE utf8mb4 0900_ ai_ ci */;
Description
• These scripts use two dashes (--) to identify comments.
• These scripts surround code in the /* ! and */ characters to indicate that the code is
specific to MySQL. As a result, a MySQL server can use that code, but another type of
database server can ignore it.
• These scripts surround names with backticks ('). This allows for names that include
spaces.
using MySQL 4.01.00 or later. Finally, this script surrounds the name of the
database with backticks ('). Although this isn't necessary for the AP database,
it's required for names that include spaces or other special characters.
If you only generate a backup for a single database, the SQL file for that
backup won't include the CREATE DATABASE and USE statements. As a
result, if you want to recreate the entire database, you need to add these state-
ments to the script.
The script continues with the statements necessary to create the structure
and content for the database. That includes the tables of the database, as well as
the views, stored procedures, function s, triggers, and events. In part 2 of figure
19-3, you can see the statements for creating the Terms table. To start, a DROP
TABLE statement drops the table if it exists. Then, a CREATE TABLE state-
ment recreates the table.
Next, the script uses an INSERT statement to reload all the data into the
table. But frrst, it uses a LOCK TABLES statement to prevent other users from
writing data to this table while the script is executing. In addition, it uses an
ALTER TABLE statement to disable the indexes for the table. Then, after the
data has been inserted into the table, the script enables the indexes for the table.
This improves the performance of the insert operations. Finally, the script uses
an UNLOCK TABLES statement to allow other users to update this table.
After the SQL statements that create the database and its objects, this script
sets some system variables. To do that, it uses some of the user-defined variables
that were defined at the beginning of the script. Again, this usually works the
way you want, so you don't usually have to examine this code closely.
The last line of this script is a comment that indicates the point in time that
the mysqldump program finished creating this SQL ftle. If you need to restore
a database later, you can use this date/time value as the start time for the state-
ments that are stored in your binary log files.
Chapter 19 How to back up an.d restore a database 571
--
-- Dumping data for table ' terms '
--
LOCK TABLES ' terms ' WRITE;
/*!40000 ALTER TABLE ' terms ' DISABLE KEYS*/;
INSERT INTO ' terms ' VALUES (1, 'Net due 10 days',10),(2, 'Net due 20
days',20), (3,'Net due 30 days',30),(4, 'Net due 60 days',60),(5,'Net due 90
days',90);
/*!40000 ALTER TABLE ' terms ' ENABLE KEYS*/;
UNLOCK TABLES;
--
-- SQL statement for the table structure and data for all other tables
-- and any triggers associated with those tables
--
--
-- SQL statements for all views, stored procedures, functions, and events
--
/*!40103 SET TIME_ ZONE=@OLD_ TIME_ ZONE */;
Description
• The mysqldump program contains many advanced options that you can use to
control how it works.
• Many options that enable features also include a corresponding option for disabling
the option. These options usually begin with ''skip-''.
• For a complete list of options for the 1nysqldump program, look up this program in
the MySQL Reference Manual.
Multiple databases
mysql < /murach/mysql/backup-2019-01-10.sql -u root -p
Description
• You can use the mysql progra1n to restore one or 1nore databases by running the
SQL sc1ipt file that contains the database backup.
• Before you restore a database from a script file, it's generally considered a good
idea to back up the existing database in case the restore operation doesn't work
correctly.
• Before you restore a database from a script file, you can open the SQL file and
view it to make sure it does what you want. If it doesn't, you can edit this file.
• If you get an error that indicates that access is denied, you may need to start the
command prompt as an administrator.
• If a firewall is running on your computer, it may attempt to block the mysql
program. However, if you allow the 1nysql program to access the database, it should
work properly.
• On a macOS system, you typically need to code a dot and slash(./) before the name
of the mysql program to specify that it's in the cu1rent directory (the bin directory).
Figure 19-5 How to use a SOL script file to restore a full backup
576 Section 5 Database administration
For all databases using multiple binary log files (macOS and Unix/Linux only)
mysqlbinlog /murach/mysql/bin-log.[0-9]* I mysql -u root -p
Description
• You can use the mysqlbinlog program to execute statements in the log file for all
databases or for a specified database. You can also execute statements that fall
within a specified date/time range.
• If the statements you want to execute are stored in multiple binary logs, you should
specify all of them on the command prompt in sequence from the lowest numbered
log file to the highest numbered log file.
• On a macOS system, you typically need to (1) begin by coding the sudo command,
(2) code a dot and slash before the name of the mysqlbinlog program and the mysql
program, and (3) specify a path to the data directory. For example, you can execute
the frrst example shown above like this:
sudo . / mysqlbinlog .. /data/binlog.000001 I ./mysql -u root -p
• In addition, on macOS, you may find it helpful to specify a password like this:
sudo ./mysqlbinlog .. /data/binlog.000001 I ./mysql -u root
--password=sesame80
A tab-delimited file
The statement
SELECT*
INTO OUTFILE '/ProgramData/MySQL/MySQL Server 8.0/Uploads/vendor_ contacts.txt'
FROM vendor_ contacts
A comma-delimited file
The statement
SELECT*
INTO OUTFILE '/ProgramData/MySQL/MySQL Server 8.0/Uploads/vendor_ contacts.txt'
FIELDS TERMINATED BY',' ENCLOSED BY ,n, ESCAPED BY ' \\'
FROM vendor contacts
Description
• You can add an INTO OUTFILE clause to a SELECT statement to save the result set in
an output file.
• You can use the FIELDS clause to identify the character that's used to delimit columns,
the character that's used to delimit rows, and an escape character.
• On a Windows system, with MySQL 5.5 and later, you can usually store tl1e output file
in the Uploads directory shown above. On a macOS system, you can sometimes store
the outpt1t file in the /tmp directory, but it's usually easier to use MySQL Workbench's
export data feature.
Note that both of the examples in figure 19-7 store the output ftle in the
MySQL Uploads directory. With MySQL 5.5 and later, this is the only directory
that you can export a file to or import a file from by default. If you want to export
to or import from a different directory, you can change the secure_file_priv
system variable to that directory. Or, you can change this variable to an empty
value so you can export to and import from any directory. This was the default
with releases of MySQL before 5.5.
Note also that the directories in these examples are for a Windows system.
For macOS, you can sometimes store the output file in the /tmp directo1·y.
However, later versions of MySQL often don't allow storing output files in any
directory by default with macOS. In addition, it's difficult to enable this feature
by setting the secure_file_priv system variable. As a result, you may want to
look for other ways to export data, such as using MySQL Workbench's export
data feature.
How to use the LOAD DATA statement to import data from a file
The syntax
LOAD DATA INFILE file_path
INTO TABLE table_ name
[FIELDS [TERMINATED BY string]
[ENCLOSED BY char]
[ESCAPE.D BY char]]
A tab-delimited file
LOAD DATA INFILE
'/ProgramData/MySQL/MySQL Server 8.0/Uploads/vendor_ contacts.txt 1
INTO TABLE vendor contacts
A comma-delimited file
LOAD DATA INFILE
'/ProgramData/MySQL/MySQL Server 8.0/Uploads/vendor_ contacts.txt 1
INTO TABLE vendor_ contacts
FIELDS TERMINATED BY 1 , 1
ENCLOSED BY 1111
ESCAPED BY I \ \ I
Description
• You can use the LOAD DATA statement to load data from an input file into a table.
• The columns in the input file must match the columns in the table.
• The data in the input file must not conflict with the values of any unique keys that
are already stored in the rows of the table.
• You can also use the mysqlimport program to load data from an input file into a
table. For more inforrr1ation, see the MySQL Reference Manual.
Description
• The CHECK TABLE statement works for InnoDB and. My ISAM tables and views.
• All of the options except for FOR UPGRADE are ignored by the InnoDB engine.
This engine automatically performs a thorough check that detects most problems.
If it finds a problem, the server shuts down to prevent the problem from getting
worse.
• The FOR UPGRADE option is useful if you upgrade to a newer release of MySQL.
In that case, a change in the new release might make data from the old release
incompatible with the new release.
• The CHECK TABLE statement works only when the server is running.
Description
• To repair a MyISAM table, you can use the REPAIR TABLE statement. This state-
ment works only when the server is running.
• The REPAIR TABLE statement checks the table to see whether an upgrade
is required. If so, it automatically pe1forms the same upgrade operation that's
provided by the FOR UPGRADE option of the CHECK TABLE statement.
• It's generally considered a best practice to make a backup of a table before
performing a table repair operation, since a table repair operation can so1netimes
cause you to lose data.
• To repair an InnoDB table, you use the procedtrre shown above. The
innodb_force_recovery system variable allows the server to restart so you can back
up and then restore the database that contains the corrupt tables.
• If restoring the database doesn' t fix the corrupted tables, you can use your last full
backup and your incremental backups to restore the database.
Description
• The mysqlcheck program uses the CHECK TABLE and REPAIR TABLE state-
ments to check and repair one or more tables.
• Most of the check and repair options are ignored by the InnoDB engine.
• You can only use the mysqlcheck program when the server is running.
Description
• The myisamchk program can check and repair MyISAM tables.
• You should only use the myisamchk program when the server is stopped.
Perspective
In this chapter, you learned how to back up your databases and how to
restore them if necessary. If you combine these skills with the skills you
learned in the previous chapter for securing a database and working with user
accounts, you are on your way to becoming a successful database adminis-
trator. Of course, there's much more to learn than what's presented here. If
you're interested in learning more, I recommend you get a book specifically on
database administration.
Terms
back up a database
restore a database
full backup
incremental backup
point-in-time recovery (PITR)
dump a database
export a database
import a database
delimit columns or rows
tab-delimited file
comma-delimited file
escape character
Chapter 19 How to back up an.d restore a database 591
Excercise
In this exercise, you back up a database to create a backup script file. Then, you
make some changes to the database and delete it. Finally, you restore the database
from the backup script and the binary log file.
Back up a database
I. If it isn't already enabled, enable binary logging as described in chapter 17.
2. Start a command prompt and use the mysqldump program to create a full backup
of the AP database. This backt1p should include the structure and data for the
database, as well as any stored routines, functions, and events for the database.
After the dump, leave the command prompt open.
3. Start MySQL Workbench and open the backup script that was created by the
mysqldump program. Make sure that this script contains all the SQL statements
needed to restore the structure and data of the database. If necessary, add the
CREATE DATABASE statement that creates the AP database and the USE state-
ment that selects it.
4. Use MySQL Workbench to execute an INSERT statement that inserts one row
into the Vendors table of the AP database, and note the time on your computer
that this statement is executed.
5. Wait until the time on your computer changes to at least the next minute. Then,
use MySQL Workbench to delete the row you just added.
Restore a database
6. Switch back to the command prompt and use the mysql program to run the
backup script. This should restore the entire AP database.
7. Identify the highest numbered file for the binary log. Then, switch back to
the command prompt and use the mysqlbinlog program to add the row to the
Vendors table that you inserted in step 4. To do that, you'll need to include start
and end times that include the INSERT statement but omit the DELETE state-
ment you executed in step 5.
•
IX
Notes
• If you install products in addition to MySQL Server and MySQL Workbench, your
con1puter 1nay be missing a requirement for one or more products. Then, a Check
Requirements page is displayed listing those requirements. If the requirement
indicates that it must be resolved mantially, you can click on it for information on
how to do that.
• You can also install MySQL Server and MySQL Workbench separately. For more
infor1nation about that, you can visit the Downloads page of the MySQL website.
• To make it easy to start MySQL Workbench, you may want to pin the program to
your taskbar or add a shortcut to your desktop.
Figure A-1 How to install MySQL Community Server and MySQL Workbench
596 Appendix A How to install the software for this book on Windows
Directory Contains
db_ setup The SQL script that's used to create the three databases for this book.
book_ scripts The SQL scripts for all of the examples presented in this book.
ex_ solutions The SQL scripts for the solutions to the exercises that are at the end
of each chapter.
diagrams The MySQL Workbench file for the diagram that's presented in chapter I 0.
java The source code for the Java application that's presented in chapter 1.
php The source code for the PHP application that's presented in chapter I .
The databases
Database Description
ap The AP (Accounts Payable) database. This is the
primary database that's used in this book.
om The OM (Order Management) database. This database
is used in some of the examples in this book.
ex The EX (Exam"p les) database. This database contains
several tables that are used for short examples.
Description
• All of the source files described in this book are in a self-extracting zip ftle (an exe
file) that can be downloaded from www.murach.com.
Figure A-2 How to install the source files for this book
598 Appendix A How to install the software for this book on Windows
Navigator
SOiEMAS !:\'° Lini1 1o 1000nrM • --o I 1J o. rn: ~
0. !Filter objem
,.. T ~ -
► om
► ex 9
► ap 10 C Execute SQL Script
► !}YS ll • DROP DATABASE IF E~
12 • OlEATE DATABASE ap;
button
13
14 e the
15 •
16
USE ap; Open a SQL
17 <~ene l • Script File button
E•Er~R:::u:~~~::eral_led:_accounts PRIMARY KEY,
21 I account:description VARCHAR( ) IJHIQUE V
< >
t : - . - - - ·- ·-
OulPul
·- ·----------------===------=--------------------------•·-1
di Actiorl ~ •
Adm,mstrabon Schemas M&,g♦
• Time - Dum,on / Flld'I "
lllformabo11 0 51 111346 CREATE D.A.TABASEom 1 row(s) affected 0.516 sec
No objttl ~k-cted
0 52 111347 USEom 0 row(s) affected 0 000 ,ec
0 53 11:13.47 CREATETABL.Ecuatomen1 ( cualomer_ld INT . 0 row(s) affected 2.484eec
0 54 11·1349 CREATE TABLElems ( lem_d INT NOT Orow(s) affected 2 469sec
0 55 11·13:52 CREATETABLE~( order...Jd INT NO... 0 row(s) affected 3.078sec
0 56 11:13:55 CREATE TABLE order_datais I order_d INT _ 0 row(sl affected 1.578sec
0 57 11.13.56 INSERT INTO ruslome,s VALUES (1.'l<orah'.'Blanca'.... 25 mw(s) affected Reccrds. 25 Dlc,licates. 0 Wa,mg .. 0.266 sec
0 58 1113.57 INSERTINTOlemsttem.)d.tile,llrtl!ll,uni.J)rice}VAl... lOrow(s)alfectedRecxnls. 10 ~ates. 0 Wa,mg ... 0531,ec
ObJea Info SesSJon 0 59 11.13.57 INSERT INTO Oldels VALUES (19. 1. "2012-10-23'. '2... 47 row(s)affected Recads. 47 [AJpk:ates. 0 Warmg .. 1.047 sec
Description
• For the create_databases.sql file to run, the database server must be running. By
default, the database server is automatically started when you start your computer.
If it isn't running on your system, you can start it as described in chapter 2.
Figure A-3 How to create and restore the databases for this book
• I
IX I
Instances Configuration
Initialize Database
Uninstall
Description
• You can use the M ySQL preference pane to start and stop MySQL and to control
whether MySQL starts automatically when you start your computer.
• To display the MySQL preference pane, use the Apple ment1 to display the System
Preferences dialog box. Then, click the MySQL icon.
Notes
• Although you can use any names you want for the connections you create in
MySQL Workbench, ''Local instance MySQL80'' is the name of the default
connection that is created on a Windows system for MySQL 8.0, and that's the
name we use in this book.
• To 1nake it easy to start MySQL Workbench, you may want to keep this application
in your dock.
The databases
Database Description
ap The AP (Accounts Payable) database. This is the
p1imary database that's used in this book.
om The OM (Order Management) database. This database
js used in some of the examples in this book.
ex The EX (Examples) database. This database contains
several tabl.e s that are used for short examples.
Description
• All of the source files described in this book are in a zip file that can be
downloaded from www.murach.com.
Figure B-3 How to install the source files for this book
608 Appendix B How to install the software for this book on macOS
SCHl'..MA.S
~ Lim't 10 1000 rows
B
Q •• •• •
► I ap
•
8
► ex 9
► om
10
11 • DROP DA ASE IF EXISTS ap; Execute SQL Script
12 • CREATE DATA ap;
► sys
13 button
14 .
15 • USE ap;
16
t(
17
18 • CREATE TABLE general_ledger_accounls Open SQL Script
19
20
21
account_number INT PRIMARY KEY.
account_desoription VARCHAR( ) UNIQUE
File button
22 );
23
?4 • l"RF'.t,Tr: TARI F tormct
too% C· 1:-1
/\ct'on Output A
y
Figure 8 -4 How to create and restore the databases for this book
BETWEEN operator (WHERE clause) 611
E Expression, 78-79
arithmetic, 82-83
EER diagram , 332-333, 336-337 comparing, 92-93
for the AP database, 336-337 in ORDER BY clause, 106-107
EER modeJ , 332-335 string, 84-85
for the AP database, 334-335 testing, 88-89
MySQL Workbench, 42-43 Extension (SQL), 18-19
ELSE clause EXTRACT function, 274-275
CASE function, 284-285
CASE statement, 4 12-413
IF state1nent, 410-411 F
ELSEIF clause (IF), 410-411 FALSE keyword, 236-237
ENABLE keyword (ALTER EVENT), 488-489 FETCH statement (cursor), 416-417
END keyword, 402-403 Field, 10-1 L
event, 486-487 FIELDS clause
stored procedure, 446-447 LOAD DATA statement, 580-581
trigger, 478-479 SELECT statement, 578-579
ENGINE clause, 376-377 Fifth normal form , 322-323, 330-331
Enhanced entity-relationship (EER) diagram, 16-17 File-handling system vs. client/server system, 7
Enhanced entity-relationship (EER) model, 332-333 Filter (WHERE clause), 74-75
Enterprise system, 4-5 Fire
Entity, 306-307 event, 486-487
Entity-relationship (ER) diagram, 16-17 trigger, 478-479
Entity-relationship (ER) model, 332-335 First normal form (INF) , 323-325
Entity-relationship (ER) modeling, 306-307 FIRST_VALUE function, 296-297
ENUM data type, 243, 244 FIXED data type, 239
Equa l operator, 92-93 Fixed-length string, 234-235
Equijoin, 134-135 Fixed-point data type, 238-239
ER (entity-relationship) model , 332-333 Fixed-point number, 238-239
ER (entity-relationship) modeling, 306-307 FLOAT data type, 15, 238-239
Error Floating-point data type, 238-239
com1non causes, 58-59 Floating-point nL1mber, 238-239
raise in stored procedure, 452-453 search for, 268-269
Error codes (MySQL), 418-419 FLOOR fun ction , 266-267
Error handler, 416-418 Flow of execution (statements), 404-405
Errorlog, 496-497 FOR clause (SET PASSWORD), 542-543
Escape character, 578-579 FOR EACH ROW clause (CREATE TRIGGER), 478-
Event, 402-403, 486-489 479
alter, 488-489 FOR SHARE clause (SELECT), 440-441
create, 486-488 FOR UPDATE clause (SELECT), 440-441
drop, 488-489 Foreign key, 12-13, 314-315
fire,486-487 MySQL Workbench , 366-367
show, 488-489 Foreign key constraint, 316-317, 348-349
to rotate general log, 518-519 FOREIGN KEY keywords, 348-349
Event scheduler, 486-487 FORMAT function, 252-253
Exact numeric type, 238-239 Format strings (date/ti1ne), 276-277
Exception handler, 418 Fourth normal form (4NF), 322-323, 330-331
EXECUTE statement, 460-461 Frame, 190-193
EXISTS operator (subquery), 214-215 analytic fun ction , 296-297
EXIT handler, 422-423 ranking function , 294
EXIT keyword (DECLARE ... HANDLER), 418-419, FROM clause
422-423 DELETE stateme11t, 162-163
Explicit conversion, 248, 250-251 join, 114-115
Explicit syntax Uoin), 114-115 SELECT statement, 26-27, 74-75
Export data (to a file), 578-580 REVOKE statement, 540-541
subquery, 218-219
616 Front end INSERT statement
Front end, 7
Front-end processing, 7
I
Full backup, 564-565 IBM (DB2), 18-19
Full outer join, 144-145 IDENTIFIED BY clause
FULLTEXT index, 374-375 ALTER USER statement, 542-543
Full-text search, 374-375 CREATE USER statement, 532-533
Function, 84-87, 258-299, 464-465 IF clause, 4 10-411
aggregate, 170-173 IF EXISTS clause
aggregate window, 188-195 ALTER USER statement, 542-543
call 464-465 DROP DATABASE statement, 342-343
column, 170-171 DROP EVENT statement, 489
create, 464-465 DROP FUNCTION statement, 470-471
deterministic, 466 DROP PROCEDURE staten1ent, 462-463
drop,470-471 DROP TRIGGER statement, 484-485
non-deterministic, 466-467 DROP USER statement, 533, 534
that calculates balance due, 468-469 IF function, 184-187, 286-287
Function characteristics, 464-465 IF NOT EXISTS clause
Ft1nctionally dependent column, 174-1 75 CREATE DATABASE statement, 342-343
CREATE ROLE statement, 546-547
CREATE USER statement, 532-533
G IF statement, 410-411
General log, 496-497 nesting, 411
Geometry data types, 232-233 stored procedure, 403,404
GLOBAL keyword IFNULL fu nction , 286-287
SET statement, 510-511 Imp.licit conversion, 92, 248-249
SET TRANSACTION LEVEL statement, 438-439 Implicit inner join syntax , 126-127
Global positioning system (GPS). 232-233 Import data (from a file), 580-581
Global privileges, 530-531 IN keyword (para1neter), 448-449
GMT (Greenwich Mean Time), 270-271 IN operator
GRANT OPTION p1ivilege, 528-529 subquery, 204-205
Grant privileges WHERE clause, 96-97
role, 546-547 lncren1ental backup, 564-565
user, 536-538 Index, 10-11 , 356-357
GRANT statement, 524-525 col umn , 320-321
assign a user to a role, 546-547 composite, 320-321
grant privileges to a role, 546-547 create, 356-357
grant privileges to a user, 536-538 drop, 356-357
Grant tables (mysql database), 530-53 1 FULLTEXT, 374-375
Greater than operator, 92-93 MySQL Workbench, 364-365
Greater than or equal to operator, 92-93 Inline view, 218-219
Greenwich Mean Ti1ne (GMT), 270-271 Inner join, 28-29, 114-117
GROUP BY clause (SELECT), 174 -177, 182-183 combined with outer join, 130, 133
WITH ROLLUP operator, 182-183 explicit syntax, 114-115
GROUPING function, 184-187 implicit syntax, 126-127
SQL-92 syntax, 114-115
INNER keyword, 114-115
H lnnoDB storage engine, 374-375
HAVING clause, 174-181 lnnoDB table (repair), 584-585
compared to WHERE clause, 178-179 INOUT keyword (parameter), 448-449
GROUPING function, 186-187 Input parameter, 448-449
subquery, 216-217 Input/output parameter, 448-449
Home page (MySQL Workbench), 42-43 INSERT function, 258-261
Hostname, 534-535 INSERT keyword (CREATE TRIGGER), 479
HOUR function, 272-273 INSERT statement, 23, 30-31, 152-1 53
HTML tags, 36 default value, 154-1 55
null value, 154-155
INSERT statemerit (continued) LTRIM function 617
www.murach.com