Murach J. Murach's MySQL. Training & Reference 4ed 2023
Murach J. Murach's MySQL. Training & Reference 4ed 2023
Morach
m urach's
MySQL 4th Edition
JOEL MURACH
m urach's
MySQL 4th Edition
Joel Murach
10 9 8 7 6 5 4 3 2 1
ISBN: 978-1 943873-10-4
Contents
Introduction xiri
Appendixes
Appendix A How to set up Windows for this book 591
Appendix B How to set up inacOS for this book 601
Expanded contents VII
Expanded contents
Section 1 An introduction to MySQL
• It has 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 and also see how the feature is used in the real world from the
more complex ones.
• The exercises at the end of each chapter provide a way for you to gain
valuable hands-on experience without extra busy work.
• All of the information is presented in paired pages, w uh the essential
syntax, guidelines, and examples on the right page and clear explanations on
the left page. This helps you learn faster by reading less.
• The paired-pages format is ideal for reference when you need to refresh
your memory about how to do something.
ioel<rt murach.com
Section 1
An introduction to MySQL
Before you learn to code MySQL statements, you need to understand some
concepts and terms related to SQL and relational databases. So, that's
what you'll learn in chapter I In addition, you II need to know how to use
the tools for working with a MySQL database. That’s what you'll learn in
chapter 2.
After that, you'll be ready to learn how to code basic SQL statements.
In chapter 3, you’ll learn how to code SELECT statements to retrieve data
from a single table. In chapter 4, you'll learn how to retrieve data from
two or more tables. And in chapter 5, you’ll learn how to add, update, and
delete rows from a table.
Once you're done reading the chapters in this section, you 11 have all
of the basic skills you need to use MySQL. Then, you can leam more SQL
skills by reading the chapters in section 2.
1
An introduction
to relational databases
This chapter introduces the concepts and terms that you need to know before
you learn how to use SQL to work with a relational database such as MySQL.
If you've never worked with relational databases before, this chapter will teach
you what they are and how they work. It also shows you some examples of
SQL statements that you'll be able to code yourself after completing section L
An introduction
to client/server systems
If this is your In st time working 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 most often a
client/server system.
Client
Server software
• To store and manage the databases of the client/server system, each server requires
a database management system (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. I his 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 chent is typically referred to as the front end.
Description
• In addition to a database server, a client/server system can include additional
servers, such as application servers and web servers.
• An application server handles the processing for an application and uses SQL to
communicate with the database server.
• A web server uses a protocol known as HTTP (I lypertexi Transfer Protocol) to
communicate with the client It can also use SQL to communicate with the database
server.
• In a web-based system, it's common for the client to use a web browser to commu
nicate with a web server that's running somewhere on the internet.
• Complex system architectures can include many application servers, web servers,
and database servers.
An introduction
to the relational database model
In 1970. Dr. E. F. Codd developed a model tor a new type of database called
a relational database. This type of database eliminated some of the problems
that were associated with standard tiles 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 standard
for database applications.
Description
• 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 column 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 sometimes called a cell. A cell stores a
single value.
• Most tables have a primary key that uniquely 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
primary' 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 the 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
Foreign key
Description
• The tables in a relational database are related to each other through then key
columns. For example, the vendor _id column is used to relate the Vendors and
Invoices tables.
• The vendor_id column in the Invoices table is called a foreign key because it identi
fies a related row in the Vendors table. A table may contain one or more foreign
keys.
• The relationships between the tables in a database correspond to the relationships
between the entities they represent. 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 relationship with
another table.
♦ »erdor_d wnu) □ □ □ □
invoice_number VAftCHARflO) □ □ □ □
<9. mvc:ce_date DATE □ □ □ □ □
■u invc!ce_totd dk:mal(U) □ □ □ □ □ □
* p«yment_totai decimalcu) □ □ □ □ D-M'
cred1_tot« decimal^J) □ □ □ D.M‘
♦ terms jd wniD □ □ □ □
<? invo-ce_due_date DATE □ □ □ □
\j t>ayment_d«te CATE □ □ □ NULL
□ □
Co'u-i- Data Type:
Oartet/Colttion: Def**:
Unagned Zerofil
Description
• The data type that's assigned to a column determines die type of information that
can be stored in the column.
• Each column definition indicates whether or not it can contain null values. A null
value indicates that a value is unknown, unavailable, or not applicable.
• A column can be defined with a default value. Then, that value is used if a 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.
invoices
invoice jd INT
, mvotce.number VARCHAR(SO)
v payment.totd DECIMAL(9,2)
credit-total DE<TMAL(9,2)
I
I tennsjd INT
invoice.due.date DATE
_ yeiM»Ml_l«igw_accounts v payment-date DATE
account.number P<T
account.descnptian VAROAR(SO)
►
T I wok e_l I ne_i terns
I
invoice Jd INT
I
invoice-Sequence INT
I
i__________ * account.number INT
ine.ltern.arrount DECIMAL(9,2)
Description
• An enhanced entity-relationship (EER) diagram can be used to show how the
tables in a database are defined and related.
An introduction to SQL
and SQL-based systems
In the topics that follow, you’il learn how SQL and SQL-based database
management systems evolved. In addition, you II learn how four of the most
popular SQL-based systems compare.
Description
• Although SQL is a standard language, each vendor has its own SQL dialect, or
variant, that may include extensions to the standards.
Oracle
• Released in 1979.
• Runs on Unix, z/OS. Windows, Linux, and macOS.
• Typically used for large, mission-critical systems that run on one or more Unix
servers.
DB2
• Released in 1985.
• Runs on OS/390. z/OS, AIX, Unix, Windows, Linux, and macOS.
• Typically used for large, mission-critical systems that run on legacy IBM
mainframe systems using the z/OS or OS/390 operating system.
SQL Server
» Released in 1987.
• Runs on Windows and Linux.
• Typically used for small- to medium-sized systems that run on one or more
Windows or Linux servers.
MySQL
• Released in 2000.
• Runs on Unix. Linux. Windows, and macOS.
• A popular open-source database that runs on all major operating systems and is
commonly used tor web applications.
Description
• Unix is a family of proprietary operating systems. It was originally developed by
Bell Labs in 1969.
• Linux is a family of open-source operating systems. It was originally released by
Linus Torvalds m 1991. Since Linux was originally based on Unix, a’s known as a
Unix-like operating system.
• MySQL is a popular open-source database that runs on all major operating systems
and is commonly used for web applications.
• These are just four of the most popular relational databases. Many other relational
databases exist.
• Some databases are offered by cloud providers as services, so you don't have to
handle setup or maintenance yourself. This is knowm as DBaaS (database as a
service).
Description
• Data manipulation language (DML) statements let you work with the data in a
database.
• Data definition language (DDL) statements let you work with the objects in the
database.
• SQL programmers typically work with DML statements, while database adminis
trators (DBAs) use the DDL statements.
A SELECT statement that retrieves and sorts selected columns and rows
from the Invoices table
SELECT invoice number, invoice date, invoicetotal,
paymenttotal, credittotal,
invoice^total - payment—total - credit-total AS balance due
FROM invoices
WHERE invoicetotal - payment_total - credit-total > 0
ORDER BY invoice date
Description
• You use a SELECT statement to retrieve selected columns and rows from a table,
called the base table. The result of a SELECT statement is a result table, or result
set.
• A result set can include calculated values that are calculated from columns in the
table.
• A SELECT statement is commonly referred to as a query-.
A SELECT statement that joins data from the Vendors and Invoices tables
SELECT vendor_name( invoice number, invoice date, invoice total
FROM vendors
INNER JOIN invoices
ON vendors.vendor_id = invoices.vendor id
WHERE invoicetotal >■ 500
ORDER BY vendor name, invoicetotal DESC
Description
• A join lets you combine data from two or more tables into a single result set.
• I’he most common type of join in SQL is an inner join. Illis 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 changes the values in the invoice due date column
for all invoices with the specified termsjd
UPDATE invoices
SET invoice due data - DATE ADD(invoice, duedate, INTERVAL 30 DAY)
WHERE terms id ■ 4
A statement that deletes all paid invoices from the Invoices table
DELETE FROM invoices
WHERE invoice-total - paymenttotal - credittotal ■ 0
Description
• You use an INSERT statement to add rows to a table.
• You use an UPDATE statement to change the values in one or more rows of a table
based on the condition you specify.
• You use a DELETE statement to delete one or more rows from a table based on the
condition you specify.
Warning
• If you're new to SQL. don't execute the statements above until you understand the
effect that they 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.
• L'se comments to document code that is difficult to understand.
Description
• I inc breaks, white space, indentation, and capitalization have no effect on how
MySQL processes statements.
• 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.
To help you understand how SQL is used, 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
SQL statements to work with the data in a relational database. With that as
background, you’re now ready to start using MySQL.
Terms
client one-to-many relationship
server one-to-one relationship
database sen er many-to-many relationship
network data type
client/sener system null value
local area network (LAN) default value
wide area netw ork (WAN) auto increment column
cloud enhanced entity-relationship (EER)
cloud computing platform diagram
enterprise system relational database management
database management system (DBMS) system (RDBMS)
back end American National Standards Institute
application software (ANSI)
data access API (application Oracle
programming interface) DB2
front end SQL Server
SQL (Structured Query Language) database as a senice (DBaaS)
query SQL dialect
query results SQL extension
network operating system open-source database
application server data manipulation language (DML)
web server data definition language (DDL)
relational database database administrator (DBA)
table base table
row result table
column result set
record calculated value
field join
cell inner join
primary key outer join
composite primary key comment
non-primary key block comment
unique key single-line comment
index
foreign key
2
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 leam
how to use the MySQL Reference Manual, and you should at least be familiar
wuh the MySQL Command I .me Client
A t
Browse Documentation * Read the Blog > Discuss on the Forums >
Description
• The Home page of MySQL Workbench is divided into the three tabs displayed at
the left side of the window: Connections. Models, and Migration.
• You can use the Connections tab to code and run SQL statements.
• 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.
• The Home page also includes links that you can use to view the documentation for
using MySQL Workbench, view the MySQL Workbench blog, and view and join in
the MySQL Workbench forum.
• 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.
Description
• To connect as the root user to an instance of MySQL that's running on the local
host computer, click the stored connection for the local instance 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 tire "‘Save password in vault ’ option when you’re prompted for your
password.
• To clear the password from the vault so you are prompted for your password,
right-click the connection, select Edit Connection, click the Clear button for the
password and click the Close button.
• To edit the connection parameters for a connection, right-click the connection and
select Edit Connection to display the Manage Server Connections dialog box. Then,
enter the connection parameters and click the Close button. This lets you specify
the connectton name, the username, the hostname, the port number, and other
connection parameters.
• To add a connection to another MySQL server, click the © icon to the right of
MySQL Connections, enter the connection parameters, and click the OK button.
Then, the connection appears in the list of connections.
• If you get a warning that MySQL Workbench is incompatible with the server
version and that some features may not work properly, don’t be alarmed. You can
click Continue Anyway and the features described in this book should still work.
A LauimaolMQlB >l
ff J ff1 6 51 £ it £j B •» o oca
MAMAttMUil
O *♦>«’*»**• Co**Onr Nmw
J* Opi*om r*e
FfirOKMAMCl
Q DaVttrt
Wonv*o*
Ma l±0t UtKtod
Description
• After you install MySQL, the database server usually starts automatically each
time you stair your computer. You can confirm that’s it’s running by displaying the
Server Status tab.
• The database server can also be referred to as the database service or the database
engine.
• If you need to start or stop the database server, appendix A provides instructions for
Windows, and appendix B provides instructions for macOS.
W l^cdwwtvnliySQlKI X
Fn 'Am Qmy FWds— TiWi Hdp
* Stated ^racceu^s
Hertwew" Oi*vl
IkoWdMMad (9 *c*X'OuttU •
Ot^ad Wo S«ii»
Description
• Each database (or schema) pros ides 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 an item
from the resulting menu.
The data for the Invoices table displayed in the Result grid
Resu t grid
9 MySQt Wo-ttwh O X
A Locd »«tanc0MySQLlO ■
© CQ ]
i , M>
r r Ao fl
SCLKT ■ m InvolHii
Itwoca
term
B n ventfe*!
■«rrtr jd aedljnW r-rsur jl *
J AacrOutM
mvo«i» data
nvDc«_ total
deer?
i ii a 44 saecr * from oMMimno iooo 0 0CDm£< OOOOwe
ctdt row dear?
nt
Objed Wo
Description
• To view the data for a table, right-click the table in the Navigator window and
select Select Rows - Limit 1 (XX) 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 tor a table
46 Section 1 An introduction to MySQL
A Lx*»«ce»y$QLK
file Esi QmV) Dabteie Server lotfe Scnpbog
O £. d o I JI S 0 fid 3 «f-
KMIMAS
Tit** Mr*
Omt^dAatar
W TOei
► ”1 ■;**<»■* Jec«jer_MT'
► ' irr»o«ce_»n?»r»e
►
► uQ *1 a
► t*ms
a a □ □ □ □ a □
► “I a
wenfce
• Cotawu W«dur_«ddr«BC
VMCHMOtl
VMCMUU1C1
VMCHMKH)
C
L
□
2 □
□
□
□
□
□
□
J J
J
□
□
□
□ LJ
□
□
»JU
vaacnaKlI) □ a □ □ J □ □ LI
□ a □ LI □ □ □ U
VMCNMClt) C s □ J □ □ □ □
VMCMWtSC) □ □ □ □ □ □ □ □ Hull
* Slartd Hocedarcs
W»»OUItO«) □ □ □ □ □ □ □ □ H.l.
W »MMai
VMCH»O«) □ c □ □ □ J □ □ NULL
LI a □ □ □ □ □ □
drf«^t_»Ct»art_fw*!bfr □ a □ □ □ □ □ □
5cted
LJ □ □ □ □ □ □
Wcmwefli
Cotan Nme;
3efeJ!G*MV'
Cofcjmns:
Cornents:
rendof k1
vendor rww>
vrxicr addimk 1
□
vfnfc)r_*dd'<M*2 □ ZoroFI
vmdortt*
□ 5<*wa»d
*«*xJe*_BD_CDde
vmKf_tror«
P®r«0*K£vi *»r!tie*w{j
Description
• To view the column definitions for a table, right-click the table name in the
Navigator window and select Alter Table.
• To edit the column definitions for a table, view the column definitions. Then, you
can use the resulting window to add new columns and modify and delete existing
columns.
Figure 2-6 How to view and edit the column definitions for a table
48 Section 1 An introduction to MySQL
O I — I
ICmMAi Lu H
. 1 A
SELKT Kndorjiiee, vendor city, vendor state
V T*i«
► B ge»er»ijec<je,_aco
cm
*n vendorjoHiffl
vendors
Foreigners
W Tnooen
* Stewed fr»c*dare«
hra*p*i
Manfuti
ve->tto_iddi«H]
vendor _ id dr«*2
Object Wo 5e»oi
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 its name in the Schemas tab of the
Navigator window. This displays the 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 Statement button
( H ) in the SQL Editor toolbar. If the statement retrieves data, the data is displayed
in a Result grid below the SQL Editor tab.
UxdunceWySQUO “
■1 .w Qje*> Catofc
& I LJ
ftr^ir
SCHEMAS
3 itflpi
® Stand *bced*t««
»Y«
tafaimitioa
Table: uendan
(3 Adar OUkM
0 000 ar
vendor, ad dr*a2
Description
• If an error occurs during the execution of a SQL statement. MySQI. 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.
© I - I
K MIMAS Bk B X / R
*tl( vendor id « 34 j
*B
► 1
>B Irwocej
► "I in.DCM
► ~j tlTO ■f1 " myiql » haot.Mfipti ■ cMU P Search «M2
► Q
> n vendM
W *
• 1 o
Stored t*ced«re>
Wdnvubet CV/tM
£5 Arter
F**a
^hon
wndtor_xl iqf*4fWI.2O19
vendor name
v*MOr_*ddh*Ml T1 saRb»Ciq«
Fib fume i«4eci_ vendor Jaiar.due sql
vendor, ad dr«A2
Widar th
Cancel
vdMOr.CM*
Obxd Irfc 5m «■
Description
• A SOL script is a file that contains one or more SQL statements.
• To open a SQL script, click the Open SQL Script File button in the SQL Editor
toolbar or press Ctrl+Shift+O. 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 button in the SQL Editor
toolbar or press Ctrl+S. Then, use the Save SQL Script dialog box that’s displayed
to specify a location and name for the file.
• To save a script you’ve modified to a new file, press Ctrl+Shift+S or select
File-^Save Script As.
A Local MySQUO
2 FAW vrMorj
J kftttRt • Mj
► n •;«’*r»ij*cg*r_4CO7ir
► ~1 in»or«_«rrv»» 4
AdrwNftntMi ScftefiM
WenrwtiB*
Cokmnr
rtakud
vendor mm
v«ndor_iddrMA]
I aw-
•
*r**r CMpwt
TWw acbm
•
Object Wo Sesnoi
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 Ctrl+Shirt+Enter or click the Execute Script
button ( ) that's located just to the left of the Execute 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 Ctrl+Enter orclick the Execute Statement button ( 5 ). If the
statement retrieves data, the data is displayed in a Result grid.
• To execute two or more statements within a script, select them iti the editor and
then press Ctrl+Shift+Enter or click the Execute Script button.
C ■ devJHyfqLcom/dcx^MfmjrVfl.flSM'Vtnanua^tfWD.Mml G id * » □ O =
MySQL Scivtr MySQL Enterprise Wnrkbentb irmoOB Ouster MySQL FOB Custer Lormtcr. Mr>f
This is the Reference Manual for the MySQL Database System, version
MySQL 8.0 Reference Manual
8.0. through release 8.0.34. Differences tet.rcen m«w versions of
• Preface end Legal Notices
MySQL 8j0 are noted in the present text with reference to release
» elien: infcrrrotkn
numbers (8.0.Ftx license information, see the Legal Notices.
• About This Manual
> Overview qf the MySQL Database Th a manual is not intended for use with cider versions of the MySQL
Management System
softwa’e due to the many funchrnal and ether deferences brv.ee"
. S New in MySQi. a.0
MySQL 8.0 and previous versions if you are using an earlier release of
• Serve* ard Status Variables ar>"1
the MySQL software, pease refer to the appropriate manual. For
Options Added. tes 'e . ‘ed, o»
Removed in MySQ. CO erampie. MySQL 5.7 neftrence Manual covers die 5.7 series of MySQL
• HeM to Report Bugs cr Problems softwa e releases.
Description
• To view the MySQL Reference Manual, go to the MySQL website and select the
correct version of the manual.
• To view a topic, click on it in the table of contents in the left sidebar.
• To return to the Home page for the manual, click the Start icon i l for the manual
that's displayed at the top of the left sidebar.
• To search for a particular word or phrase, use the search bar near the top of the left
sidebar. Then, you can scroll through the results that are displayed and click any
link to get more infonnation.
• You can also download the MySQL Reference Manual for ottline use by clicking
on one of the links below the table of contents. However, it typically makes sense to
use the manual online.
Type ‘help;’ or *\h‘ for help. Type *\c* to clear the current Input statement.
mysql>
How to start the MySQL Command Line Client from the command line
For Windows
cd \Program Files\MySQL\MySQL Server 8.0\bin
mysql -u root -p
For macOS
cd /uar/local/mysql/bin
./mysql -u root -p
Examples
mysql -u aptester -p
mysql -h loc&lhost -u root -p
mysql -h murach.com -u aptester -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, the easiest way to start the MySQL Command Line Client is to
display the Start menu, enter “mysql 8.0 command”, and click Open. However, you
can also 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 command
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-12 How to start and stop the MySQL Command Line Client
60 Section 1 An introduction to MySQL
ap
ex
information schema
nrysql
can
pe r f o man c e _s c hexna
sys
Description
• You can use the MySQL Command Lme 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 Enter.
• 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 Lme Client, most programmers enter their statements in lowercase
letters because they’re easier to type.
Figure 2-13 How to use the MySQL Command Line Client to work with a database
62 Section 1 An introduction to MySQL
In this chapter, you learned how to use MySQL Workbench to start and
stop a MySQL server, enter and execute SQL statements, and work with SQL
scripts. 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 statements.
Terms
MySQL Workbench
database server
database service
database engine
database object
schema
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.
8. Delete the e 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 number of-invoicesf
SUM(invoicetotal) AS grand invoicetotal
FROM invoices
An introduction
to the SELECT statement
To get you started quickly, this chapter begins by presenting tire basic syntax
of the SELECT statement. Then, it presents several examples that should give
you an overview of how this statement works.
Description
• The SELECT statement retrieves the columns specified in the SELECT clause from
the base table specified in the FROM clause and stores 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 expressions
that result in a true, false, or null value. If the combination of all the expressions is a
true 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. Otherw ise, 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 rows. It you omit this clause, all rows that match are returned.
• You must code the clauses in the order 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'll learn about the other clauses later in this book.
Figure 3-1 The basic syntax of the SELECT statement
68 Section 1 An introduction to MySQL
(114 rows)
(114 rows)
(37 rows)
Description
• L'se 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
returned. See figure 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
74 Section 1 An introduction to MySQL
• 1 22 24
2 23 27
3 24 30 V
► 1 0.3333 0 1
2 0.6667 0 2
3 1.0000 1 0 V
Description
• Unless parentheses are used, the operations in an expression take place from left to right
in the order ofprecedence. 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.
► Madison WI Madson WI
Washington DC Washing tonDC v
(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.
► Francesco FA
Ama Irvin Al
LiJcas bana LL
Kense Qum KQ
frkhete Marls MM V
(122 rows)
(114 rowa)
(114 rows)
Description
• When using the D \TI .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.
Figure 3-7 How to use functions with strings, dates, and numbers
80 Section 1 An introduction to MySQL
♦ 2100.0
» Ed WAans EW
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.
► Ara hern CA
Anahem CA
Am Arbor MI
Adxxn Hfa MI
Boston MA
Boston MA
Boston MA
(122 rows)
► Arahem CA
Am Arbor Ml
Auburn MI
Boston MA
Brea CA
Carol Stream IL
Charlotte NC V
(5 3 rows)
Description
• The DISTINCT keyword prevents duplicate (identical) rows from being included in
the result set. DLS11NCTROW 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 (he default,
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 comparison 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 performed 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.
The OR operator
WHERE vendor state ■ 'NJ* OR vendor city ■ 'Pittsburg'
(11 rows)
Description
• The AND and OR logical operators create compound conditions that consist of two
or more conditions. The AND operator specifies that the search must satisfy both
conditions. The OR operator specifies that the search must satisfy at least one condition.
• 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 MySQL evaluates a compound condition, it evaluates the operators in this
order: (1) NOT. (2) AND. and (3) OR. You can use parentheses to override this order.
Figure 3-11 How to use the AND, OR, and NOT logical operators
88 Section 1 An introduction to MySQL
Description
• You can use the IN phrase to test whether an expression is equal to a value tn 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.
Description
• You can use the BETWEEN phrase to test whether an expression falls within a
range of values. The lower limit must he coded as the first expression, and the
upper limit must be coded as the second expression. Others ise. 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
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. I’he mask
for a REGEXP phrase can contain special characters and constructs. Masks aren't
case-sensitive.
• If you use the NOT keyword, only those rows 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 them 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 are standard for creating regular expressions. For 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 find that they work similarly in MySQL.
► 1 125.00
2 0.00
IM.H
3
4 2199.99
S 0.00 V
> 2 0.00
5 0.00
» 1 125.00
4 2199.99
* 1 125.00
2 0.00
4 2199.99
5 0.00
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 (").
Description
• The ORDER BY clause specifies how you want the rows in the result set sorted.
You can sort by one or more columns, and you can sort each column in either
ascending (ASC) or descending (DESC) sequence. ASC is the default.
• By default, in an ascending sort, special characters appear first in the sort sequence,
followed by numbers, then letters. This sort order is determined by the character set
used by the server, which you can change when you start the server.
• Null values appear first in the sort sequence, even if you're using DESC.
• You can sort by any column in the base table regardless of whether it's included in
the SELECT clause.
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, I represents the first 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 invoicetotal DESC
LIMIT 5
vendorjd nvace_total
110 37966.19
110 26881.40
110 23S17.S8
72 21842.00
110 20551.18
A SELECT statement with a LIMIT clause that starts with the third row
SELECT invoiceid, vendorid, invoice total
FROM invoices
ORDER BY invoiceid
LIMIT 2, 3
nvoicejd vendor jd rvoce_totai
• 3 123 138.75
4 123 144.70
5 123 15.50
A SELECT statement with a LIMIT clause that starts with the 101st row
SELECT invoice_id, vandorid, invoicetotal
FROM invoices
ORDER BY invoice_id
LIMIT 100, 1000
nvntcejd vendor jd rivoce_totai
(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 integer 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 relieve 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’ll 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 pattern
arithmetic expression mask
arithmetic operator wildcard
order of precedence regular expression
literal value null value
stung nested sort
function offset
argument
Exercises
Run some ot the examples in this chapter
In these exercises, you’ll 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 find in this directory:
murach/mysql/book_scnpts/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 Execute 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 single table 103
5. Open the script named 3-05.sql in the ch()3 directory. Then, run the second
query. W hen you do. you’ll see that the result 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.
1i 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
paj ment_total and credit-total columns
Return only invoices that have a balance due that’s greater than S50.
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.
(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 relationships.
• If the two columns 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 qualified
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 alias is an alternative table name assigned m 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 can 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 referred 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)
» 1 Smith Ondy 2
2 Jones Bner 4 1
3 Snonar 33k*- 2 2
14 Hernandez Otvia 1 9
5 Aaronsen Robert 2 4
6 Watson Dense 6 8
7____________ Hardy Thomas S 2 V
(9 rows)
I Thomas Hardy
(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_cityf
vl.vendor state
FROM vendors vl JOIN vendors v2
ON vl.vendor_city * v2.vendor city AND
vl.vendorstate ■ v2.vendorstate AND
vl.vendor name <> v2.vendor name
ORDER BY vl.vendor_state, vl.vendor_city
vendor .name vendor _cty vendor .state A
(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 foi 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.
(114 rows)
(11 rows)
Description
• Instead of coding a join condition in the FROM clause, you can code it in the
Wl II .RE clause along with any search conditions In that case, you list the tables in
the FROM clause separated by commas.
• Tins syntax for coding joins is referred to as the implicit syntax. Il was used prior to
the SQL-92 standards, which introduced the explicit syntax.
(202 rows)
Description
• An outer join retrieves 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 w ith 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.
► Acccxrhng
2 Payroi
3 Operators
4 Personnel
5 Maintenance
► 1 Smith Cindy 2
2 Jones Elmer 4 1
3 Simonian Ralph 2 2
14 Hemandea Olvia 1 9
5 Aaronsen Robert 2 4
6 Watson Dense 6 8
7 Hardy Thomas 5 2
8 Oleary Rhea 4 9
9 Locario Paulo 6 1
» P1011 8
Pion 4
PIO 12 3
PIO 12 1
PIO 12 S
PIO 13 6
PIO 13 9
P1014 10
Description
• The examples in this figure use the Departments, Employees, and Projects tables
from the EX database.
► Accounting 1 Hernandez
Mantawxe 5 Hardy
3
E3S9
Operations
Payrol 2 Smih
Payrol 2 Simonian
Payrol 2 Aar omen
Pereomri 4 Jones
Personnel 4 Oleary
(6 rows)
(9 rows)
Description
• A left outer join returns unmatched rows trom the first (left) table.
• A light 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 has the same name in both tables.
• To include multiple columns, separate them with commas.
• The join must be an equijoin, which means that the equal operator is used to
compare the two columns.
(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 natural join is shorter than the code for joins that use
the ON or USING clause, a natural join only works correctly for certain types of
database structures. In addition, a natural join often yields unexpected results for
complex queries. As a result, it's more common to use the ON or USING clause to
join tables.
► I Accourtng 2
1 Acoxntng 7 hard?
1 Accounting 4 Hernandez
1 ActanonQ 1 Smith
1 Accounting 9 l oca? io V
(4 5 rows)
► Accounting 2
i Acaxntng 7 Hardy
i Accnuntng 4 Hernandez
a Accomtro 1 Smith
i Accounting 9 Locario V
(4 5 rows)
Description
• A cross join joins each row from the first table with each row from the second
table. The result set returned by a cross join is known as a Cartesian product.
(2 2 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 SELE(?T clauses have no effect on the final
result set.
• To sort the rows in the final result set. code an ORDER BY clause after the last
SELECT statement. T liis 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, "33Jt Payment1 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 invoicetotal > 10000
UNION
SELECT invoice number, vendor name, '50^ Payment1 AS payment.type,
invoicetotal 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
A
nvacejiunber vendor _name pa mnent-type tota payment
Figure 4-14 How to combine result sets from the same tables
136 Section 1 An introduction to MySQL
(10 rows)
Description
• When you use a full outer join, the result set includes all the rows from both tables.
• MySQL doesn’t provide a keyword for full outer joins, but you can simulate a full
outer join by using the L’NION 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 thoroughly before you go on.
Terms
join implicit syntax
join condition outer join
inner join left outer join
ad hoc relationship right outer join
qualified column name equijoin
explicit syntax natural join
SQL-92 syntax cross join
table alias Cartesian product
schema union
self-join full outer join
Exercises
I. 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 invoicc_number column from the Invoices table
invoice_date The invoice_date column 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 tor Invoices.
Return one row for each invoice with a nonzero 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
(ieneral_Ledger_Accounts table
Return one row tor each vendor. This should return 122 rows.
Sort the result set by account_description and then by vendor_name.
Chapter 4 Hoc to retrieve data from two or more tables 139
Return one row for each account number that has never been used. This
should return 54 rows. Hint: Use an outer join and only return rows where the
invoice_id column contains a null value.
Remove the invoice_id column from the SELECT clause.
Sort the final result set by the account_number column.
7. Use the UNION operator to generate a result set consisting of two columns
from the Vendors table: vendor_name and vendor_state. It the vendor is in
California, the vendor_state value should be ‘*CA”; otherwise, the
vendor_state value should be ‘’Outside CA.” Sort the final result set by
vendor_name.
5
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 statement.
• Each column name in the SELECT clause must be unique. If you use a calculated
value in the select list, you must name the column.
• You can code the other clauses of the SELECT statement just as you would for any
other SELECT statement including 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 statement 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 column, 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.
The Color Sample table after the rows have been inserted
color -number color _name A
mj
► 1 606
2 0 YetCVJ
3 0 Orange
4 8G8
5 E331 W
0
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 value, you can use the DEFAULT keyword in
the list of values to insert the default value for that 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 w ith 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 subquttry is a SELECT statement that's coded witinn another SQL statement.
• To insert rows selected from one oi more tables into another table, you can code a
subquery m 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 the\ 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. You can specify the
value for a column as a literal or an expression.
• In the WHERE clause, you can specify the conditions that must be met for a row to
be updated.
• You can use the DEFAULT and NULL keywords to specify default and null values.
• By default. MySQL Workbench runs in safe update mode. That prevents you from
updating rows if the WHERE clause is omitted or doesn't refer to a primarj key or
foreign key column.
• To get around the restrictions of safe update mode, you can turn this mode off. To
do that, select Edit-> Preferences. select the SQL Editor node, uncheck the box next
to ‘Safe Updates”, and restart MySQL Workbench.
Warning
• If you tum off safe update mode and omit the WHERE clause in an UPDATE state
ment. all rows in the table will be updated.
Update the terms for all invoices for vendors in three states
UPDATE invoices
SET terms id ■ 1
WHERE vendorid IN
(SELECT vendorid
FROM vendors
WHERE vendor_state IN ('CA', ‘AZ1, "NV"))
(40 rows affected)
Description
• You can code a subquery in the W1IERE clause of an UPDATE statement to
provide one or 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 w ithin 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 it 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 turn safe update mode off and omit the WHERE clause from a DELETE
statement, all the rows in the table w ill 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 groups 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 Select Rows - Limit 1000 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.
I. Write an INSERT statement that adds this row to the Terms table:
terms_id: 6
terms_description: Net due 120 days
tet ms_due_days: 120
Use MySQL Workbench to review the column definitions for the Terms table,
and include a column list with the required columns in the INSERT statement.
2. Wr ite an UPDATE statement that modifies the row you just added to the
Terms table. I hi* 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 Terms table
in exercise I
4. Write an INSERT statement that adds this row to the Invoices table:
invoice, id. The next automatically generated ID
vendor_id: 32
i nvoice_nu mber: AX-014-027
invoice_date: 8/1/2022
invoice_total: $434.58
payment_total: $0.00
credit_total. $0.00
terms_id: 2
invoice_due_date: 8/31/2022
payment_date: null
A summary query that counts unpaid invoices and calculates the total due
SELECT COUNT(*) AS number_of invoices,
SUM(invoice_total - payment_totai - credittotal) AS total due
FROM invoices
WHERE invoicetotal - payment total - credittotal > 0
number _of_nvo*ces toti_due
» 11 32020.42
Description
• Aggregate functions, also called column functions, perform a calculation on the
values in a set of selected rows.
• A summary 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 functions 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 omif duplicate values, code the DISTINCT keyword.
This keyword is typically used with the COUNT function.
• All of the aggregate functions except for COUNTt*) ignore null values.
A summary query that uses the COUNT(*), AVG. and SUM functions
SELECT 'After 1/1/20221 AS selection date,
COUNT (*) AS number ofinvoiceg,
ROUND(AVG(invoice total), 2) AS avg invoice amt,
SUM(invoice total) AS total invoice amt
FROM invoices
WHERE invoice date > 12022-01-01 1
sdectton_date nifnber_ofjn voices avg_rvoce_amt total jnv«e_amt
Description
• To count all of the selected rows, 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 count 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
MM 7123.34
99 6940.25
119 4901.26
122 2573.33
86 2433.00
1D0 2184.50
(8 rows)
Description
• The GROUP BY clause groups the rows of a result set based on one or more columns or
expressions, lb 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 columns or expressions in the GROUP BY clause, the
results are grouped by the first column, then by the second column if there are any ties,
and so on.
• The HAVING clause specifies a search condition for including a group in the results.
MySQL applies this condition after it groups the rows that satisfy the search condition
in the WHERE clause.
• W hen 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 for grouping. To he functionally dependent. MySQL must be able to
unambiguously determine the column's value based on the grouping column.
can group by those columns and include other columns from the table in the
SELECT statement as well.
The second example illustrates how this works. This example gets the
vendor name, vendor state, and the average invoice total for each vendor.
To do that, it joins the Vendors and Invoices table and groups the rows by
vendor_name. Although the vendor_state column isn’t included in the GROUP
BY clause, it can be included in the SELECT clause because MySQL can deter
mine the value of the vendor_state column based on the vendor_name column.
This is because the vendor name column contains only unique, non-null values.
► 34 2
37 3
4fl 1
72 2
80 2 V
(34 rows)
► AZ Phoenix 1 66200
CA Fresno 19 1206.75
CA Los Angees 1 503.20
CA Oxnard 3 188.00
CA Pasadena 5 196.12 V
(20 rows)
CA Ftesno 19 1208.75
CA Oxnard 3 188.00
CA Pasadena 5 196.12
CA Sacramento 7 253.00
CA San Francsco 3 1211.04 V
(12 rows)
Description
• With MySQL 8.0.12 and earlier, the GROUP BY clause sorted the columns in ascending
sequence by default, and you could code the ASC and DESC keywords on the clause.
• With MySQL 8.0.13 and later, the columns in a GROUP BY clause are not sorted by
default. Instead, you must use the ORDER BY clause to specify a sort sequence.
Figure 6-4 Queries that use the GROUP BY and HAVING clauses
170 Section 2 More SQL skills as you need them
(19 rows)
(20 rows)
Description
• When you include a WHERE clause 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 column 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 functions.
• A HAVING clause can contain aggregate functions.
Figure 6-5 How the HAVING clause compares to the WHERE clause
172 Section 2 More SQL skills as you need them
2022-05-31 2 453.75
2022-05-25 3 220 L15
2022-05-23 2 347.75
2022-05-21 2 8078.44
2022-05-13 3 1888.95
2022-05-11 2 5009.51
2022-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.
119 1 4901.26
121 8 6940.25
122 9 23177.96
123 47 4378.02
csn 114 214290.51
(3 S 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 _cjty qty .vendors
► IA Farted 1
IA Washington 1
IA 2
MJ East Ekuwrdc 2
NJ Fat fled 1
MJ Waging ton 1
LiLEIB
NJ 4
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
summarize* the entire result set.
• If the GROUP BY clause specifies a single group, the WITH ROLLUP operator
only adds the final 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 alter 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 nowr 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 W I T H 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(invoicetotal - credittotal - payment_total) AS balance due
FROM invoices
WHERE invoice date BETWEEN '2022-07-24' AND '2022-07-31'
GROUP BY invoice date, payment-date WITH ROLLUP
invoice date payment_date rvoce_tntal balance _due
2022-07-24 cnns
503 20 503.20
2022-07-24 2022-08-19 3689.99 0.00
2022-07-24 2022-06-23 67.00 0.00
2022-07-24 2022-08-27 23517.58 0.00
2022-07-24 Gl'iH THTi.T! 503.20
2022-07-25 2022-08-22 1000.46 0.00
2022-07-25 1000.46 0.00
2022-07-23 90.36 90.36
[ill!
2022-07-28 90 36 90.36
2022-07-30 2022-09-03 22.57 0.00
2022-07-30 22.57 0.00
inflis
2022-07-31 10976.06 10976.06
2022-07-31 CQH1 10976.06 10976.06
UUliS
39867.22 11569.62
Description
• The GROUPING function returns 1 if the expression is null. Otherw ise, it returns 0.
Figure 6-8 How to use the GROUPING function (part 1 of 2)
178 Section 2 More SQL skills as you need them
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 I
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 summary queries 179
Description
• The GROUPING function is commonly 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 first argument and returns the
second argument if the expression is true and the third argument it 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 HAVING clauses, you can code the GROUPING
function in the ORDER BY clause.
Description
• A window consists of all of the rows that are needed to calculate the aggregate
value for the current row.
• The window functions can be used with all of the aggregate functions listed in
figure 6-1. The groups, or partitions, in an aggregate window function are not
collapsed to a single row.
• To treat an aggregate function as a window function, you include an OVER clause
that indicates how to partition the rows m the result set.
• If you code an empty 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 m the
vendor_total column for vendor 1 10. 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.
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 column. The third row in the vendor_total
column contains the value of the second row plus the value of the third 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 arc accumulated up to and including the current row as shown
above.
In that case, the ending row defaults to the current 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 first
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 2022-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 column 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 tluctuations so long-term trends
become more obvious.
In Uns example, a three-month average is calculated for the sum of invoice
totals. To do that, the RANGE keyword is coded w ith a BETWEEN clause
that indicates that the invoice total for the current month, one month before
the current month, and one month after the current month should be used to
calculate 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. The
MONTH function extracts the numeric month from a date. You'll leam about
this function as well as other functions for working with dates in chapter 9.
Chapter 6 How to code summary queries 185
► 4 5828.18 32212.64
5 58597.10 39614.34
6 54417.73 69370.19
7 95095.75 49955.08
8 351.75 47723.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 calculate a moving average. A moving average is calculated by
adding the value of the current row to the values of zero ch more preceding and following
rows.
• Because there are no preceding rows for the first row in a partition, the mov ing
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 cunent 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,
SUN (invoice total) OVER (PARTITION BY vendor_id) AS vendor total,
ROUND(AVG(invoicetotal) 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 invoicetotal > 5000
Description
• To define a named window, you code a WINDOW clause. Tliis 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.
Perspective
In this chapter, you learned how to code queries that group and summarize
data. In most cases, you'll be able to use the techniques presented here to get
the summary information you need.
Terms
scalar function partition
aggregate function w indow
column function frame
summary query peer
functionally dependent column moving 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 vendorjd 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 Invoices 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_descnption column from the General_Ledger_Accounts table
The count of the items in the Invoice_Liae_Items table that have the same
account_number
Chapter 6 How to code summary que ries 189
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.
(21 rows)
Description
• A subquery is a SELECT statement that’s coded within another SQL statement. For
this to work, you must 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.
(4 0 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.
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
subquenes.
33 Nelson OH
135 CA
Cal State Termte
36 Gray!ft CA
138
Venture Communications Int'l MY
139 Custom Ponting Company MO
40 Nat Assoc of Colege Stares OH v
(8 8 rows)
Description
• The IN operator allows you to test if a value is in a list of values returned by a
subquery.
• 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 m 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.
> 116.54
:ca3.58
(25 row)
Description
• You can use the ALL keyword to test if a 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, invoice number, invoicetotal
FROM vendors JOIN invoices ON vendors.vendorid ■ invoices.vendor_id
WHERE invoicetotal < ANY
(SELECT invoice total
FROM invoices
WHERE vendorid = 115)
► 6.00
6.00
25.67
6.00
(17 rows)
Description
• You can use the ANY keyword to test if a condition is true for at least one 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.
83 31359783 1575.00
95 m^jR-iooes 32 TO
95 111-9 2R-10C93 39.77
95 111-93^-10092 45.21
110 P-0259 26881.40
(3 6 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 suhquery 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 remove ambiguity.
33 Nieisor OH
35 Cal State Termte CA
36 Gray! ft CA
38 VentLre Cornfnmcatjons Inti NV
(88 rows)
Description
• You can use the EXISTS operator to test if at least one row is returned by a
subquery.
• You can use the NOT EXISTS operator to test if no rows are returned by a
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, and 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 sum of invoice totals for a vendor in each state
SELECT vendoratate, MAX (sximofinvoices) AS maxsumofinvoices
FROM
<
SELECT vendor state, vendor name,
SUM(invoicetotal) AS sum ofinvoices
FROM vendors v JOIN invoices 1
ON v.vendorid ■ i.vendor_id
GROUP BY vendor_fltate, vendorname
I t
GROUP BY vendor_state
ORDER BY vendor state
(34 rows)
►
vendor -State
AZ
ma m _sum .ofjn voces
662.00
1
CA 7125.34
DC 600.00
----------------- J
(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 sum of invoice
totals. 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 invoice totals.
• The subquery named Jt3 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 11 and t3 are joined on both the vendor_state and sum_of_invoices
columns.
(34 rows)
► NV 23177.96
TN 4378.02
CA 712S.34 V
(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 Wil 11 keyword followed by the definition of the CTE.
Then, immediately alter 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 as shown in figure 7-14.
• Although you can use CTEs with INSERT. UPDATE, and DELETE statements,
you’re most likely to use them with SELECT statements.
► 1 Smith Cindy 2
2 Jones Smer 4 i
3 SrwMar Rafoh 2 2
4 Hernandez oirvia 1 9
5 Aaronsen Robert 2 4
6 Watson Dense 6 8
7 Harfiy Thomas 5 2
8 O'Leary Rhea 4 9
9 locarto Paufo 6 t
» 1 Qndy Smith 1
2 E>xr Jones 2
9 Pado Lorar o 2
3 Ralph Simonian 3
4 OlMa Hernandez 3
7 fhomas Hardy 3
8 Rhea Oleary 3
5 Robert Aaronsen 4
6 Dense 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 subquery can often be
restated more clearly by using a join. It so, you'll typically want to use a join
instead of a subquery.
If you fmd yourself coding the same subqueries in multiple places, you
should consider creating a view tor that subquery as described 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
queries.
Terms
subquery comment
introduce a subquery pseudocode
nested subquery common table expression (CTE)
correlated subquery recursive query
uncorrelated 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 vendorname
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 than 0?
Return the invoice_number and invoice_total columns for each invoice. This
should retuin 20 rows.
Sort the results by die 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
hne item in the lnvoice_Line_Items table. To do that, use a subquery intro
duced with the NOT EXISTS operator. This should retuin 54 rows.
Sort the results by the account_number column.
Chapter 7 How to code subqueries 221
Overview
The MySQL data types can be divided into the 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, symbols, 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 dau/tune or
temporal data types.
Since the first three categories are the most widely used, this book focuses
on these data types. However. MySQL also pros ides binary data types that are
useful for storing encryption keys and hash values, as well as smaller image,
audio, and video files. It also provides large object (LOB) data types that are
useful for storing larger image, audio, and video files, as well as large amounts
of character data. And it provides spatial data types that are useful for storing
geographical values such as global positioning sy stem (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 JSON data type, which is used to store
JavaScript Object Notation (JSON) 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.
Chapter 8 How to work with data types 225
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
Binary Strings of binary data (bytes)
Large Object (LOB ) Large strings of character or binary data
Spatial Geographical values
JSON JSON documents
Description
• MySQL provides data types for storing many ty pes 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
types.
• I’he binary data types are useful for storing bytes of data that can’t be represented
as character strings, such as encryption keys, hash values, and smaller image,
audio, and video files.
• The large object (LOBi data types are useful for storing images, audio, video, and
large amounts of text.
• The spatial data types are useful for storing geometric or geographical values
such as global positioning system iGPS} data. These data types are referred to as
geometry types.
• The JSON data type is used for storing JavaScript Object Notation (JSON)
documents.
Description
• The CHAR type is used for fixed-length strings. A column with this type uses the
same amount of storage for each value regardless of the actual length of the string.
• 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 uses the utftbnM 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 standard.
• By default. MySQL 5.6 and 5.7 use the utf8mb3 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 w estern European languages.
• To leam how to change the character set. 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.
However, 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 latin 1
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 columns. 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 uses 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 attr i
bute, an error occurs.
• The INTEGER type is a synonym for the INT type.
• The BOOL and BOOLEAN types are synonyms for T1NYINT. You can use these
types to store true and false values, where 0 represents a false value and any
non-zero number represents a true value.
• The TRUE and FALSE keywords are aliases for 1 and 0 respectively.
Description
« Real numbers can include digits to the right of the decimal point. The precision of
a real number 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 value exactly.
• 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 the TIMESTAMP type is automatically updated to the current date
and time when a row is inserted or updated. If a table has multiple TIMESTAMP
columns, only the tirst 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 Millennium 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. It you enter a 1-digit or 2-digit
year, it will be converted to a 4-digit year. Values from 0 to 69 are converted to
2000 to 2069. and values from 70 to 99 are converted to 1970 to 1999.
• For a value of 0 or 00 to be stored as 20CX) in a YEAR column, you must 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
format for MySQL is “yyyy-mm-dd". which is why we’ve used this format in
most of the examples in this book. By default. My SQL doesn’t support other
common date formats such as “mm-dd-yy”, If you attempt to use an unsupported
format. MySQL returns an error.
You also need to he 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
how MySQL interprets the year. By default. MySQL interprets the years (X)
through 69 as 2(XX) 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 MySQI. is
interpreting the year correctly.
Prior to MySQL 8.0.29. you could use almost any punctuation character as
a delimiter between date and time parts. For example, it was common to use a
slash as a separator between date parts. With MySQL 8.0.29 and later, however,
you should only use a hyphen as a separator between date parts and a colon
as a separator between time parts. That’s because the use of other punctuation
characters has been deprecated. If you don’t use delimiters, you can code a
DATE or TIME 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.
I’he 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. Like
dates. 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 are 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 time defaults to
00:(X):(X), which is midnight.
Chapter 8 How to work with data types 235
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-hour 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 mteiprets 2-digit years from (*0 to 69 as 2(J00 to 2069 and the
years from 70 to 99 as 1970 to 1999.
• MySQL interprets hyphens and colons as delimiters between date and time parts
respectively. If you don't use any delimiters, you can code values as numetic literals
w ithout quotes.
• If you don’t specify a time when storing a DATETIME or TIMESTAMP value,
MySQL stores a time value of 00:00:00 (12:00 midnight).
• If you don’t specify seconds u hen 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 detennines that a date or time isn’t valid, it returns an error.
• If MySQL can’t interpret a date or time value, it returns an error or a warning.
Description
• The ENUM and SET types restrict the values you can store to the set of values
specified when the column is created.
• To specify a value for an ENL'M column, you code a single text string. If the string
contains an unacceptable value, an error occurs and the row isn't inserted.
• If you don't specify a value for an ENUM column when you insert a row; MySQL
assigns a default value. If the column allows null values. MySQL assigns a null
value. If it doesn’t allow null values. MySQL assigns the first value in the set of
acceptable values.
• To specify values for a SET column, you code a single string with the values separated
by commas but no spaces. If any of the values are unacceptable, the row' isn't inserted.
• If you don’t specify a value for a SET column w hen you insert a row. MySQL
assigns a null value if the column allows null values. Otherwise, an error occurs
and the row isn't inserted.
• MySQL stores the values you specify for a SET column using the order specified in
the column definition, and it does not store duplicate values.
Figure 8-6 The ENUM and SETT types
238 Section 2 More SQL skills as you need them
Note that each binary number consists of only 0’s and 1 ’s. Because a SET
column has a minimum of one byte and each byte contains 8 bits that can each
store tlie value 0 or 1, each byte can represent up to eight values. If a bit has a
value of 1, it indicates that the associated string value is stored in the column. If
it has a value of zero, the string value isn't stored in the column.
The third table in figure 8-6 illustrates how this works. Here, the SET
column has three possible values: Pepperoni. Mushrooms, and Olives. If the
value 'Pepperoni* is inserted into this column, a value of 1 is stored in tlie
column, which is represented by a single byte with its bits set to(KXXXXX)l. If
two values are stored in the column, the bits for each value are added together.
So Olives (100) and Pepperoni (1) is stored in a single byte with its bits set to
00000101, which is equivalent to a decimal value of 5.
When storing multiple values in a SET column, the order of the values
doesn’t matter. That's because MySQL stores the values in the same order as
in the column definition. It also doesn't matter if you repeat a value because
MySQL doesn t store duplicate values. Because you don’t have to store any
values in a SET column, you can also assign an empty string to it.
Description
• The BINARY and VARBINARY types store strings of fixed- and variable-length
binary data respectively.
• If you store a string in a BINARY column and its length is less than the maximum
size of the column. MySQL pads the string on the right so it contains the specified
number of bytes.
• The BLOB types store strings of binary data and are referred to as binary large
object iBLOB) types.
• The TEXT types store strings of character data and are sometimes referred to as
character large object (CLOB) types.
• The data in BLOB and TEXT types is never padded.
SELECT statements that implicitly convert data from one type to another
Number to string
SELECT invoice total, CONCATOS', invoice total)
FROM invoices
COfJCATff, A
iHvacetntal
rtvocejotitf)
3613.33 $3813.33
40.20 (40.20
138.75 $136.75
144.70 $144.70 V
String to number
SELECT invoice number, 989319/invoice number
FROM invoices
989319/nvoice_rwiijer A
989319-457 1
263253241 0.0037580505988908225
963253234 0.0010270601385803393
2-000 2993 494659.5
V
963253251 0.001027060 lg454241^
Date to number
SELECT invoice data, invoice date ♦ 1
FROM invoices
nvoce_datr "TMJce_d.it* ♦ 1
2022-08-02 20220803
2022-08-01 20220602
2022-07-31 20220732
2022-07-30 20220731
7077-07-78 70270729
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 number 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 encounters 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
CHAT[(M)] A string of characters where N is the maximum 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[,DJ )] 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
244 Section 2 More SQL skills as 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
246 Section 2 More SQL skills as you need them
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 leam some of the additional functions for
working with data.
Terms
data type latin 1 character set
character data types integer types
string fixed-point number
text scale
numeric data types precision
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 2038 problem
geometry ty pes Y2K38 problem
J SON 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
utfKmb3 character set Code for Information
single-byte character set Interchange)
Chapter 8 How to work with data types 247
Exercises
1. Write a SELECT statement that returns these columns from the Invoices
table:
The :nvoice_total column
A column that uses 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. V\ rue 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
9
How to use functions
In chapter 3, you were 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 scalar 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.
► 1 Uzbeth Danen
2 Darnel O'Sdivan
3 Aisha won Strung
17 Lance Pros-Potte*
20 Jean Pad Renard
» 1 Uzbetr Danen
2 Darnel O'SiAvan
3 Aisha won Strung
17 Lance Pros -Potter
20 Jean Pad Renard
Sorted by the empjd column after it has been padded with leading zeros
SELECT LPAD(emp id, 2, 'O’) AS emp id, emp name
FROM stringsample
ORDER BY emp id
empjd emojwne
» 01 Uzbeth Darter
02 Darnel O'Sdlvan
03 Aisha von Strung
17 Lance Pnos-Potter
20 Jean Pad Renard
Description
• 'rhe empjd column in the String-Sample table used in the examples above is
defined with the type VARCI1AR(3). Therefore, the numeric values it contains are
stored as character strings.
» Lobeth Dar en 8 0
Darnel OSubvan 8 0
Lance Pinos -Potter 6 0
Jean Paul Renard 5 10
Altsha vtn Strump 7 11
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.
Note
• If an error occurs, each of the numeric functions returns a null value.
2 1
3 1 000000000000001
4 1234.56789012345
5 999.04440209348
6 24.04849
» 2 1
I 1 0.999999999999999
2 1
3 i.ooooooooooooooi
► 1 0.999999999999999
2 1
3 1.000000000000001
Description
• Because 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
Description
• Parentheses are required after the NOW, SYSDATE, CURDATE, and CURI’IME
functions.
• Parentheses are optional after the UTC_DATE, UTC !IME.
CURRENT,! I.MESTAMP. CURRENT_DATE, and CURRENT-TIME functions.
Examples
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
266 Section 2 More SQL skills as 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 MINUTE Hour and minutes
DAY HOUR Day and hours
YEAR MONTH Year and month
HOUR SECOND Hours, minutes, 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
268 Section 2 More SQL skills as you need them
Examples
Examples
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.
► 1 1986-03-0 1 00:00:00
2 2006-02-28 00:00:00
3 2010-10-31 00:00:00
4 2022-02-28 10:00:00
5 2023-02-28 13:58:32
6 2023-03-0109:02:25
» 4 2022-02-28 10:00:00
► 4 2022-02-28 10:00:00
4 2022-02-28 10:00:00
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.
► 1 1936-03-01 00:00:00
2 2006-02-28 00:00:00
3 2010-10-31 00:00:00
4 2022-02-28 10:00:00
5 2023-02-28 13:58:32
6 2023-03-0 1 09:02:25
Error
Error Code: 1525. Incorrect DATETIME value: '10:00:00*
» 4 2022-02-28 10:00:00
► 4 2022-02-28 10:00:00
► 6 2023-03-0109:02:25
► 4 2022-02-28 10:00:00
6 2023-03-0109:02:25
Description
• You can search for a time 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.
Description
• The CASE function returns a value that's deter mined by the specified conditions.
No Payment
2022-08-13 2022-08-13
2022-08-20 2022-08-20
2022-08-07 2022-08-07
No Payment V
Description
• The IF function returns one value if the test expression is true and another value if
the test 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 null, this function returns a null value.
Figure 9-15 How to use the IF, IFNULL, and COALESCE functions
230 Section 2 More SQL skills as 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 REGEXPJNSTR function in the SELECT
clause to return the index of the first space in the vendor_city column. The same
REGEXP„1NSTR function is also used in the WHERE clause so only the cities
that have a space in their names are included m 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 occurs anywhere in the vendor_address 1
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_L1KE function in the
WHERE clause so only vendors with a vendor_address 1 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 283
(17 rows)
(12 rows)
> Expedata Inc 4420 N. Rrst Street. Suite 138 4420 N. Frst St, Sute 103
Fresno Photoengraving Company 1952 *H' Street 1952 *H’St
Nat Assoc of Colege Stores 500 East Lor an Street SOO East Lor an St
The Fresno Bee 1626 E Street 1626 E St
The Presort Center 1627 T-Street 1627 T St
Reiter's Sceneftc & Pro Books 202 IK Street Ma 202 IK St Nw
(4 rows)
Description
• The REGEXP_L1KE function works just kkc 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 remains unchanged.
» 1 AT AT AZ
2 Computer Lixary AZ
3 Weis Fargo Bank AZ
1 Abbey Office Fumings CA
2 Amer car Excess CA
3 ASCSgra CA
Description
• The ROW_NUMBER. RANK. DENSE_RANK. and NT1LE functions were intro
duced 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_N(JMBER function returns the number of the current row within its
partition, starting at 1 for the first row in each partition.
The first example m 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, tile fourth row has a different value. To
calculate the value for this row. the RANK function adds I to the total number
of previous rows. In other words, since the first 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
fourth 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 partition 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, w'hen the
rows can't be evenly div ided 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
NT'ILE function divides this result set into 3 groups w ith 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 NTILE 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 div ide 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 functions. 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 287
1 1 6.00 25022117
1 1 6.00 24863706
1 1 6.00 24780512
4 2 9.95 21-4748363
4 2 9.95 21-4923721 V
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 functions give the same rank to all rows that are tied.
• To determine 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.
► 3020 Jonathon Thomas 1274356.38 Jonathon Thomas Andew Markasan Sonja Martnez
2020 Andrew Markasun 1032875.40 Jonathon Thomas Ande* Markasan Sonja Martnez
2020 Sonja Martnez 978465.99 Jonathon Thomas Anden Markasan Sonja Martnez
2021 Andrew Mancasiar 1132744.56 Andrew Markasan Sonja Martnez Lyda Kramer
2021 Sonja Martinez 974853.81 Andew Markasan Sonja Martnez Lyda Kramer
2021 Jonathon Thomas 923746.85 Andrew Markasan Sonja Martnez Lyda Kramef
2021 Philo Winters 655786.92 Andrew Markasan Sonja Martnez Lyda Kramer
3021 Lyda Kramer 422347.86 Andew Markasan Sonja Martnez Lyda Kramer
2022 Jonathon Thomas 998337.46 Jonathon Thomas Sonja Martinez Lyda Kramer
2022 Sonja Martinez 887695.75 Jonathon Thomas Sonja Martnez Lyda Kramer
2022 Philo Writers 72443.37 Jonathon Thomas SonjaMartnez Lyda Kramer
2022 Lyda Kramer 45182.44 Jonathon Thomas Sonja Martnez Lyda Kramer
Description
• The FIRS!LVALUE, LAST_VALUE. NTH VALUE, LEAD. LAG. PERCENT_RAN’K.
and CL’ME_DIST functions are sometimes referred to as analytic functions. They were
introduced with MySQL 8.0.
• The FIRST_VALUE, LAST_VALL’E. and NTH.VALUE functions return the first,
last, and nth value in a sorted set of values. When you use the PARTITION UY
clause with LAST_VALUE or NTH_VALL"E. you typically include the ROWS or
RANGE clause as well to define a subset of the current partition.
Figure 9-18 How to use the analyte functions (part 1 of 2)
290 Section 2 More SQL skills as you need them
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 example in part 2 of figure
9-18 Here, the OVER clause is used to group the result set by the rep Jd 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 fifth column uses the
same function, but it subtracts the result of this function from the current sales to
show the change m sales from the previous year. The LEAD function is similar,
but it lets you refer to values in following 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 0 and I
The CL'ME_D1ST 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. I he 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 291
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 CI’ME_D1ST function 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 teamed about the different functions that you can use
to operate on MySQL 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
LTTC (Coordinated Universal Time)
GMT (Greenwich Mean Time)
format string
string pattern
regular expression
regular expression functions
specialized window functions
ranking functions
partition
analytic functions
cumulative distnbution
Exercises
1 Write a SELECT statement 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 TRUNCAT E function to return the invoice_total
column w ith 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_EORMAT 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
Chapter 9 How to use functions 293
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 returns 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 column 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, every thing after the first part should be considered part of
the last name. Be sure to provide for last names with hyphens 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 RANKO function to rank the balance due in
descending sequence
Section 3
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’ll learn how to create and maintain views, which are database objects
that provide another way to look at tables.
10
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.
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.
•
’"Part No. Qty. Description Unit Price Extension
\________ >
Your salesperson: Ruben Goldberg, ext 4512 $7,557.83
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 systems.
• 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.
1
Vendor contact last
Goldberg
An address that's divided into street address, city, state, and zip code
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 element, you can easily rebuild it when necessary by
concatenating the individual 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 die elements to entities, you should omit elements that aren't needed,
and you should add any additional elements that are needed.
Description
• Most tables should have a pi unary key that uniquely identifies each row. If neces
sary, you can use a composite key that uses two or more columns to uniquely
identify each row.
• 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 primary key, you can create an auto incre
ment column that can be used 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 column 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.
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 referential integrity (DRI). you define foreign key constraints.
You E 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 die 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.
terms_descnpton
terms_due_days
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 unnonnaliztd data structure. a table can contain information about two or
more entities. It can also contain repeating column*, 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 information is stored in exactly one place.
• To normalize a data structure, you apply the normalforms in sequence. Although
[here are a total of seven normal forms, a data structure is typically considered
normalized if the first three normal 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 system 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
w hen 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 normal form.
The other four forms are not commonly used and are not covered in detail in this
book.
Description
• For a table to be in first normal form, 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 has repeating values in its rows. This can be
resolved by apply ing the second normal form.
T
ovoiotjd mot r sequence i terr _descnp tor
► 1 1 Anckod ad
1 2 MySQL ad
1 3 Lbrary drectery
2 1 Catalog
2 2 MySQL flyer
3 1 Card rei’sion
Description
• For a table to be in second normal 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
primary 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.
-• termsjd
terms-desenpt on
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 column 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 allow s 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
• accountno
city
state accountjiesc'ipt'on
terms
area_codes
♦ termsjd
-♦ area_code_id ■(frrrsdescripton
area_code terms_due_days
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 u ill 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.
• Include columns with derived values when those values are used frequently in
search conditions. If you do that, you need to be sure that the column value is
always synchronized with the value ot 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 form and can there
fore be less efficient.
• MySQL statements that work with tables that are normalized to the fourth normal
form and beyond are ty pically more difficult to code and debug.
• Most designers denonnalize 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 forms unless
it is clear that performance will be improved by denormalizing.
A
E«d Uew OatataM Toda Send** Hrtr
Models ®®®
1? M U Q9-B
Description
• MySQL Workbench allows you to create an enhanced entity-relationship model
(EER model). This type of model extends the original entity-relationship model lER
model).
• Once you have created or opened an EER model, you can work with one or more
EER diagrams that are associated with that model.
• To open a recently used EER model, click on the model in the list of models.
• To open an EER model, click the © icon to the right of the Models heading, or
select File->Open Model 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 light of the Models
heading, or select File->New Model.
• To create an EER model from an existing database, click the ® icon to the right
of the Models heading, select “Create EER Model from Database” 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 ® icon to the right of
the Models heading, select “Create EER Model from Script" 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 "Remove Model File from List”.
Dasaoo*
TjCie rone; »wxkr»
WMH) aaaoacso
VA«CMM(5I) - G
-- □ □ □ □ □
0 -- -- -
VAfiOtAfifM) □□ □ □ □ □ □ □
____________
VAftDtAflfM) □ Qncnnoc muu
3ta«d
Mat MJ iw®»
GraiM
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 Delete.
• 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
Model->Add Diagram.
• To export a database creation script from the model, select Filc->Export->Forward
Engineer SQL CREATE Script.
6rf» fv«
Zotn 10C1 £
vendors
wndorjd JMT(JI)
I moiwjd
I WK 11)
e V4AO4 JR(SOI
«-<b» jrf^na
T«ft«
5rW> t_tFrrr5_rf 1wi»
~ fiencfV.ddQcr.Mt
♦ atWt_X£Ou«LnMT>fier JNT(ll)
. "vc^ce «rct»w
►
o
I
Z) trniic gpwr J_Udaer_*tt6unti
| mriijdNTfii] KCOUIIJLflbM N’t 11]
■aswit^HST^tan VMOMAjW)
SQLCdec" ctond
Description
• An EER diagram is a visual representation of an EER model. As a result, when you
modify the tables in the diagram, you also modify the model and vice versa.
• 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 die 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 Remove figure.
• To remove a table from the diagram and delete it from the model, ught-click on die
table and select Delete.
Terms
data structure composite index
entity Boyce-Codd normal form
attribute transitive dependency
instance multivalued dependency
entity-relationship (ER) modeling domain-key normal form
CASE (computer-aided software derived data
engineering) denormalization
linking table entity-relationship (ERi model
connecting table enhanced entity-relationship (EERj
associate table model
referential integrity EER diagram
declarative referential integrity (DRIt
foreign key constraint
orphaned row
normalization
data redundancy
unnormalized data structure
normalized data structure
normal forms
index
table scan
Chapter 10 How to design a database 331
Exercises
1. Use MySQL Workbench to create an EER diagram for a database that stores
information about products.
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
information 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 hase 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, first 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.
11
How to create databases,
tables, and indexes
Now that you've learned how 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 both DDL statements and MySQL Workbench to create databases,
tables, and indexes. In addition, you’ll learn how to change the character set,
collation, and storage engine.
Description
• The CREATE DATABASE statement creates a database with the specified name on
the server.
• The DROP DATABASE statement deletes the database with the specified name
from the server. This deletes all of the tables and data that are stored in the
database.
• The USE statement selects the specified database and makes it the current database.
Before 1 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. As a result,
if you want to test these statements, you can run them against the EX database
or create a new database as shown in the previous figure. 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 die 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 m 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 column can contain multiple null values. However, it's common
to use 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 AUTOJNCREMENT
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 the AUTO INCREMENT attribute. MySQL automatically
generates the next nuinbei in sequence for the column if you don't specify a
value. By default. MySQL starts numbering with I, but you can 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
Chapter 11 How to create databases, tables, and indexes 337
Description
• To test die code m Uns figure and in the figures that follow, you can use 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.
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 CL'RRENT_DATE function.
Although it's not illustrated here, you can also code the IF NOT EXISTS
keywords on the CREATE TABLE statement. These keywords work the same
way they do for the CREATE DATABASE statement, and they’re most useful
when you're writing scripts. Without them, the statement generates an error if
the table already exists. With them, the statement generates a warning instead of
an error. This allows a script to continue executing instead of being stopped.
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 ot 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.
When you code a constraint at the table level, you must code a comma at the
end of die preceding column definition. If you don't, you vs ill get an error when
you try to tun the statement.
Description
• A foreign 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 def ine a relationship that consists of two or more columns, you must define the
constraint at the table level.
• Not all MySQL storage engines support foreign key constraints.
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 constraints 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 MySQL 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 TRl’NCATE 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 name with the database name.
• 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 unknow n. 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 defined the vendor address columns like this:
vendor_addressl VARCHAR(50) DEFAULT 1'f
vendor address2 VARCHAR(50) DEFAULT
In this case, empty strings would be stored for these columns unless other values
were assigned to them.
In practice, a null value is a more 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 1 coded a primary key or foreign key constraint at the
table level, 1 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 columns. MySQL uses the name
"PRIMARY” for the name ot the index for a table's primary 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 tor 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 d creates an index named
invoices_fk_terms for the terms_id column.
In addition to the indexes that are created automatically. 1 used a CREATE
INDEX statement to create an index for the invoice_datc column in the Invoices
table. Since this column is frequently used to search for rows m 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 353
-- create an index
CREATE INDEX invoices invoice dateix
ON invoices (invoice date DESC);
O O du S 0 O fl. v
Wtll)
AdaMHtrrton Sc**»h
|™™“ * - DeWt:
Qmaanti Sttragr MU J
H K»r OlHu
O v D uw*^ O i*®
9 Auto tnatncnt f GcreMcd
Description
• To view the columns tor 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
column. Then, select a data type from the drop-dou n list that's displayed.
• To change the default value for a column, enter a new default value 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, nght-click on the column name and select Delete Selected.
• To move a column up or down, right-click on the column name and select Move Up
or Move Down. 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.
□ rf«i2ice_djt_dati
Cfll^wN todM
Description
• To view the indexes for a table, right-click on the table in the .Navigator window,
select Alter Table, 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 column 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, eight-click on the index name and select Delete Selected.
• 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.
G W O S O o D o A 'r* o r-n
A
» ajr r«bu.
»■ Qanara *do»r«cta*re»
► | ar»cia»rthv<
► rtveica_<lna jtarra
► ■ nvotna
tetemcdC^
► t«m«
L_ "»«iCT_id On IDdatt JCtJffUCT
► T1 »vadorwcsnt«ta
□ a«ido«jd
► I vpadoil On Mta. •c’rnucr
Q iWtl
Sviam
. ... □ •nQtCC.WJ □ S'® r Kl fleneoexr
F^vtiona
D Dtvmcrtjata1
□ atdrt Jc*d
0 ftrwnjd
□ ■t«Qice_du«_<Mi
AdMiMMtraticn
O ptv’^t.dne
Description
• To view the foreign keys for a table, right-click on the table in the Navigator
window, select Alter Table, 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
column and select a table from the drop-down list that appears.
• To change the column 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 Delete Selected.
• 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 aceent-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 utfKmb4, for example, you can use
the utf8mb4_09(X)_as_,cs collation instead of the default of utf8mb4_(W00_ai_ci.
In general, if you want to use a case-sensitive sort, you can use a collation
with a name that ends with as. Or. you can use a collation w ith a name that
ends with bin. which stands for binary. This sorts characters by their numeric
values instead ot by then 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 tablename, tablecollation
FROM information scheme.tables
WHERE table schema = ' ap'
TA8l£_NAK TA0i£_COLLAT]Oh A
Description
• You can use the CHARSET and COLLATE clauses to set the character set and
collation at the database, table, or column level.
• If you omit the CHARSET clause. MySQL uses the character set that corresponds
to the specified collation.
• If you omit the COLLATE clause. MySQL uses the default collation for the speci
fied character set.
• The CHARACTER SET keywords are a synonym for the CHARSET keyword.
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'
A
TABLE ‘LAME B1GM
rwocejnejtems InnoDB
rtvoces InnoDB
terms LnnoM V
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 - InnoDB
Description
• To specify a storage engine for a table, you can use the ENGINE clause.
• To change the default storage engine for the current session, you can use die SET
SESSION statement to set the storage_engme 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 information about how to do this, see
chapter 17.
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 MySQL Workbench's graphical interface to work with the
tables of a database.
Before you move on, though, take a moment to consider the advantages
and disadvantages of using MySQL Workbench to work with database objects.
I he advantage, of course, is that MySQL Workbench provides a graphical user
interface that makes 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. 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 excel
lent 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
primary key constraint
foreign key constraint
reference constraint
cascading delete
index
script
character set
collation
case-insensitive collation
case-sensitive collation
accent-insensitive collation
accent-sensitive collation
binary collation
storage engine
Chapter 11 How to create databases, tables, and indexes 371
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 memberscommittees committees
member id e —S memberjd • commltteejd
first_name commt:ee_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 memberjd and committeejd 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 statements that add rows to the tables that are created in
exercise 2. Use any data that you like.
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 I. 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 committee 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.
12
An introduction to views
Before you learn the details for working with views, it’s helpful to get a
general idea of how views work. In addition, it’s helpful to consider some of the
benefits of views so you can determine whether you want to use them.
(122 rows)
(7 5 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 would normally
use a table in a SELECT, INSERT. I 1’DATE. 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 he 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. T*hat 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 number, invoice_date, invoice.total, balance_due)
AS
SELECT invoice number, invoice date, invoice .total,
invoice.total - payment-total - credit_total
FROM invoices
WHERE invoice total - payment total - credittotal > 0
A view that names just the calculated column in its SELECT clause
CREATE OR REPLACE VIEW invoices outstanding AS
SELECT invoice number, invoicedate, invoicetotal,
invoice_total - paymenttotal - credit total AS balance due
FROM invoices
WHERE invoice total - payment total - credit-total > 0
The example in part 2 of figure 12-3 creates a view that summarizes the
row s in the Invoices table by vendor. This shows that a view can use aggregate
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,
view s 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 carefully.
Chapter 12 How to create views 381
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.
• The 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.
Note
• If you try running these UPDATE statements and get an error that says ‘’You are
using safe update mode...”, you can turn off safe update mode. To do that, select
Edit->Preferences, select the SQL Editor node, uncheck ’’Safe Updates”, and
restart MySQL Workbench
Description
• If you don't include a WI TH 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 error
will occur if you try to modify a row in such a way that it would no longer be
included m the view.
Description
• You can use the INSERT statement to insert rows into a base table through a view
only if the view includes all of the columns required by the base table.
• 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. For this to work, the view must be based on a single table.
Description
• To alter a view, you can use the CREATE OR REPLACE VIEW statement to
replace the existing view with a new one.
• You can also use the ALTER VIEW statement to alter a view, but if the view
doesn't exist, an error will occur. The syntax of the ALTER VIEW statement is the
same as the syntax of the CREATE OR REPLACE VIEW statement.
• To delete a view from the database, you can use the DROP VIEW statement.
Perspective
In this chapter, you learned how to create and use views. As 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 restrict the access to a
database while providing a consistent and simplified way for end users 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 1
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 I, with one row for each invoice that has a
balance due of $ I (MX) 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 statement 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 vendorjd
column and all of the address columns for each \endor.
6. Write an UPDATE statement that changes the address for the row w ith 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.
Section 4
CALL test();
Description
• A stored program consists of one or more 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 includes if/else constructs, loops, and error-handling code.
data types that are used for the mvoice_total. payment_total. and credit_total
columns of the Invoices table. T hen, 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 specifics the name ot the variable. As a result,
the SELECT statement selects the value into the variable.
After the first SELECT statement, the script uses an IE statement to test the
value of the variable. It 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
statement to change the delimiter back to the default delimiter of a semicolon
(:). Then, it uses a CALL statement to call the stored procedure. This executes
the code stored within the procedure. You’ll learn more about how the CALL
statement works in chapter 15.
Eor now; don’t worry if you don't understand the coding details for this
script. Instead, focus on the general ideas. Later in this chapter, you'll learn 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
tlow 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
three statements that are commonly used within stored procedures. You saw all
three of these statements in the script in the previous figure. When working with
stored programs, though, you should knowr that you can use the SELECT state
ment 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 statement 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 programs 397
Description
• MySQL provides statements that can be used within scripts to add functionality
similar to that provided by procedural programming languages.
Ths is a test.
Description
• To display a message from a stored program, you can use the SELECT statement to
return a result set.
Similarly, the ELSE clause is also optional. As a result, it’s common to code
an IF statement like this:
IF first invoice due date < NOW() THEN
SELECT 'Outstanding invoices are overduel';
END IF;
You can also nest one IF statement within another like this:
IF firstinvoiceduedate <■ NOW() THEN
SELECT 'Outstanding invoices are overdue!';
IF first_invoice. due date - NOW() THEN
SELECT 'TODAY I *;
END IF;
END IF;
In this case, the outer IF statement is executed w hen 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 programs 403
Description
• You can use an IF statement to execute one or more statements depending on one
or more Boolean expressions. A Boolean expression 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 code parentheses around the Boolean expressions in an IF statement like
this:
IF (first invoice due data < NOW()) THEK . ..
Description
• You can use a simple CASE statement or a searched CASE statement to execute one
or more statements depending on a value that's relumed by an expression.
WHILE i < 4 DO
SET 8 - CONCATfs, 'I-', 1, * | •);
SET i - i * 1;
END WHILE;
SELECT s AS message;
END//
A REPEAT loop
REPEAT
SET 8 ■ CONCATts, '1-', 1, ' | *);
SET 1-1*1;
UNTIL 1-4
END REPEAT;
IF 1 - 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 W HILE 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.
• You can name a loop using a label. This is most helpful for identifying loops in
nested loops.
Figure 13-7 How to code loops
408 Section 4 Stored program development
The syntax
Declare a cursor
DECLARE curaor_nama CURSOR FOR selectatatemant;
Declare an error handler for when no rows are found in the cursor
DECLARE CONTINUE HANDLER FOR NOT FOUND handler_8tatC*lMnt ;
Get column values from the row and store them in a series of variables
FETCH cursor, name INTO variable!. [, variable2] (, variables]...;
» 2 row^) updated.
Description
• You can use the DECLARE.. HANDLER statement to declare a handler for errors
that may occur. In MySQL, this is referred 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 error codes and their corresponding SQLSTATE
codes, you can search the My SQI 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 procedure. Within the nested block of code,
the first 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 w'hen 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
TREE. 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? 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 state
ments 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 SQLEXCEPT1ON 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 SQLEXCEP1 ION 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 programs 415
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 EXIT HANDLER FOR 1062
SET duplicate entryfor key ■ TRUE;
DECLARE EXIT HANDLER FOR 1048
SET column cannot bonull = TRUE;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
SET sql_exception ■ TRUE;
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 error 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’ll learn 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 how to code triggers and events.
Terms
stored program searched CASE statement
stored procedure loop
stored function WHILE loop
stored routine REPEAT loop
trigger label
event simple LOOP
block of code cursor
variable condition handler
IF statement error handler
Boolean expression exception handler
nested statement named condition
simple CASE statement
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.
I. Write a script that creates and calls a stored procedure named test. This
stored procedure should declare a variable and set it to the count ot all rows
in the Invoices table that have a balance due that’s greater than or equal to
$5.(XX). Then, the stored procedure should display a result set that displays the
variable 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:
Chapter 13 Language skills for writing stored programs 419
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.
nnoice_number, and balance_due columns tor each invoice with a balance
due that’s greater than or equal to $5.(XX). The rows in this result set should
be sorted in descending sequence by balance due. Then, the procedure should
display a string \ariable that includes the balance due. invoice number, and
vendor name for each invoice so it looks something like this:
16896.06 IP-0608I Malloy Lithographing Inc//9878.45|0-2436 Malfoy
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. Tnis proce
dure should identify all of the prime numbers less than 1 (X). (A prime number
is an integer that can't be divided by another integer other than 1 and itself.)
Then, it should display a string variable that includes the prime numbers like
this:
2 I 3 I 5 I 7 I 11 I 13 I 17 I 19 I 23 I 29 I 31 |...
Hint: To get this to work, you will need to nest one loop within another 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.06|P-0608 Halloy
Lithographing Inc//$5,000 to $10,000: 9878.45|0-2436(Malloy
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.
14
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. It that's not w'hat 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 statements in the transaction are committed or rolled
back. To commit the changes, code a COMMIT statement. To mil back tlie 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 commit the changes and end the transaction.
START TRANSACTION;
SAVEPOINT baforeinvoica;
SAVEPOINT bafore_line_item2;
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 tiie 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 B as described.
START TRANSACTION;
COMMIT;
Transaction B
- - Use a second connection to execute these statements!
- - Otherwisej they won't work as described.
START TRANSACTION;
COMMIT;
Description
• Concurrency is the ability of a system to support two or more tiansactions working
with the same data at the same time.
• By default. MySQL prevents most concurrency problems by using locks. A lock delays
the execution of another transaction if it conflicts with a transaction that is already
running.
• Concurrency is a problem only when the data is being modified. When two or more
transactions read the same data, the transactions don't affect each other.
Description
• In a large system with many users, you should expect for these kinds 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.
• You should consider these locking problems as you write 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
430 Section 4 Stored program 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 It 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 from updating that
data. However, this 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.
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 retrieves 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.
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 SQI. statements can violate data integrity, you learned how
to prevent these problems by grouping the statements into transactions. Since
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 nonrepeatabie 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 SQI., statements coded as a transaction
to reflect the following change: United Parcel Service has been purchased by
Federal Express Corporation and the new company is named EedL’P. 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 should 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 items for that invoice from the
Invoice_Line_Iteins table.
If these statements execute successfully, commit the changes. Otherwise, roll
back the changes.
15
How to create
stored procedures
and functions
In chapter 13, you learned how to code simple stored procedures that didn't use
parameters. Now. you'll learn some additional skills for coding stored proce
dures. including how to use 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;
UPDATE invoices
SET credit_total ■ credittotal param
WHERE invoice.id = invoice id param;
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 sptoc or a procedure.
• You can use parameters to pass one or more values from the calling program to the
stored procedure, from the procedure to the calling program, or both.
• To declare a parameter within a stored procedure, you code the name of the param
eter followed by its data type. To declare two or more parameters, 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.
control over the privileges that you grant to users, you can create stored proce
dures that perf orm 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 ■ credittotal param
WHERE invoice_id ■ invoice—id param;
A script that calls the stored procedure and uses the output parameter
CALL update_invoicea_credit-total(56, 200, Grow count);
SELECT CONCATprow count: *f Grow 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 stoned procedure. By default, param
eters are defined as input parameters. As a result, the IN keyword is optional for
identifying input parameters.
• Output parameters store values that are passed back to the calling program. These
values must be set by the body of the stored procedure. To identify an output
parameter, you must code the OUT keyword.
• hiput/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.
START TRANSACTION;
UPDATE invoices
SET credit_total ■ credit-total param
WHERE invoice_id - invoiceidparam;
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 PRCX'EDURE statements
so they list parameters that require values first, followed by parameters that allow
null values.
UPDATE invoices
SET credit_total ■ credittotal param
WHERE invoice id ■ invoiceid 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 hke 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 first 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 first four parameters
are the only parameters that require non-null values.
The third CALL statement provides a negative number 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 figure 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 procedures and functions 449
Description
• If the data for each of the columns of the row is valid, the procedure executes an
INSERI 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, ii can handle any errors that arc
raised by the procedure or by the database engine.
Two stored procedures that work with the same user variable
DELIMITER //
» 101
Description
• A user variable is a special type of MySQL variable that’s globally available to the
current user.
• To identify a variable as a user variable, you code an at sign ((fl) in front of the
variable name.
• A user vanable is only available to the current user and 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 variable.
• A user variable is available from statements coded both inside and outside of stored
programs.
Description
• Prepared statements were introduced with MySQL 8.0. They run more efficiently
than regular SQL statements when executed repeatedly, and they are more secure
than using dynamic SQL statements.
• The PREPARE statement creates a precompiled statement that can use question marks
(?) to identify placeholders whose values can be supplied when the procedure is called.
• The EXECUTE statement can pass user variables to the prepared statement, with
the first variable being substituted for the first placeholder, the second variable for
the second placeholder, and so on.
• The values that are passed to a prepared statement must be stored as user variables.
• In general, it’s a good practice to release the system resources for a prepared state
ment after you're done using it by deallocating the prepared statement.
Unfortunately, the use of dynamic SQL makes your code vulnerable to a SQL
injection attack. As a result, you should avoid using dynamic SQL unless you
understand the security risks and are comfortable with them.
Description
• To drop a stored procedure from the database, use the DROP PROCEDURE
statement.
SELECT vendorid
INTO vendor id_var
FROM vendors
WHERE vendor_name = vendor name param;
RETURN(vendoridvar);
END//
Description
• A stored function, or just function, is an executable database object that 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 relumed.
• A function can accept input parameters that work like the input parameters tor a
stored procedure.
• When you create a function, you can include one or more characteristics that
describe the function.
• To call a stored function, you can use it in an expression just like a built-in function.
► 315
Description
• If binary logging is enabled, which it is by default with MySQL 8.0 and later, each
function must include the DETERMINISTIC, NO SQL. or READS SQL DATA character
istic. To ox erode this requirement, you can set the log_bin_trust_function_creators system
variable to 1 (ON J. 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-deterministic. 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.
► 37 547481328 0.00
37 547479217 0.00
37 547480102 224.00
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.
Description
• To view the stored procedures and functions for a database, you can expand the
node for the database. 1 hen. you can expand the Stored Procedures or Functions
node.
• To view the code for an existing procedure or function, right-click on its name and
select Alter Stored Procedure or Alter Function.
• To create a new stored procedure, right-click on the Stored Procedures node and
select Create Stored Procedure.
• To create a new function, right-click on the Functions node and select Create
Function.
• 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 comer of the Navigator window.
• To drop a procedure or function, right-click on its name and select Drop Stored
Procedure or Drop Function. Then, use the resulting dialog box to confirm the drop.
• You can use the SHOW PROCEDI RE STATE’S and SHOW FUNCTION STATUS
statements to display information about the stored procedures and functions on a
server. For more information, see the My SQL Reference Manual.
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. You can learn more by looking up
“Stored Procedures and Functions” in the online documentation.
Terms
stored procedure raising an error
sproc prepared statement
procedure dynamic SQL
parameter SQL injection attack
compiling a procedure stored function
calling a procedure function
passing parameters by position scalar function
input parameter binary log
output parameter deterministic function
input/output parameter non-deterministic function
user variable stored routine
data validation
Chapter 15 How to create stored provedtires and functions 467
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 Al* 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 duplicate 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 TRUE if the account description is in the table
or EALSO if it isn’t. (Note: If a SELECT statement doesn’t return any data, it
raises a NOT FOUND condition that your function can handle.)
3. Modify the script that you created in exercise I so it creates and calls a stored
procedure named insert_glaccount_with_test. This procedure should use 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 msert_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 terms_due_days column and another for the
terms_description column.
If the value for the description column is null, 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
CALI, statement that tests this procedure.
16
How to create triggers
and events
Now that you’ve learned how to work with stored procedures and functions,
you’re ready to Icam 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 powerf ul
way to enforce data consistency, log changes to the database, and implement
business rules. Events can be executed at a scheduled 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.
fr U5 Postal Service Wl
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 the FOR EACH ROW keywords after the table name. 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.
OLD refers the values of an existing row befoie it’s updated or deleted, and NEW
refers to either the values of a new row being inserted or the values of an existing
row after it's updated.
In the last chapter, you learned that if the body of a stored procedure or
function consists of a single statement, it can be coded without specifying a
block of code. The same thing applies to triggers. For example, the trigger in this
figure could be coded like this:
CREATE TRIGGER vendors bi?tore update
BEFORE UPDATE ON vendors
FOR EACE ROW
SET NEW.vendor_state ■ UPPER(NEW.vendor state);
Like stored procedures and functions, the advantage of not specifying a block of
code for a lugger 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.
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 I NT NOT NULL
invoicenumber VARCHAR(50) NOT NULL
invoice total DECIMAL(9,2) NOT NULL
action type VARCHAR(50) NOT MULL
action date DATETIME NOT NULL
)
Two AFTER triggers that insert rows into the audit table
DELIMITER //
Description
• You can use an AFTER trigger to insert rows into an audit table.
» in cm _a fte* _nser t INSBU rvoices BEGIN INSERT INTO rvoces audt VALUES AF’t^ 2023-07-2
ri voices .before .update LPOATE rvotces BEGIN DECLARE Sum Jnejtem.amoirit DECI .. BEFORE 2023-07-2
mvoicei .after .delete moces BEGIN H'JSERT INTO r-.0«s_aud! VALUES .. AFTBt 20 2 3-07-2
vendors_befor e.ipdate LFDAT1 vendors BEGIN SET NEW. vendor .state ® UPPER (ICW... BEFORE 2023-07-2
A statement that lists all triggers in a database that begin with 'ven”
SHOW TRIGGERS IN ap LIKE 'vanV
» vendor s _feeftx e_i®date LPDATE vendors BEGIN SET PCW.vendor.state-UPPS*(T€W.... B&=ORE 2023-07-2
Description
• To view triggers, use the SHOW TRIGGERS statement. To filter the result set
that's returned, include an IN clause or a LIKE clause.
• To drop a trigger, use the DROP TRIGGER statement. To be sure a trigger exists
before it’s dropped, include the IF EXISTS keywords.
» event sdieduier ON
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.
• 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 otf, 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 'monV
Tm Interval In ten
Db Name Definer Type Execute at
zone vaUe field
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 teamed how to use triggers to perform tasks that would
be difficult or impossible to perform 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.
Terms
trigger
fire a trigger
row-level trigger
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
tins 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 w ith an appropriate UPDATE statement If the
lnvoices_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.
Section 5
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 teach you the skills you need to be
the database administrator for a MySQL database that runs on a single,
local 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 leam some practical skills that you can use to monitor and
configure a server and work with its logs. In chapter 18, you'll leam how
to secure a database and work with user accounts. Finally, rn chapter 19.
you'll learn how to back up and restore a database.
At this point, you'll have a solid foundation in database administration.
Then, in chapter 20, you'll leam some additional skills for administering a
database that’s hosted in the cloud.
17
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 hies that are used by a database. Then this chapter presents some practical
skills that you can use to get stalled with database administration. These skills
include monitoring the server, conhguung the server, and working with the
server’s logs.
Design
- Design the database
- Create the database
Security
- Maintain user accounts
- Secure the server and its databases
Backup
- Backup the database regularly
- Restore the database
- Migrate data to another server
Miscellaneous
- Start or stop the server
- Optimize the server
- L'pdate software
- Enable and manage replication
Description
• A database administrator iDBA < has many responsibilities that vary depending on
the database.
• Database replication involves setting up two or more MySQL servers, usually
running on different machines, where one server is the source and the other servers
are the replicas. Then, any changes made to databases on one server are automati
cally propagated to the databases on the other servers.
Description
• The database server 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.
• Before you can use some logs, you need to enable them.
0 l b. 1
1
Running
Server
CoroiedFBr
rx*S^#»nan rw
5 32 KB/S
Server Directories
r^Mvtdi ’W Vtw ut
AHMAJB.cn
Description
• To view the server status, start MySQL Workbench and open a connection to
the server. Then, select Sen er-> Server Status Or, select Server Status from the
Administration tab of the Navigator window
• By viewing the server status, you can get an idea of whethei the server has enough
resources to handle its connections and traffic.
< - | Eaftc* |
Q >Wi>aay/W hairti
Description
• A process is a connection to the database.
• To view the processes that are running for a connection from .MySQL Workbench,
select Sen er->< Client Connections, or select Client Connections from the
Administration tab of the Navigator window.
• It the Refresh Rate option is set to Don’t Refresh, click the Refresh button to
display the process list
• To stop a query, select it and click the Kill Query(s) button.
• To stop a process, select it and click the Kill Connection(s) button.
• To manually view a list of processes, use the SHOW PROCESSLIST statement. To
manually stop a query or process, use the KILL statement For more information
about these statements, you can refer to the MySQL Reference Manual.
Status variables
■ MySG. Wtttfecftch
© E UL1
Cep* Oobd SubM and varttfjtea to Ocboard Caoy Sdetned w Ococed Rcfretf*
Description
• A status variable is a variable that contains information about the status of the
MySQL server.
• To view status variables from MySQL Workbench, select Server->Status and
System Variables, or select Status and System Variables from the Administration
tab of the Navigator window. If necessary, click the Status Variables tab. Within the
Status Variables tab. you can click on any of the categories to display the variables
in that category.
• To search for a status variable, use the Search box at the top of the tab.
• To manually view status variables, use the SHOW STATUS statement in a query
window.
System variables
■ MySQL Woittefttn □ X
© cwa
Loo# reties MvSQlK
Stfvtr Variables
Nm
•Ct, *«$«_•! I_rgj«« _on_ tog*
■dma.addroi
■d«w*_isLc*
■dme_ssi_ca9M>
adM»_MCc«rt
admia.aai.k*
•d«ne 0pM*vajaa
•drwa_tft_v«r«Qn n>izns»M
»Ut*W)CltanJ 8
■dto_fl C" er 1 tt_ctrti o* fca aufageBcrote SS. «e» and <
■ uto_i •ere*' ert_i rw^ert i |ra] *UTO_rftCT£MtNT CoManS arc I ft
autoj #crefienr_Gfl*d i (naj 0**i« added to *LT0_W«MB
BUtOCOCfK Oft JnC Srs ma aixocoma TOtSi
ItdfiJ>* vl«Qtf Oft ^CraaCAfi and d*t)C>e»io
■ d.UTBfMf ■ OFF [nil Mvtmar alter ta&lL tAadd -aj
bttk.iag LSI df 6*Afttandng carMadMH i*q
baa«dr Ftf *a< natalaait* diradari
Rcfretf*
Description
• A system variable is a variable that stores a setting for the cunent configuration of
the MySQL server.
• To view system variables, select Server->Status and System Variables, or select
Status and System Variables from the Administration tab of the Navigator window.
If necessary, click the System Variables tab. From that tab. you can click any of the
categories to display the variables in that category.
• To search for a system variable, use the Search box at the top of the tab.
• To manually view system variables, use the SHOW VARIABLES statement in a
query window.
A iratarKa NrSQLM] k
□ sM»ijlr
□ tocA
Sprt"
□ Vrod.toroarrijcvade tMwtfwr MTtR TJW <nJd fr»-18« tenpvd tto^ra
Sd Edtor Closed
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
Server->Options File, or select Options File from the Administration tab of the
Navigator window. Then, click an appropriate tab and use it to change options.
Finally, 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, right-click the MySQL
Workbench icon and then select ‘"Run as administrator’’.
• If the configuration file shown at the bottom of the window isn’t correct for your
system, you won’t be able to use Workbench to make changes to your system
configuration. In that case, you can use a text editor to set system variables as
shown in the next figure.
• 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 configuration.
It s often stored in the /private/etc directory with a name of my.cnf.
• The MySQL server only reads the configuration file when it starts. As a result, 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 tile directly, use a text editor. This file is named my.ini
(Windows) or my.cnf tmacOS or L’nix/Linux).
• With Windows, you may need to start your text editor as an administrator. To do
that, right-click the shortcut for your text editor and select “Run as administrator”.
• Will) 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 Get Info, click the lock icon, and modify the
permissions. When you're done editing the file, revoke your write peimission.
• When specifying a number of bytes, you can add a suffix to a number to specify
kilobytes (Ki. megabytes (Ml. or gigabytes (G).
Session variables
SET [SESSION] var name ■ var value;
Session variables
00[SESSION.]var name
► 1 0
► 0
Description
• You can use the SET statement to set the values of system variables dynamically.
• If you don't specify the GLOBAL or SESSION keyword when setting the value of
a system variable, MySQL sets the session variable if it exists.
• If you don't specify the GLOBAL or SESSION keyword 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 i K. M, G). but you can
use expressions.
Figure 17-9 How to set system variables using the SET statement
504 Section 5 Database administration
o cca
H tag-e-v
0 tog-au4M
Q teg c*j*rw» not UBTQ <dlMM log ojenw T<r. are e«ecuied xthxr bygfr c»* rv *o the »>* pjcrt f* r c open
logerror ■ "/murach/mycql/error.log"
g 1 owquerylog
alow query log file ■ "/murach/mysql/slow.log"
Description
* Logs can help you monitor the database, find and fix errors, restore data, replicate
changes, and optimize your database.
• Log files can take a significant amount of disk space, reduce server speed, and if you
don’t secure the log tiles properly, compromise security.
• If you don’t specify a directory for a log tile, 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:
lcqbin»‘c: /nturach/ntysql/bln-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-"volume sI archive/murach/myaql/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.
ft deletes binary log files that are more than 7 days old
expire logs days = 7
ft 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.
• Many variables are available for configuring logging in addition to those shown
above. For a complete list, check the MySQL documentation.
n M Mystxn .
@ i :q i
O m O wooe
*raaaa®*v A
2923-M-M 19 15:17.39 1 [Swtem] C^regrwi ruaiMiSqiiMrSQL Xie "Vrwin'd (myioid 10-S3) vtsrti"g m p*oc«ii
INMW 1 [Mtem] (Mv-fl zrwoD® Mined.
[Sutemj (M*-a
•9 IS MOI 1 tmoDV Mi enoed
23Z>06M 19 15 12 91 1 [wvwi^J ’mv-a CA cemficMt a.ptn is mF uped
2023-M-M 19 15.12.99 1 [Sxtmi] CMantf ci^iQattdtn itocartTL5 Facetted a nnecSoM vtnow itcoarttd *art
23 Z3 (« M 19:15:13-Ofi 1 [9rtt>m] [Mv-a X rwAdv for cC'oftttit B®d AdSreiA: U‘pe*t 33169
2823 06 M H:1S:11M 1 (MV 0 FltuMiSQfMjSQL Sarvtf I.SfenY^Hld.aM: Wdtffflf cmmCjwu. Lfl.
aa i6 m 13:16:MJ1 a rwamfiQ] [Ml a FdltoMia •»**» ■«« K>*cF«d if! CREATE u5E5 F HOT EXISTS but I'M, it/Utli UHL
3813 M 13 24 [Warnftg] [Mvd FdllMiq aaitf ad in CAEaTI lIIR F RO T EXISTS tv 11M> Miaadi ^iil Ca»iaapo
2823-M-U MJ9:22JS 24 taMtel (MV-fl fallfrMafl cun «0acd>ad m CREAV1 lSSI 1c NOT EXISTS tul tMv akMdi Carraapo
How to view the log files when they are written to tables
The general log
SELECT ♦, CHAR(argument) AS argumenttext FROM myfiql.general„log
event-time user.host thread jd server Jd command .type argument argi A
< >
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
Server-} Server Logs, or select Server Logs 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.
DELIMITER //
Description
• Il s generally considered a good practice to disable any logs that you don’t need.
• You can manually manage the text-based log Hies (general, error, and slow query)
by deleting and renaming log tiles.
• You can automatically manage text-based log files (general, error, and slow query)
by creating batch files (Windows) or bash files (macOS or L’nix/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 tiles 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 perf orm some of these respon
sibilities. including 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.
Terms
database administrator (DBA) slow query log
database replication binary log
source relay log
replica process
configuration tile mysqld program
data file MySQL daemon
log file 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 w hat they do.
3. Use Workbench’s Server Variables w indow to view the system variables
named basedir and datadir. Note the paths to these directories. 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 w'hether 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 513
GRANT ALL
ON ap.*
TO ap_admin01ocalhoflt;
Description
• You use the CREATE USER statement to create a user that has no privileges.
• You use the GRANT statement to grant privileges to a user.
• You use the SHOW GRANTS statement to view the privileges for a user.
A summary of privileges
Figure 18-2 summarizes some of the common privileges that a database user
can have. To start, 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 519
Description
• The privileges a user has control the operations that the user can perform on the
database.
• Privileges for working with the data in a database are typically given to all users of
the database, including end users.
• Privileges for modifying the structure of a database are typically given only to
database administrators and programmers.
The privileges you learned about in part I of figure 18-2 are called object
privileges because they allow the user to create and work with database objects,
such as tables, views, and stored procedures. The exact privileges that arc 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 sen er, shut down the server, and so on.
These privileges are listed in the first table in part 2 of this figure.
The second table lists some other privileges you’ll use frequently. The ALL
privilege grants all privileges available at the specified level except die 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 you do. they can grant
privileges to other users.
The USAGE privilege doesn’t grant any privileges to a user. In most cases,
you'll use this privilege when you wrant to give a user the ability to grant privi
leges to other users. In that case, this privilege indicates that the existing privi
leges for the user shouldn't be changed. You'll see an example of how this works
later in this chapter.
Before you go on. you should know that My SQL provides many privileges
othei than the ones shown here. As a result, if the privileges presented in
this chapter aren’t adequate for your security needs, you can use the SHOW
PRIVILEGES statement to view a list of all the privileges that are available with
your version of MySQL Then, you can refer to the MySQL documentation for
information on any of these privileges.
Chapter 18 How to secure a database 521
Administrative privileges
Privilege Description
CREATE USER Create new user accounts.
CREATE ROLE Create a new role.
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 privileges to other users.
USAGE No privileges. It can be used 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 ty pe 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 the privileges that are supported by your version of MySQL along
with their definitions, use the SHOW PRIVILEGES statement.
Description
• You can use MySQL to grant privileges at four different levels.
• MySQL stores all users for the server and their privileges in grant tables in an
internal database named mysql.
A statement that creates a user whose last five passwords can't be reused
CREATE USER jIDENTIFIED BY 'sesame' PASSWORD HISTORY 5
A statement that creates a user whose passwords can t be reused for 365 days
CREATE USER John IDENTIFIED BY 'sesame* PASSWORD REUSE INTERVAL 365 DAY
Description
• You use ihe 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.
• 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 determines the number of days until 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 as you’ll see shortly.
The sixth example in figure 18-4 uses the RENAME USER statement to
change the name of the user named joel@localhost to joelmurach©1 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
named joelmurach&localhost and jane@%. 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 executing instead of being stopped. Before dropping users, remember
that they are for all 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 MySOL
j ohnOlocalhost
The same user but with the wildcard character explicitly coded
john9'Js1
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 username 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 username 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 annedlocalhost
WITH GRANT OPTION
Description
• You use the GRANT statement to grant privileges to an existing user.
• 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.
• WITH GRANT OPTION allows the user to grant their privileges to other users.
• The USAGE keyword indicates that no privileges are being granted to the user.
Instead, the user account is being modified in some way.
► jane %
jim %
John %
anne localhost
ap_admr locabost
ap_tester localhost
ap_user localhost
joel localhost
mysql. info schema localhost
mysql. session localhost
mysql.sys localhost
locahost__________________________________________
root_________________ V
A statement that shows the privileges for a user from any host
SHOW GRANTS FOR j im
Grants for jim©%
» GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, ...
GRANT BACKUP _ADMIN,BINLOG-ADMIN, COttf£CTION_ADMIN,ENCRYPT] ON
A statement that shows the privileges for a user from a specific host
SHOW GRANTS FOR apuser@localhost
Grants for apusef ©localhost
k GRANT SELECT, INSERT. UPDATE. DELETE, CREATE. DROP. RELOAD, SHUTDOWN, ...
GRANT BACKUP_ADMIN,BINLOG_ADMIN, CONNECT] ON _ADMIN,ENCR¥iPTI ON _KE/_...
GRANT PROXY ON TO root’©locabost WITH GRANT OPTION
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 must have the global CREATE USER privilege.
• To revoke specific privileges, you must have the GRANT OPTION privilege and
you must have the privileges that you are revoking.
• If any of the specified privileges don't exist for a user, an error occurs and the
statement isn't executed. To change this error to a warning and allow the statement
to execute for privileges that do exist, include the IF EXISTS keywords.
• If any of the specified users don’t exist, an error occurs and the statement isn’t
executed. To change this error to a warning and allow the statement to execute for
users who do exist, include the IGNORE UNKNOWN USER keywords.
A SELECT statement that selects all users that don’t have passwords
SELECT Host, User
FROM mysql.user
WHERE authentication string
AND password expired ■ 'N*
Host U50
CEO EBI
Description
• You can use the ALTER L’SER statement to change a password.
• To change the password for another user, you must have the CREATE USER
privilege or the UPDATE privilege for the mysql database.
• To change the password for the current user, include the USER function instead of
a user name.
• 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.
Description
• A role is a collection of privileges that you can assign to one or more users. Roles
were introduced with MySQL 8.0.
• You use the CREATE R< )LE statement to create one or more roles. For this to work,
you must have the CREATE USER or CREATE ROLE privilege.
• If you code the IF 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 you name 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 W ITH ADMIN
OPTION clause, the user can also grant the roles to other users.
• You use the SHOW GRANTS 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 server. 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 they have been
assigned directly. If you specify ALL. the user is given all of the privileges of all
of the roles that they have 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 you 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
nke 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 die ones you name. In this figure, the SET ROLE state
ment simply sets the active role to the invoice_entry 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 mvoice_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.
Notice that, just as when you revoke privileges from users, you can include the
IF EXISTS and IGNORE UNKNOWN USER keywords when you remove a
user from a role. That way, the statement will still execute if a user doesn t exist
or if a user hasn't been assigned to a role.
To drop one or more roles, you list them on the DROP ROLE statement. In
this figure, the invoice_entry role is dropped. You can also code the IF EXISTS
clause on this statement. Then, if the role doesn't exist, a warning is generated
instead of an error.
Chapter 18 How to secure a database 541
QjRRe^T.ROLEO I
» 0'%'
moicejerifry'
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.
ffifc o u. w © I-]
MAMJU.IMIMI
L«cai rwtancr HrfQfO
O Wni Siatm
Users and Pnvi ieges
J Cifflf C<w»«fiorM
1 Ultn ind*Mb»gtt umt Acaxxa Octa to Aja *cco«Mt
AA Stwiogi
A OptMmFM )ori b<alko« MM tt> HMtS MjU3MXJ.
jokfl %
vtarondAMci rtVH».rHo«rt»r*i >3<b4*o* PM»mrd'
Q baiTAMfd 'rI»C.»n»o< QiaOaC
A&a«»tr*d' SdMeui 'WrtQf.WJ toalloft
r«t nacalta*
WbHuCai C-y<*r? P*SW»crd
atava %
*■ ■toad wMid
© Cu J
l» ».*JW
Users and Privileges
>rw
•« Dtin GSAHTOPTWM, R!<RT, RLTCTIM1A1T
Addthtor
tH^9
ACrWt
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 show n 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 you
assign to these roles.
Chapter 18 How to secune a database 547
£ £ o a fCEE 0 »
0^1
lert wra MtSQlsq
Users and Privileges
0et»4f *Of *LkMOtit jo*Mfaif l^nlJ
Description
• To display the Users and Privileges window, select Users and Privileges 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 all 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 privileges
granted to those roles, use the Administrative Roles tab. You can also use the check
boxes on tins tab to assign or revoke the privileges of the administrative roles.
These roles are defined by Workbench and are not stored as roles in the mysql
database.
Description
• To create a connection for testing a specific user’s privileges and roles, 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 tor 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, 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 usernames 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 551
Exercise
In this exercise, you will create two users and a role. You will grant privileges
directly to the first user, and you will grant privileges to the second user through a
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 that
expires immediately. 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 privi
leges 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 connect as that user. To do that, you can leave the
old password blank and enter a new password. 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 wilh 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 dorothy again and then display the active roles using the same
statement as in exercise 12. This time, the ap_user role should be displayed.
19
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 something bad happens to the database, you can restore it
and minimize the amount of data that's lost.
In this chapter, you'll 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.
Specifically, you'll learn how to export data to a file and how to import data
from a file.
Description
• It’s important for the database administrator to regularly back up the database.
Then, if the database becomes corrupted, the database administrator can use the
backup to restore the database.
• A full backup includes the structure and content of a database. You should perform
full backups according to a regular schedule.
• An incremental backup only contains changes that have been made to the structure
and content of a database since the last full backup.
• You often want to include the database named mysql in your backups, since this
database stores information about the users and privileges for all databases on the
server.
• You shouldn't store your 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
along with the databases if that hard drive fails.
• A point-in-time recovery i PITR) allows you to restore the data up to any specified
point in time.
ff, ff. o » ® £ 51 £) R r
MANAGfMEMI
uacai ncsanca M/SCXJO
LI :«w Status
Data Export
, Ctaanl Cannadtarw
.1, Umh and fritfieffti
DaU nDdrtVrJaia
INCTANCI Q
Q Uatlufi SbuMa«MH
A S***e*lo«t
f QpOana hit
PDDKMMANCI
£ Oathtaovd
kfonaatNfl
□ Dun* Staved NochIj es and Pindars O Dm® Eserfe
EwnrtCMoni
Each fiaMa aitaaamfNd rtaaMC**ta Ha. Iha a*M a aatectaj* raaWa kA nay ba dew.
O * Sa#<anta»»d *N C: UsmWre©oaaM*»ttMoa’Aa»ti2D23MX a®
at M tisane —0 be ® wFtto
abject Mo Saaita
Description
• You can use Workbench to back up, or dump, one or more databases into one or
more SQL script tiles.
• By default Workbench backs up the structure and data for the database into
multiple scripts with one script per database object.
• By default. Workbench doesn’t show internal databases like the mysql database in
the list of databases. To change that, click the Advanced Options button and select
Show Internal Schemas.
• By default. Workbench doesn’t start a new binary log file when you create a full backup.
To change that, click the Advanced Options button and select ‘’flush-logs”.
program to back up one or more databases. Then, you use the operating system's
task scheduler to execute that script file at a specified interval.
© CQ[J
MAHA&CMIMI
Loot meSance MySCXoC
o S*Ae$Utut
Data Import
INHANCl Q
Q Diihtaail
Mo ubjtsil wfected
M
0
0
3
3
0
0 •eadOfl
Object Wo 5esr **
Description
• You can use Workbench to restore one or more databases by running the appro
priate SQL script tiles generated by a previous backup.
For all databases using multiple binary log files (macOS and Unix/Linux only)
mysqlbinlog /murach/mysql/bln-log. [0-9]* | mysql -u root -p
Description
• You can use the mysqlbinlog program to execute statements in the log file.
• If the statements you want to execute are stored in multiple binary logs, you should
specify all of them on the command line in sequence from the lowest numbered log
file to the highest numbered log file.
• On macOS. you typically need to begin by coding the sudo command, code a dot
and slash before the name of the mysqlbinlog program and the mysql program, and
specify a path to the data directory. For example, you can execute the first example
shown above like this:
sudo ./mysqlbinlog ../data/binlog.000001 | ./mysql -u root -p
A UdtxMMlfrSM) x
Ws Eds «Ww iGa«y Cscatais r*w T«di Scrct^g Hde
a .. * 8 o" e r a
© I JlJ
T9 05
3 OM v.vendor Ld -
989319457 2D2244<fi 38 U. 33
ztjax^i 2022-04-W
W3J2X 2022-04-13
3022 44-16
•63253251 202244 16 15. SO
963253X1 202244-16 4i n
9613321? 2022-04-2 L 172. SO
f'«m e :»w-i J022-64.H •5.00
202244 24 60L95
M3 253250 202244-24 42.67
96133362 2D2244-2S
1 M C
Description
• You can use Workbench to export data to different types of files including CSV and
ISON files.
• A CSV (comma-separated values) file uses commas to separate each column, stores
each row on its own line, and typically includes the column names on its first line.
• JSON (JavaScript Object Notation) is a data interchange format that was originally
used by the JavaScript language but is now used by many modern programming
languages.
CtMrrrr
E Soiree Cokann
0 vendor Jd vendor.! v
0 -
0 flr«tjwre
Description
• You can use Workbench to import CSV files or JSON files.
• If you import data into an existing table. Workbench adds the data to the table by
default. However, if you w ant to delete the existing data before the import, you can
select ‘Truncate table before import"
Perspective
In this chapter, you teamed 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 administrator.
Terms
back up a database
restore a database
full backup
incremental backup
point-in-time recovery <PITR)
dump a database
CSV (comma-separated values)
JSON (JavaScript Object Notation)
Excercisc
In this exercise, you will back up a database. Then, you'll make some changes
to the database. Finally, you'll restore the database.
Back up a database
I. Make sure binary logging is enabled as described in chapter 17.
2. Use Workbench to connect to the local server, and then create a full backup
of the AP database. This backup should include the structure and data for the
database, as well as any stored routines, functions, events, and triggers for the
database.
3. 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.
4. Wait until the time on your computer changes to at least the next minute.
5. Execute a DELETE statement that deletes the row you just added.
Restore a database
6. Use Workbench to restore the entire AP database.
7. Identify the highest numbered file for the binary log.
8. Open a command line and use the mysqlbinlog program to add the row to the
Vendors table that you inserted in step 3. To do that, you'll need to include
start and end times that include the INSERT statement but omit the DELETE
statement you executed in step 5.
20
How to host a database
with AWS
For years now. the tech industry has been moving away from using local
servers to host databases and websites, preferring instead to use servers in
the cloud. In other words, instead of using physical servers located on the
same premises, many organizations are now using virtual servers hosted at
server farms running at one or more remote locations. This is know n as cloud
computing. There are many reasons for tins trend including increased afford
ability. flexibility, and scalability.
In this chapter, you'll leam how to use Amazon’s cloud computing
platform. Amazon Web Services (AWS), to host a database in the cloud. In
particular, you'll leam how to use Amazon's Relational Database Service
I RDS) to host MySQL databases.
Description
• The Amazon Web Services (AB'S) portal provides a way to manage all types of
Amazon services, including database services.
• Amazon Relational Database Service (RDS) is a managed database service. That
means that Amazon handles most of the server and database maintenance for you.
• To work with MySQL database (DB) instances in the Amazon cloud, you use the
Amazon RDS Databases page To display this page from the AWS portal, use the search
bar to search for and select RDS, or click the Services icon and select Database->RDS
from the lists that are displayed. Then, click Databases in the left sidebar.
Figure 20-1 The AWS Management Console and the RDS Databases page
570 Section 5 Database administration
Description
• As you follow the procedure above, you can skip any additional options that
Amazon presents for now. Thon, you can change these options later when you have
a better idea of how you want to use AWS.
C ■ us-east-1.console-aws-amazon corn
aws
Certificate author»ty into
rds-ca-2019
▼ Additional configuration
Public acceu
O Publicly accessible
RDS aMxjm j pubbe IP adom
Database port
5506
Description
• By default, an RDS instance you create isn’t publicly accessible. To work with
the instance from outside of the VPC (virtual private cloud) associated with the
instance, you need to change the instance so it is publicly accessible.
• In the real world, your instance shouldn't be publicly accessible unless you
properly configure the inbound firewall rules.
MYSOL/Aurora ▼
5506 My IP V
99.120.205_22fi/32 X
Description
• AWS uses firewall rules to control access to RDS instances. Security groups are
used to combine rules for different types of traffic.
• Before you can connect to you RDS instance from outside of the VPC. you need to
add a firewall rule for your IP address if it isn't automatically added.
Figure 20-4 How to add a firewall rule for your IP address
576 Section 5 Database administration
Description
• If the connection is successful, a confirmation message is displayed. If the connec
tion isn't successful, an error message is displayed unless the error is due to the
lack of a tirewall rule for your IP address.
• An unsuccessful connection may indicate that the RDS instance isn t publicly
accessible. It may also indicate that you're using an IP address that’s different from
the one you used when you created your AWS account.
A RD S x
Ed* .ww Cmt? CaOrtm- Sptvw Hrip
f tf f Fr a v © LUJ
Nwigxor
• fa W y 1 A O fa 0 Q H i^teioan^ • « Q 1 i
Q l,||M " ] 1 • surer • f«» invoices
► CH
► ea
* • ip
Orfpui
Ac*m OiipLl
Q G5 U4>M NSERT WTO mton VALUES (111.‘2020-10-23 4’kj-p Ad« ftorti 4? Dicterfd 0 Wi OlMme
O G6 U4M RSERTMTOmte_At^ VALUES 081 1 1>< M-wrt. Adri fewii U DitAgM 5 A. CIBmc
Description
• Once you've created a connection to an RDS instance from MySQL Workbench,
you can use that connection to interact with the instance just like you would a local
instance.
• Most of the SQL statements that work on a local database will work on a database
hosted by RDS. However, some statements used to configure a database may
conflict with the RDS instance. Because of that, you should use the RDS Databases
page for database configuration.
• Some MySQL extensions and plugins may not work with RDS. particularly if they
are specific to certain versions of MySQL.
Figure 20-6 How to run scripts and SQL statements against an RDS instance
580 Section 5 Database administration
Backup target
Description
• You can use the built-in backup settings for your automatic backups, you can
modify those settings, and you can create one or more custom backup plans.
Description
• You can manually back up a database at any time by taking a snapshot of it.
• You can manually restore a database from any backup or snapshot.
Figure 20-8 How to work with snapshots and restore a database instance
584 Section 5 Database administration
-* c us-«*rt-1xonsol«JMrtjnnaxonxom tailling/hcm»?r»gion-uj-«Mt-2*/
84b
Cost allocation tjqt Prior month for the same period Total manber of active services
with trend
Free ber
5
B4l<ig Conductor M No data to display 4* O.O^fa
Budgets
Budgets reports
Sa.tqs Plans E
Highest cost info
▼ Prefa rancrs
Viewing highest tervxe spend
Description
• To display the AWS Billing Dashboard, enter ‘'Billing” in the AWS search bar and
select Billing from the list that's displayed.
• The Billing Dashboard shows your current and projected charges for the month, as
well as analytics on which services are costing you the most.
• You can also use this dashboard to make payments and generate cost and usage
reports.
Description
• When you are finished experimenting with the database, you should delete it so you
won’t incur any charges.
• It is usually a good idea to keep backups of a database prior to deleting it.
Perspective
The world is moving away from locally hosted databases and towards
cloud-hosted databases. Although this chapter showed you the steps for hosting
a database using Amazon Web Services, most cloud providers offer similar
services.
Terms
AWS (Amazon Web Service) Outbound rule
RDS (relational database service) Security group
Database (DB) instance Back up a database
EC2 (elastic compute cloud) Restore a database
Compute and storage Built-in backup
VPC (virtual private cloud) Backup plan
Firewall rule Snapshot
Inbound rule
Exercises
l. Create an AWS account and sign m.
2. Navigate to the RDS Databases page and create a MySQL RDS instance.
3. Configure the instance to be publicly accessible.
4. Check if the instance includes an inbound firewall rule for your IP address,
and create one if it doesn’t.
5. Create a connection to the RDS instance in MySQL Workbench, and open
that connection.
6. Open and run the create_databases.sql script to create the three databases used
by this book.
7. Enter and run a SELECT statement against one of the databases.
8. Create a backup plan that creates a w eekly backup of the database instance.
9. Take a snapshot of the database instance.
10. Use MySQL Workbench to make a change to a database in that instance.
11. Restore the snapshot and confirm that the change to the database was
reversed.
12. Delete the RDS instance.
Appendix A
How to set up Windows
for this book
Before you begin reading this book, we recommend that you install MySQL
Community Server and MySQL Workbench. Both of these software products
are available for free from the MySQL website, and you can install them on
your computer as described in this appendix.
After you install these products, we recommend that you download
the files for this book that are available from the Murach website
t w ww.inui.tch.comi. Then, we recommend that you run the SQL script that
creates the databases that are used throughout this book.
Once you create these databases, you're ready to gain valuable hands-on
experience by running the SQL scripts for the examples presented in this
book. In addition, you can get more practice by doing the exercises that are at
the end of each chapter, starting with chapter 2.
Description
• In July 2023. Oracle announced a new versioning model for MySQL that provides
two different release tracks. The releases that contain new features and improvements
will be known as Innovation versions, and the releases that will only be updated with
bug fixes after the initial release w ill be known as Long Term Support (LTS) versions.
• Since July 2023, Oracle is only updating MySQL 8.0 with bug fixes, not new
features or improvements. As a result, MySQL 8.0 is now essentially an LTS version.
• If you want to make sure that the MySQL server works exactly as described in this
book, you should use the 8.0 version.
• If you want access to the latest features as they become available, you should use
an Innovation version. The first Innovation version is 8.1.
• If you only want access to the features included in an LTS version, you can use that
version. The first LTS version will become available in 2024.
• You can use the Services app to start and stop the MySQL service and to control
whether the MySQL server starts automatically when you start your computer.
Figure A-1 How to install MySQL Community Server
594 Appendix A How to set up Windows for this book
shown in figure A-l. Then, when you’re ready to start the service again, you can
use this procedure to do that too.
Notes
• If you install a newer version of MySQL server such as 8.1 Innovation, you may
need to install an older version of Workbench such as 8.0. That's because there may
not yet be a newer version of Workbench available.
• To make it easy to start MySQL Workbench, you can pin jr to the taskbar.
Description
• All of the files described in this book are contained in a zip file that can be
downloaded from u ww.muiach.com.
Figure A-4 How to create and restore the databases for this book
Appendix B
How to set up macOS
for this book
Before you begin reading this book, we recommend that you install MySQL
Community Server and MySQL Workbench. Both of these software products
are available for free from the MySQL website, and you can install them on
your computer as described in this appendix.
After you install these products, we recommend that you download
the files for this book that are available from the Murach website
1 wuw.inuiach.comi. Then, we recommend that you run the SQL script that
creates the databases that are used throughout this book.
Once you create these databases, you're ready to gain valuable hands-on
experience by running the SQL scripts for the examples presented in this
book. In addition, you can get more practice by doing the exercises that are at
the end of each chapter, starting with chapter 2.
Description
• In July 2023, Oracle announced a new versioning model for MySQL that provides
two different release tracks. The releases that contain new features and improve
ments will be known as Innovation versions, and the releases that will only be
updated with bug fixes after the initial release will be known as Long Term Support
(LTS) versions.
• Since July 2023, Oracle is only updating MySQL 8.0 with bug fixes, not new
features or improvements. As a result, MySQL 8.0 is now essentially an LTS
version.
• If you want to make sure that tlie MySQL server works exactly as described in this
book, you should use the 8.0 version.
• If you want access to the latest features as they become available, you should use
an Innovation version. The first Innovation version is 8.1.
• If you only want access to the features included in an LTS version, you can use that
version. The first LTS version will become available in 2024.
• You can use the MySQL preference pane to start and stop the MySQL server and
to control whether the MySQL server starts automatically when you start your
computer.
Notes
• If you install a newer version of MySQL server such as 8.1 Innovation, you may
need to install an older version of Workbench such as 8.0 That’s because there may
not yet be a newer version of Workbench available.
• To make it easy to start MySQL Workbench, you may want to keep this application
in your dock.
However, to get these figures to work correctly on macOS, you need to substitute
the following path:
I Us er s / yo urnaaa / Document s/murac h I ray sq 1
Here, you need to substitute your macOS username for voumame. For example,
for a usemame of johndoe. you could use this path:
/Users/j ohndoe/Document s/murach/mysql
Appendix B How to set up macOS for this hook 607
Description
• All of the source files described in this book are in a zip file that can be
downloaded from u ww.muruch.com.
Figure B-4 How to create and restore the databases for this book
AWS (Amazon Web Services} G11
Default role. set. 540-541 DROP TABLE statement. 23. 142-143. 346 347
DEFAULT ROLE clause (CREATE USER) 540 DROP TRIGGER statement. 476-477
Default value DROP USER statement. 525-526
column.14-15 DROP VIEW statement, 374-375, 388-389
parameter. 442-443 Dump. 556-557
DELETE clause (DELETE). 154-155 Duplicate rows. eliminate. 82-83
DELETE keyword (CREATE TRIGGER). 471 Dy namic SQL. 452, 454
DELETE privilege, 518-519
DELETE statement. 23. 30-31. 154=155
through view. 386-387
E
w ith a subquery. 154-155 EC2 (Amazon Elastic Compute Cloud), 568
DELIMITER statement. 394-396 EER diagram, 16-17, 324-325, 328-329
Denormalization. 322-323 for the AP database, 328-329
Denormalize a data structure. 322-323 EER model. 324-327
DENSE.RANK function. 285-287 for the AP database. 326-327
Derived data. 321-322 MySQL Workbench. 36-37
DESC keyword ELSE clause
ORDER BY clause. 96-97 CASE function. 276-277
GROUP BY clause. 174-175 CASE statement. 404-405
index. 348-349 IF statement. 395-396. 402-403
Design (data structure), 298 299 ELSEIF clause (IF). 402-403
DETERMINISTIC characteristic (CREATE ENABLE keyword (ALTER EVENT). 480-481
FUN(’TION). 456-459 END key word. 394-395
Deterministic function. 458 event. 478-479
Diagram (database). 324-325 function. 456-457
Dialect (SQL). IS 19 stored procedure. 438-439
Dirtv read. 429 trigger. 470-471
DISABLE keyword (ALLER EVENT). 480-481 Endpoint string. 576-577
Display data. 398-399 ENGINE clause. 368-369
DISTINCT key word Enhanced entity-relationship diagram, see EER
aggregate function. 162-165 diagram
SELECT clause. 70-71. 82-83 Enhanced entity-relationship model, see EER
self-joins. 114-115 model
subquery. 196-197 Enterprise system. 4-5
WITH ROLLUP, 175 Entity, 298-299
DISTINCT ROW keyword, 83 Entity-relationship (ER) model. 324-327
DIV operator. 74-75 Entity-relationship (ER) modeling. 298-299
Div ision operator, 75 ENUM data type. 236-237
DML (data manipulation language). 22-23 Equal operator. 84-85
DO clause (( REATE EVENT). 478-479 Equijoin. 126-127
Domain. 315 ER (entity-relationship) model. 324-325
Domain-kev normal form(DKNF). 314-315 ER (entity-relationship) modeling. 298-299
DOUBLE data type. 230-231 Error
DOUBLE PRECISION data type. 231 common causes, 50-51
Double precision number. 230-231 raise in stored procedure. 444-445
DR1 (declarative referential integrity). 308 309 Error codes (MySQL). 410-411
DROP COLUMN clause. 342-343 " Error handler. 408-410
DROP DATABASE statement. 23. 334-335 Error log. 488-489
DROP EVENT statement. 480-481 Event, 394-395, 478-481
DROP FOREIGN KEY clause. 344-345 alter, 480-481
DROP FUNCTION statement. 462-463 create. 478-480
DROP INDEX statement. 23. 348 349 drop. 480-481
DROP PRIMARY KEY clause. 344-345 fire, 478-479
DROP privilege. 518-519 rotate general log. 510-511
DROP PROCEDURE statement. 394-395. 454-455 show. 480-481
DROP ROLE statement. 540-541
616 EVENT privilege Greater than operator
o OVER clause
aggregate window function. 180-181
Object privileges, 518-521 analytic function. 288-291
OFF key word (SET), 479 ranking function. 284-285
offset (Limit clause), 100-101
OLD key word (trigger). 470-471
ON clause
p
CREATE TRIGGER statement. 470-471 Parameter. 76-77
GRANT statement. 528-529 default value. 442-443
ON DELETE clause (foreign key). 340-341 function, 456-457
ON key word (SET). 478-479 input. 440-441
ON phrase (join). 106-107. 126-129 inpul/outpul. 440-441
ON SCHEDULE clause (CREATE EVENT). 479 output. 440-441
One-time event. 478-479 pass by position. 438-439
One-to-many relationship. 12-13, 306-307 stored procedure. 438-439
One-to-one relationship. 12-13, 306-308 Parse
OPEN statement (cursor). 408-409 dates and times. 264-267
Open-source database. 20-21 strings. 256-257
Operators Partition. 180-181
arithmetic. 74-75 ranking function. 284-285
comparison, 84-85 PARTION BY clause
logical. 86-87 aggregate window function. 180-181
OR operator. 86-87 analytic function. 288-289
join, 112-113 named window. 186-187
OR REPLACE keywords (CREATE VIEW). 378 OVER clause. 284-286
379, 388-389 Password, 524-525
Oracle relational DBMS, 18-19 change. 534-535
compared to other databases. 20-21 MySQL Workbench. 38-39
PASS WORD EXPIRE clause Relational Database Service (RDS) instance 621
U V
Uncorrelated subquery, 204-205 Value. 10-11
Unicode character set, 360 literal. 74. 76-77
Unicode standard, 226-227 null. 94-95
Union, 132-137 VALUES clause (INSERT), 30-31. 144-145
syntax, 132-133 VARBINARY data type. 238-239
that simulates full outer join. 136-137 VARCHAR data type. 15. 226-228. 360
UNION ALL operator (recursive CTE), 218-219 Variable. 400-401
UNION keyword. 132-137 counter. 406-407
UNION operator (recursive CTE), 219 declare. 400-401
UNIQUE attribute (column), 336-339 set. 400-401
Unique constraint, 338-339 status. 494-495
Unique key. 10-11 system. 496-501
UNIQUE keyword (index). 348-349 user, 440-441,450-451
Unix Millennium bug. 232-233 Variable-length string. 226-227
Unix operating system. 20-21 Variant (SQL). 19
Unnormalized data structure. 310-311 View, 374-389
UNSIGNED attribute benefits, 376-377
integer. 228-229 create. 378-381
real number. 230-231 delete through. 386-387
Updatable view. 382-383 insert through. 386-387
with WITH CHECK OPTION clause. 384-385 nested. 380-381
UPDATE clause. 150-151 read-only, 383
UPDATE keyword (CREATE TRIGGER). 470 replace. 378-379
471 ‘ updatable. 382-383
UPDATE privilege, 518-519 update through. 374-375, 382-385
UPDATE statement. 23. 30-31. 150-151 Viewed table. 375
through view. 374-375. 384-385 VPC (virtual private cloud). 572-573
with subquery. 152-153
UPPER function. 250-253
USAGE privilege. 520-521 w
USE statement, 334-335 WAN. 4-5
User account. 516-517 Web application, 8-9
assign to role. 538-539 Web browser. 8-9
connection. 548-549 Web server. 8-9
create. 524-526 Web-based system. 8-9
MySQL Workbench. 544-545 WEEK function. 265
remove from role. 540-541 WHEN clause
specify name. 526-527 CASE function, 276-277
USER function (ALTER USER). 534-535 CASE statement. 404-405
User variable. 440-441, 450-451 WHERE clause
Username. 526-527 compared to HAVING clause, 170-171
USING clause (EXECUTE). 452-453 DELETE statement, 154-155
USING keyword (join). 126-127, 128-129 SELECT statement. 26-27. 66-67. 84-95
UTC (Coordinated Universal Time), 262-263 subquery, 196-207
UTC.DATE function. 262-263 UPDATE statement, 150-153
UTC.TIME function, 262-263 WHILE loop. 406-407
utf8 character set. 360 WHILE statement. 397. 406-407
utf8mb3 character set. 226-227, 360-361 Wide-area network (WAN). 4-5
utf8mb4 character set. 226-228. 360-361 Wildcard (LIKE). 92-93
Window
aggregate function. 180-181
named. 186-187
626 WINDOW clause (named windowl
XYZ
Y2K38 problem. 232-233
Year 2038 problem. 232-233
YEAR data type. 233
YEAR function. 265
z/OS operating system. 20-21
100% Guarantee
When you order directly from us, you must be satisfied Try our books for 30
days or our eBooks for 14 days. They must work better than any other programming training you've
ever used, or you can return them for a prompt refund. No questions asked!
www.murach.com twitter.com/murachbooks
facebook.com/murachbooks
1-800 221-5528
(Weekdays 8 am to 4 pm Padfc Ti-nei
linkedin.com/company/
mike-murach-&-associates
[email protected] instagram.com/murachbooks
What software you need
• MySQL Community Server
• MySQL Workbench
This software is available for free, and appendixes A (Windows) and B (macOS) show how to
install it.
www.murach.com
What makes Murach books the best
During the last 50 years, nuns customers hast asked me how :t is that a small publisher in Fresno ».an nuke
the best pn»graniming books. The short answer is that no other publisher w'orks the way we do.
Instead of using freelance writers who get no training, we use a small staff of programmers who arc trained
in our proven writing and teaching methods. Instead ot publishing 40* looks each year, we focus on just a few.
Instead of show ing pieces of code, we provide complete applications that hast been checked and re-checked
for accuracy*. And instead of rushing books to market, we refuse to let schedule or budget interfere with quality.
As I see it, that’s the only* way to make sure that every book we publish is the best one on its subject.
That’s why people often tell me that our lxx>ks arc the ones that they kxikfixyirrr whenever they need to
ham a new subject. Why not try this bcxik and see for yourself! Mike Munich
Publi.'fjer
MySQL contents
What developers have said
Get started fast about the previous editions
• The concepts and terms you need for working with relational
databases and SQL 'If you ever wanted to learn to use MySQL, write SQL
• L’sc MySQL Workbench to work more efficiently' with a MySQL queries, create database elements, then this is the book
database to pick up. Rating: 10 Horseshoes.”
Review by Mohamed Sanaulla, JavaRancfi .com
Master the SQL that you'll use every day
• Write SQL statements that retrieve data from a database "A great first book into SQL: From all the SQL books I
• Write SQL statements that insert, update, and delete the data in a looked over, this has by far the best division of chapters
database and the best order for learning.”
Posted at an on me booicseller
■ Work with joins, summary queries, subquerics, data types, and
functions
"As a developer with almost 10 years of MySQL
Learn how to design and create a database experience, I still picked up a lot of new detail on things
• Design a database from start to finish, the first step toward
I thought I knew. Every development shop that works
becoming a database administrator (DBA) with MySQL should have a copy of this book.”
Dav.d Bolton, OC++/C# Guide, About.com
• L’sc an EER (enhanced entity-relationship i model and its related
diagrams to create or modify the design for a database “This book was the text in my Database Concepts class,
• Maintain referential integrity with foreign keys and I am so thankful that it was! It provided excellent
• Speed data access with indexes explanations and examples of database syntax, queries,
• Simplify’ data access with views subqueries, design, etc. I aced the class and decided to
take more database classes because of this book.”
Master stored programs Posted at an on me bookseller