Download DBA 1: Introduction to Database Administration

Document related concepts

IMDb wikipedia , lookup

Tandem Computers wikipedia , lookup

DBase wikipedia , lookup

Microsoft Access wikipedia , lookup

Relational algebra wikipedia , lookup

Concurrency control wikipedia , lookup

Extensible Storage Engine wikipedia , lookup

Functional Database Model wikipedia , lookup

Oracle Database wikipedia , lookup

Entity–attribute–value model wikipedia , lookup

Ingres (database) wikipedia , lookup

Database wikipedia , lookup

Microsoft Jet Database Engine wikipedia , lookup

Null (SQL) wikipedia , lookup

Clusterpoint wikipedia , lookup

Microsoft SQL Server wikipedia , lookup

Open Database Connectivity wikipedia , lookup

SQL wikipedia , lookup

Database model wikipedia , lookup

Relational model wikipedia , lookup

PL/SQL wikipedia , lookup

Transcript
DBA 1: Introduction to Database Administration
Lesso n 1: Int ro duct io n
Getting Started
Lesso n 2: St o ring Dat a
Sto ring Data
Data and Data Types
What is NULL and NOT NULL, Anyway?
Our First Table
Lesso n 3: Re lat io nships Be t we e n T able s
Other Tables
Lesso n 4: INSERT , SELECT , UPDAT E, DELET E
DESCRIBING Yo ur Tables
Insert
SELECT
Update
Delete
Lesso n 5: T ransact io ns
Making Sure Yo ur Co mmands Behave
ACID
Transactio n Iso latio n Levels
Using Transactio ns
Co mmitting and ro lling back
Lesso n 6 : J o ins
Co mbining Tables with a Jo in
Other Jo ins
Left Jo ins
Full Outer Jo ins / Unio n
Lesso n 7: Aggre gat e s, Funct io ns, and Co ndit io nals
Aggregating Data
Functio ns
Co nditio nals
Lesso n 8 : Subque rie s and Vie ws
Querying Queries
Views
Creating a View
Restrictio ns o n Views
Dro pping a View
Lesso n 9 : St o re d Pro ce dure s
Using Sto red Pro cedures
Mo tivatio ns
Creating Sto red Pro cedures
Setup
Duplicating o ur View
Parameters
Variables
Lesso n 10 : PIVOT and UNPIVOT
PIVOTing Data
UNPIVOTing Data
Lesso n 11: Full T e xt
Creating Full-Text Indexes
Querying Full-Text Indexes
Lesso n 12: Inf o rm at io n Abo ut t he Dat abase
INFORMATION_SCHEMA
TABLES
COLUMNS
VIEWS
ROUTINES
Lesso n 13: Final Pro je ct
Final Pro ject Specificatio n
Copyright © 1998-2014 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
Introduction
Welco me to the O'Reilly DBA Series!
In this co urse, yo u will learn the basics to create a well-designed database using basic database co mmands. Yo u will also
learn ho w to manipulate the data sto red in these tables and to return meaningful results to help analyze the data sto red.
Course Objectives
When yo u co mplete this co urse, yo u will be able to :
create, read, update, and delete data using basic SQL co mmands.
perfo rm relatio nal jo ins and transactio ns o n SQL tables.
aggregate data thro ugh functio ns and co nditio nals.
perfo rm subqueries and manipulate views.
create sto red pro cedures within SQL.
summarize data using PIVOT and UNPIVOT.
demo nstrate kno wledge o f data indices and info rmatio n schemas.
create a full-fledged blo g database.
Fro m beginning to end, yo u will learn by do ing pro jects in yo ur o wn Unix and MySQL enviro nments, and then handing them in
fo r instructo r feedback. These pro jects, as well as the final pro ject—develo ping a co mplete database and demo nstrating
administrative tasks—will add to yo ur po rtfo lio and will co ntribute to certificate co mpletio n. Besides a bro wser and internet
co nnectio n, all so ftware is pro vided o nline by the O'Reilly Scho o l o f Techno lo gy.
Learning with O'Reilly School of T echnology Courses
As with every O'Reilly Scho o l o f Techno lo gy co urse, we'll take a user-active appro ach to learning. This means that yo u
(the user) will be active! Yo u'll learn by do ing, building live pro grams, testing them and experimenting with them—
hands-o n!
To learn a new skill o r techno lo gy, yo u have to experiment. The mo re yo u experiment, the mo re yo u learn. Our system
is designed to maximize experimentatio n and help yo u learn to learn a new skill.
We'll pro gram as much as po ssible to be sure that the principles sink in and stay with yo u.
Each time we discuss a new co ncept, yo u'll put it into co de and see what YOU can do with it. On o ccasio n we'll even
give yo u co de that do esn't wo rk, so yo u can see co mmo n mistakes and ho w to reco ver fro m them. Making mistakes
is actually ano ther go o d way to learn.
Abo ve all, we want to help yo u to learn to learn. We give yo u the to o ls to take co ntro l o f yo ur o wn learning experience.
When yo u co mplete an OST co urse, yo u kno w the subject matter, and yo u kno w ho w to expand yo ur kno wledge, so
yo u can handle changes like so ftware and o perating system updates.
Here are so me tips fo r using O'Reilly Scho o l o f Techno lo gy co urses effectively:
T ype t he co de . Resist the temptatio n to cut and paste the example co de we give yo u. Typing the co de
actually gives yo u a feel fo r the pro gramming task. Then play aro und with the examples to find o ut what else
yo u can make them do , and to check yo ur understanding. It's highly unlikely yo u'll break anything by
experimentatio n. If yo u do break so mething, that's an indicatio n to us that we need to impro ve o ur system!
T ake yo ur t im e . Learning takes time. Rushing can have negative effects o n yo ur pro gress. Slo w do wn and
let yo ur brain abso rb the new info rmatio n tho ro ughly. Taking yo ur time helps to maintain a relaxed, po sitive
appro ach. It also gives yo u the chance to try new things and learn mo re than yo u o therwise wo uld if yo u
blew thro ugh all o f the co ursewo rk to o quickly.
Expe rim e nt . Wander fro m the path o ften and explo re the po ssibilities. We can't anticipate all o f yo ur
questio ns and ideas, so it's up to yo u to experiment and create o n yo ur o wn. Yo ur instructo r will help if yo u
go co mpletely o ff the rails.
Acce pt guidance , but do n't de pe nd o n it . Try to so lve pro blems o n yo ur o wn. Go ing fro m
misunderstanding to understanding is the best way to acquire a new skill. Part o f what yo u're learning is
pro blem so lving. Of co urse, yo u can always co ntact yo ur instructo r fo r hints when yo u need them.
Use all available re so urce s! In real-life pro blem-so lving, yo u aren't bo und by false limitatio ns; in OST
co urses, yo u are free to use any reso urces at yo ur dispo sal to so lve pro blems yo u enco unter: the Internet,
co urses, yo u are free to use any reso urces at yo ur dispo sal to so lve pro blems yo u enco unter: the Internet,
reference bo o ks, and o nline help are all fair game.
Have f un! Relax, keep practicing, and do n't be afraid to make mistakes! Yo ur instructo r will keep yo u at it
until yo u've mastered the skill. We want yo u to get that satisfied, "I'm so co o l! I did it!" feeling. And yo u'll have
so me pro jects to sho w o ff when yo u're do ne.
Lesson Format
We'll try o ut lo ts o f examples in each lesso n. We'll have yo u write co de, lo o k at co de, and edit existing co de. The co de
will be presented in bo xes that will indicate what needs to be do ne to the co de inside.
Whenever yo u see white bo xes like the o ne belo w, yo u'll type the co ntents into the edito r windo w to try the example
yo urself. The CODE TO TYPE bar o n to p o f the white bo x co ntains directio ns fo r yo u to fo llo w:
CODE TO TYPE:
White boxes like this contain code for you to try out (type into a file to run).
If you have already written some of the code, new code for you to add looks like this.
If we want you to remove existing code, the code to remove will look like this.
We may also include instructive comments that you don't need to type.
We may run pro grams and do so me o ther activities in a terminal sessio n in the o perating system o r o ther co mmandline enviro nment. These will be sho wn like this:
INTERACTIVE SESSION:
The plain black text that we present in these INTERACTIVE boxes is
provided by the system (not for you to type). The commands we want you to type look lik
e this.
Co de and info rmatio n presented in a gray OBSERVE bo x is fo r yo u to inspect and absorb. This info rmatio n is o ften
co lo r-co ded, and fo llo wed by text explaining the co de in detail:
OBSERVE:
Gray "Observe" boxes like this contain information (usually code specifics) for you to
observe.
The paragraph(s) that fo llo w may pro vide additio n details o n inf o rm at io n that was highlighted in the Observe bo x.
We'll also set especially pertinent info rmatio n apart in "No te" bo xes:
Note
T ip
No tes pro vide info rmatio n that is useful, but no t abso lutely necessary fo r perfo rming the tasks at hand.
Tips pro vide info rmatio n that might help make the to o ls easier fo r yo u to use, such as sho rtcut keys.
WARNING
Warnings pro vide info rmatio n that can help prevent pro gram crashes and data lo ss.
T he CodeRunner Screen
This co urse is presented in Co deRunner, OST's self-co ntained enviro nment. We'll discuss the details later, but here's
a quick o verview o f the vario us areas o f the screen:
These video s explain ho w to use Co deRunner:
File Management Demo
Co de Edito r Demo
Co ursewo rk Demo
Getting Started
In this co urse, yo u will be creating SQL files. SQL files are made up o f SQL statements and have an .sql extensio n.
Click the Ne w T e rm inal butto n
to co nnect to Unix o r click the Co nne ct t o MySQL butto n
to co nnect directly
to the MySQL server. In this co urse we'll primarily use the Unix Terminal and no t the MySQL server directly. By do ing
so we have so me additio nal co ntro l o ver ho w we co nnect to MySQL. Many o f the pro jects will be turned in as SQL
files.
Click the Ne w T e rm inal butto n
to co nnect to Unix no w. Yo u will see pro mpts fo r the lo gin and passwo rd yo u
were given when yo u registered with OST, altho ugh the system may fill o ne o r bo th o f these in fo r yo u. If the system
do esn't auto matically lo g yo u in, type yo ur username and passwo rd when pro mpted. (Yo u may need to click inside the
Unix Terminal windo w to be able to type. When typing yo ur passwo rd, yo u will no t see any characters reflected back to
yo u as yo u type.) Yo u will then be lo gged in to o ne o f the OST servers.
Once yo u see the UNIX pro mpt, it's time to co nnect to MySQL! Be sure to replace bo th o ccurrences o f username with
yo ur o wn username.
Type the fo llo wing at the UNIX pro mpt:
cold1:~$ mysql -h sql -p -u username username
Yo ur screen will lo o k like this:
OBSERVE:
cold1:~$ mysql -h sql -p -u username username
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 135535
Server version: 5.1.69-log Source distribution
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
To co nnect to a mysql database, we run the pro gram m ysql. To specify which database server we want to co nnect to ,
we type -h sql. We want to be pro mpted to pro vide a passwo rd, so we use the -p o ptio n. To specify o ur username, we
use the -u username o ptio n. Finally, the database we want to use has the same name as o ur username, so we
pro vide it again: username.
Befo re we are ready to use MySQL, let's type in a co mmand that tells MySQL to act in a "traditio nal" way. The
co mmand will cause MySQL to act mo re like Po stgreSQL, Micro so ft SQL Server, and Oracle.
Type the fo llo wing at the MySQL pro mpt:
mysql> set sql_mode='traditional';
Query OK, 0 rows affected (0.00 sec)
mysql>
When yo u are ready to leave mysql and return to the Unix pro mpt, type e xit as sho wn.
INTERACTIVE SESSION:
mysql> exit
Bye
cold1:~$
Fo r mo st pro jects, yo u will select SQL fro m the Syntax menu in Co deRunner. If yo u are in the Unix Terminal, click o n
the "untitled" tab next to the Terminal tab. No w, click the Ne w File butto n in the menu bar to create a new "untitled"
tab.
Enter the fo llo wing co de as sho wn:
Type the fo llo wing into Co deRunner:
set sql_mode='traditional';
select now();
select 'hello world' as Message;
To save yo ur file, click the Save butto n
. Fo r this example, name the file dba1le sso n1pro je ct 1.sql:
Note
When naming files and creating tables, please be sure to name them exactly as requested. The .sql
extensio n is impo rtant fo r MySQL files, and in a Unix system, case is significant: dba1lesso n1pro ject1.sql
and DBA1Lesso n1Pro ject1.sql wo uld be entirely different files, and Artists and artists wo uld be different
tables. While file and table names are case sensitive, MySQL keywo rds, such as SET and SELECT , are
no t, and can be entered in either upper o r lo wer case.
To o pen a file yo u have previo usly saved, click the Lo ad butto n
and select the file fro m the Lo ad File windo w, o r
do uble-click the file in the File Bro wser. No te that when yo u save a file, the wo rd "untitled" is replaced by the file name
in the co de edito r tab. When yo u o pen a file, the file o pens in a new tab.
Test it in the Unix Terminal using the fo llo wing co mmand:
Type the fo llo wing at the UNIX pro mpt:
cold1:~$ mysql -t -h sql -p -u username username < dba1lesson1project1.sql
Enter password:
+---------------------+
| now()
|
+---------------------+
| 2013-10-16 15:56:48 |
+---------------------+
+-------------+
| Message
|
+-------------+
| hello world |
+-------------+
cold1:~$
OBSERVE:
cold1:~$ mysql -t -h sql -p -u username username < dba1lesson1project1.sql
The -t o ptio n tells MySQL to o utput yo ur queries in a nice table fo rmat. Be sure to replace username with yo ur specific
username, and dba1le sso n1pro je ct 1.sql with yo ur pro ject filename.
Yo u've finished this lesso n! When yo u finish a lesso n, co mplete the ho mewo rk o bjectives and quizzes. To get started
o n the first o bjective, click Obje ct ive 1 in the curriculum area in the upper left. Fo r this o bjective, yo u'll submit the
dba1le sso n1pro je ct 1.sql file we created here.
No w yo u're ready to mo ve o n to the next lesso n, where yo u'll dive right in and create so me tables!
Copyright © 1998-2014 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
Storing Data
Storing Data
Befo re we get started, make sure yo u are in the Unix Terminal and then co nnect to MySQL. Click the Ne w T e rm inal
butto n
and lo g in. Be sure to click in the windo w befo re yo u start typing. When yo u have lo gged in, co nnect to the
MySQL server. Remember to replace username with yo ur actual username, and be sure to type yo ur username twice!
Type the fo llo wing at the UNIX pro mpt:
cold1:~$ mysql -h sql -p -u username username
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 778597
Server version: 5.0.41-community-log MySQL Community Edition (GPL)
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql>
Do n't fo rget—yo u also need to set the 'TRADITIONAL' mo de.
Type the fo llo wing at the MySQL pro mpt:
mysql> set sql_mode='traditional';
No w yo u're ready to go !
Databases excel at fo ur o peratio ns: Creating data, Reading data, Updating data, and Deleting data; we refer to these
o peratio ns co llectively as CRUD. The mo st po pular databases use Structured Query Language (SQL) to perfo rm
tho se o peratio ns.
Yo u canno t build a skyscraper witho ut blueprints, and yo u canno t sto re data in a database witho ut defining what type o f
info rmatio n yo u wish to sto re, and ho w yo u want to sto re it. The subset o f SQL to create yo ur blueprints is called Data
Definition Language (DDL).
Data and Data T ypes
Befo re yo u can build the walls o f a skyscraper, yo u must decide which material yo u will use to build yo ur
walls. Database administrato rs must also cho o se the material with which to co nstruct their database. Let's
wo rk with an example.
Suppo se yo u've just been hired by a used bo o k sto re. Yo ur jo b is to build a new database system fo r tracking
bo o ks, amo ng o ther things.
Since we are interested in keeping track o f bo o ks, we need to determine the data that co mprises a bo o k. Mo st
bo o ks have a title, an autho r, the date the bo o k was published, a co unt o f the number o f pages, and a price.
So me bo o ks co ntain a brief descriptio n o f their co ntent, o thers do no t. Fo r example, Database Nation was
written by Simso n Garfinkel in December 20 0 0 and currently co sts $16 .9 5. The descriptio n o f the bo o k reads:
"As the 21st century begins, advances in techno lo gy endanger o ur privacy in ways never befo re imagined.
This newly revised update o f the po pular hardco ver editio n, 'Database Natio n: The Death o f Privacy in the 21st
Century,' is the co mpelling acco unt o f ho w invasive techno lo gies will affect o ur lives in the co ming years. It's
a timely, far-reaching, entertaining, and tho ught-pro vo king lo o k at the serio us threats to privacy facing us
to day."
Here is the co ver o f Database Nation, with so me o f its data items highlighted:
Database tables sto re info rmatio n in ro ws and co lumns. The co lumns are the definitio n (o r template) that
each ro w must fo llo w. Fo r a table that sto res bo o k info rmatio n, we might have co lumns fo r T it le , Aut ho r,
Dat e Publishe d, Num be r o f Page s, Price , and De script io n.
Each co lumn o f info rmatio n is o f a different type. Fo r example, the title and autho r are textual. The date
published is exactly that: a date. The number o f pages is a no n-negative integer. The co st is a decimal, with
two decimal places. The descriptio n, if o ne exists, is also textual.
As a database administrato r (DBA), yo ur jo b is to pick the smallest and mo st appro priate data type fo r the
info rmatio n we want to sto re. Yo u co uld just sto re everything as a bunch o f wo rds. Fo r example, yo u co uld
sto re the Date Published as 0 5 /10 /20 0 7 . If yo u saw this data, wo uld yo u be certain it was May 10 th, 20 0 7, o r
co uld it be Octo ber 5th, 20 0 7? If yo u sto re it as a date, there wo uld be no questio n, because the database
co uld return the date to yo u in any fo rm yo u like, even "May 10 th, 20 0 7." It co uld also do so me calculatio ns
fo r yo u, like tell yo u that "o ne mo nth prio r to the publish date" was "April 10 th, 20 0 7."
Data types can be classified into three gro ups: text data types, numeric data types, and date/time data types.
Here are so me o f the data types MySQL suppo rts:
Gro up
Dat a T ype
De script io n
Sam ple
Text
CHAR
A fixed length o f zero to 255 characters. Useful fo r data like state
co des, which are always two characters lo ng.
IL
Text
VARCHAR
A variable length o f zero to 6 5535 characters. Useful fo r data
who se length varies, but is always within a certain size range.
Co mmo n examples are first o r last names.
ILLINOIS
Text
TEXT
A variable length o f up to 6 5535 characters.
Illino is is a
great state.
Text
MEDIUMTEXT A variable length o f up to 16 777215 characters.
This
histo ry o f
Illino is...
Text
LONGTEXT
A variable length o f up to 429 49 6 729 5 characters.
The lo nger
histo ry o f
Illino is...
Numeric INT
Integer (who le) numbers.
5
Numeric FLOAT
An appro ximate decimal po int value sto red in 4 bytes.
5.15
Numeric DOUBLE
An appro ximate decimal po int value sto red in 8 bytes.
7.25
Numeric DECIMAL
An exact decimal po int value. The preferred data type fo r sto ring
mo netary values such as prices o r salaries.
2.25
Date
DATE
Year, mo nth and day.
20 0 9 -1231
Date
DATETIME
Year, mo nth, day and time.
20 0 9 -1231
14:25:0 0
Date
TIME
Time o nly.
14:25:0 0
Date
YEAR
Year o nly. Year(4) has a range o f 19 0 1-2155, year(2) has a range o f
20 12
19 70 -20 6 9 .
What is NULL and NOT NULL, Anyway?
In a database, yo u might have a co lumn that is o ptio nal, such as a seco nd address line fo r yo ur custo mers.
Elsewhere yo u might want to sto re so me bit o f info rmatio n, like the list price (a decimal), which is also
o ptio nal. Yo u co uld set the list price to be $-9 9 9 9 .9 9 and define that value as the "no list price" value, but
there is a better way.
NULL is no thing. It is no value.
WARNING
Be careful with NULL—NULL is no t equal to "" o r 0 . It is not an empty string. It cannot be
co mpared to so mething else. Ho wever, even tho ugh is no thing, yo u can tell if so mething
IS NULL o r IS NOT NULL.
Our First T able
In o rder to interact quickly with data in o ur tables, we need to define the primary key co lumns o n o ur table. A primary
key is the minimum set o f info rmatio n needed to uniquely identify a ro w in a database table. At first glance, the primary
key fo r o ur bo o k table co uld be the title.
Dat abase Nat io n is o ne title; ho wever, the bo o k might co me in hardco ver and paperback editio ns, and there might
so meday be ano ther bo o k with the same title. If o ur bo o k sto re sto cks bo th editio ns, o r the o ther bo o k with the same
title, the title "Database Natio n" alo ne wo n't be eno ugh fo r us to distinguish between the different bo o ks. Thus we wo n't
be able to use the title as o ur primary key.
Amo ng o ther aspects o f a bo o k that we might sto re in a database, the price, the autho r, the descriptio n, and the
catego ry are all po tentially no t unique.
Yo u might decide to sho eho rn so me extra info rmatio n to the bo o k's title, perhaps creating two bo o ks:
Database Natio n - Hard Co py
Database Natio n - Paperback
This type o f co mpro mise isn't a go o d idea. The title is Dat abase Nat io n, no t Dat abase Nat io n - Hard Co py.
Our manager might step in at this po int, and tell us that everything in the sto re has a unique Pro duct Co de . This
pro duct co de sho uld be o ur primary key, since it can be used to uniquely identify a ro w in o ur table.
We will use the Pro duct Co de as o ur primary key, add a co lumn called Cat e go ry, and fo rget abo ut the Autho r, the
Date Published, and Number o f Pages co lumns fo r no w.
Befo re we get started, make sure Co deRunner is in MySQL mo de. Click in the windo w, and type in yo ur passwo rd.
Type the fo llo wing at the MySQL pro mpt:
mysql> CREATE TABLE Products
--> (
-->
ProductCode char(20) NOT NULL,
-->
Title varchar(50) NOT NULL,
-->
Category varchar(30) NOT NULL,
-->
Description text,
-->
Price DECIMAL(9,2) NOT NULL,
-->
PRIMARY KEY(ProductCode)
--> ) ENGINE=INNODB;
Query OK, 0 rows affected (0.00 sec)
mysql>
Let's take a clo ser lo o k:
OBSERVE:
mysql> CREATE TABLE Products
--> (
-->
ProductCode char(20) NOT NULL,
-->
Title varchar(50) NOT NULL,
-->
Category varchar(30) NOT NULL,
-->
Description text,
-->
Price DECIMAL(9,2) NOT NULL,
-->
PRIMARY KEY(ProductCode)
--> ) ENGINE=INNODB;
The Pro duct s table is fairly small; it co ntains a Pro duct Co de used to uniquely identify a ro w, the Title o f the item, a
Catego ry, an o ptio nal Descriptio n, and the Price. The NOT NULL keywo rds indicate which co lumns are required
(canno t be null). We didn't specify "NOT NULL" fo r De script io n, so we do n't require a value in that co lumn. Finally, we
specify o ur PRIMARY KEY as Pro duct Co de .
Can a primary key be null? Create a little test table to find o ut.
Note
In this co urse, we use the INNODB engine (ENGINE=INNODB) fo r mo st o f the tables we create. This
engine allo ws us to use mo re standard SQL than the no rmal MySQL tables.
Believe it o r no t, yo u just created a new table! In the next lesso n, yo u'll create additio nal tables, and see ho w all o f the tables
relate to each o ther. See yo u there!
Copyright © 1998-2014 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
Relationships Between Tables
Other T ables
In the last lesso n, we learned ho w to create tables. One table is o kay, but we'll need a few additio nal tables to keep
track o f custo mers, invento ry, and o rders.
In the last lesso n we decided to sto re the Pro ductCo de, Title, Catego ry, Descriptio n, and Price fo r all o f o ur bo o ks.
Being a bo o k sto re, it wo uld be nice to track o ur custo mers and o rders so we kno w which bo o ks are selling well. We
co uld add a new co lumn called "Custo mer" and a co lumn called "DatePurchased" to o ur bo o k table, but then we
wo uld have to co py the Pro ductCo de, Title, Catego ry, Descriptio n and Price each time a bo o k was so ld! Also , we
designed the Pro ducts table to co ntain pro ducts, and a custo mer isn't a pro duct!
A better so lutio n is to use a separate table fo r each gro up o f info rmatio n—a table fo r bo o ks, a table fo r custo mers, and
a table fo r o rders. This way we do n't have a lo t o f duplicate info rmatio n in o ur tables, wasting space and po tentially
causing co nfusio n.
MySQL, Po stgreSQL, Oracle, and SQL Server are all relational databases. They efficiently sto re info rmatio n in multiple
tables that are linked to gether by relatio nships.
The first table we'll create will keep track o f custo mers. The data used to describe a custo mer sho uld include their first
and last name, address, and email address. But suppo se yo u had two custo mers with the name "Jo hn Smith," o r a
custo mer who shares his email address with his wife? Ho w wo uld yo u keep these individual entries separate?
We need a primary key fo r o ur custo mer table, but we really do n't have any unique info rmatio n. Fo rtunately we can
have the database create a unique co lumn fo r us. MySQL pro vides an AUT O_INCREMENT that will auto matically
po pulate a co lumn with an increasing integer number. The value fo r the first ro w is 1, then the next ro w is 2, and so o n.
It do es no t repeat numbers.
This type o f key is also kno wn as a surrogate key. We'll use a surro gate key fo r o ur custo mer table, and call it
Cust o m e rID.
Type the fo llo wing at the MySQL pro mpt:
mysql>
->
->
->
->
->
->
->
->
->
->
->
->
->
Query
mysql>
CREATE TABLE Customers
(
CustomerID int AUTO_INCREMENT NOT NULL,
FirstName varchar(50) NOT NULL,
LastName varchar(50) NOT NULL,
AddressLine1 varchar(50) NOT NULL,
AddressLine2 varchar(50),
City varchar(50) NOT NULL,
State char(2),
PostalCode varchar(10),
EmailAddress varchar(100),
DateAdded DATETIME NOT NULL,
PRIMARY KEY(CustomerID)
) ENGINE=INNODB;
OK, 0 rows affected (0.01 sec)
Let's discuss so me impo rtant parts o f this co mmand:
OBSERVE:
mysql> CREATE TABLE Customers
-> (
->
CustomerID int AUTO_INCREMENT NOT NULL,
->
FirstName varchar(50) NOT NULL,
->
LastName varchar(50) NOT NULL,
->
AddressLine1 varchar(50) NOT NULL,
->
AddressLine2 varchar(50),
->
City varchar(50) NOT NULL,
->
State char(2),
->
PostalCode varchar(10),
->
EmailAddress varchar(100),
->
DateAdded DATETIME NOT NULL,
->
PRIMARY KEY(CustomerID)
-> ) ENGINE=INNODB;
The f irst line t e lls t he dat abase se rve r t o cre at e a ne w t able nam e d Cust o m e rs.
This table co ntains o ur surro gate key co lumn named Cust o m e rID. No tice the use o f the mySQL-specific
AUT O_INCREMENT keywo rd.
Note
Auto -Increment co lumns so metimes have gaps. Fo r instance, a table may have a 1 in the first ro w, then 5
in the next ro w, depending o n whether ro ws are added o r remo ved fro m the table.
Next, we defined the name co lumn. First Nam e will be a varchar with a maximum length o f 5 0 characters. This sho uld
be a required value fo r all custo mers, so it is defined as NOT NULL. The co lumns fo r LastName and AddressLine1
are defined similarly.
Addre ssLine 2 is also a varchar o f maximum length 5 0 characters, but since so me peo ple do n't have a seco nd
address line, yo u do n't need to include the NOT NULL keywo rds.
Dat e Adde d will sto re the date and time the custo mer is added to the table.
Finally, yo u let the database engine kno w that the PRIMARY KEY is the surro gate key, Cust o m e rID.
No w that yo u have the Custo mers table in place, let's create so me additio nal tables to help o rganize the bo o ksto re.
We'll need to create tables to sto re Inve nt o ry, track Orde rs, and tell us what pro ducts make up an o rder
(Orde rLine ). We can represent these tables graphically this way:
In the diagram, arro ws po int to the so urce o f the info rmatio n. In o ther wo rds, the Cust o m e rID in Orders has a
co rrespo nding Cust o m e rID in Custo mers.
Here are the o ther tables we'll create:
T able Nam e
Co lum ns
Invento ry
Pro ductCo de, QuantityInSto ck
Orders
OrderNumber, Custo merID, Invo iceNumber, DatePlaced, OrderStatus
Order Line
OrderNumber, Pro ductCo de, Quantity, ExtendedAmo unt
The Inve nt o ry table will keep track o f the number o f bo o ks in sto ck. No te that we uniquely identify the quantity in sto ck
by Pro duct Co de , which relates back to the Pro ducts table. We need to include the Pro duct Co de in bo th tables in
o rder to make this link. A Pro ductCo de o f "ABC123" in Pro ducts will co rrespo nd exactly to a Pro ductCo de o f "ABC123"
in Invento ry.
Type the fo llo wing at the MySQL pro mpt:
mysql> CREATE TABLE Inventory
(
ProductCode char(10) NOT NULL,
QuantityInStock int NOT NULL,
PRIMARY KEY(ProductCode)
) ENGINE=INNODB;
Query OK, 0 rows affected (0.00 sec)
mysql>
Next, create a table to ho ld Orde rs. This table will co ntain an auto -increment co lumn to uniquely identify each o rder.
Type the fo llo wing at the MySQL pro mpt:
mysql> CREATE TABLE Orders
(
OrderNumber int AUTO_INCREMENT NOT NULL,
CustomerID int NOT NULL,
InvoiceNumber varchar(15),
DatePlaced DATETIME,
OrderStatus char(10),
PRIMARY KEY(OrderNumber)
) ENGINE=INNODB;
Query OK, 0 rows affected (0.01 sec)
mysql>
Finally, the Orde rLine table will be used to reco rd the items purchased fo r each unique o rder.
Type the fo llo wing at the MySQL pro mpt:
mysql> CREATE TABLE OrderLine
(
OrderNumber int NOT NULL,
ProductCode char(10) NOT NULL,
Quantity int NOT NULL,
ExtendedAmount DECIMAL(9, 2) NOT NULL,
PRIMARY KEY(OrderNumber, ProductCode)
) ENGINE=INNODB;
Query OK, 0 rows affected (0.01 sec)
mysql>
This table has so mething new:
OBSERVE:
PRIMARY KEY(OrderNumber, ProductCode)
The PRIMARY KEY is defined o n two co lumns. A PRIMARY KEY uniquely identifies a ro w in a table. Often the primary
key is just o ne co lumn, such as a userid o r UPC co de. It can be multiple co lumns, ho wever.
Note
A key (primary o r o ther) that spans multiple co lumns is also kno wn as a composite key.
In o ur table the Orde rNum be r and Pro duct Co de to gether will uniquely identify a ro w.
Believe it o r no t... yo u just made fo ur new tables! In the next lesso n yo u will learn ho w to sto re data in these tables. See yo u
there!
Copyright © 1998-2014 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
INSERT, SELECT, UPDATE, DELETE
DESCRIBING Your T ables
In the last lesso n yo u created tables that will sto re data fo r yo ur bo o ksto re. No w it's time to actually sto re so me data!
Befo re we get started, let's examine the tables created in the last lesso n. MySQL has a DESCRIBE keywo rd that can
be used to do just that.
Note
Befo re yo u get started, make sure yo u are co nnected to MySQL, and have set the 'traditio nal' mo de.
Type the fo llo wing at the MySQL pro mpt:
mysql> DESCRIBE Customers;
+--------------+--------------+------+-----+---------+----------------+
| Field
| Type
| Null | Key | Default | Extra
|
+--------------+--------------+------+-----+---------+----------------+
| CustomerID
| int(11)
| NO
| PRI | NULL
| auto_increment |
| FirstName
| varchar(50) | NO
|
|
|
|
| LastName
| varchar(50) | NO
|
|
|
|
| AddressLine1 | varchar(50) | NO
|
|
|
|
| AddressLine2 | varchar(50) | YES |
| NULL
|
|
| City
| varchar(50) | NO
|
|
|
|
| State
| char(2)
| YES |
| NULL
|
|
| PostalCode
| varchar(10) | YES |
| NULL
|
|
| EmailAddress | varchar(100) | YES |
| NULL
|
|
| DateAdded
| datetime
| NO
|
|
|
|
+--------------+--------------+------+-----+---------+----------------+
10 rows in set (0.02 sec)
DESCRIBE returns a lo t o f useful info rmatio n: the co lumn names, the data types (and sizes), whether the co lumn can
be NULL, any default values, and whether the co lumn is auto _increment.
Insert
To add data to a table, use the INSERT keywo rd.
Type the fo llo wing at the MySQL pro mpt:
mysql> INSERT INTO Customers
-> (FirstName, LastName, AddressLine1, City, State, PostalCode, DateAdded, EmailAdd
ress)
-> VALUES ('John', 'Smith', '123 4th Street', 'Chicago', 'IL', '60606', NOW(), 'joh
[email protected]');
Query OK, 1 row affected (0.01 sec)
Co ngratulatio ns, yo u just added a ro w o f data into yo ur table! Let's lo o k clo ser.
OBSERVE:
mysql> INSERT INTO Customers
->(FirstName, LastName, AddressLine1, City, State, PostalCode, DateAdded, EmailAddr
ess)
->VALUES ('John', 'Smith', '123 4th Street', 'Chicago', 'IL', '60606', NOW(), 'john
@hotmail.com');
The syntax fo r INSERT is fairly co mpact. First, yo u specify the target table fo r yo ur data—in this case, Cust o m e rs.
Next, yo u list the specific co lumns fo r which yo u will pro vide data. There are co mmas between each co lumn name, and
they are enclo sed within pare nt he se s ().
Note
Yo u do n't have to pro vide data fo r all co lumns—o nly the required (no n-null) co lumns.
Next, yo u specify the VALUES fo r each co lumn. Values that will be sto red in text co lumns must have single quo tatio n
marks (') aro und them.
The DateAdded co lumn in the Custo mers table must be the date, right now. Fo rtunately, mySQL pro vides a NOW()
functio n that returns the date and time in the pro per fo rmat fo r use in o ur table.
Note
It's o kay to change the o rder o f yo ur co lumns—see ho w DateAdded is befo re EmailAddress? Just
remember to pro vide yo ur VALUES in the same o rder yo u specified the co lum ns.
No w let's insert ano ther reco rd.
Type the fo llo wing at the MySQL pro mpt:
mysql> INSERT INTO Customers
-> (FirstName, LastName, DateAdded, EmailAddress)
-> VALUES ('Jane', 'Adams', NOW(), '[email protected]');
ERROR 1364 (HY000): Field 'AddressLine1' doesn't have a default value
mysql>
While this erro r message may seem strange, everything is wo rking perfectly. When we created the table, we defined the
co lumn "AddressLine1" to be NOT NULL. We didn't pro vide a value fo r AddressLine1 in o ur insert statement, the
database set it to NULL by default, resulting in this erro r.
WARNING
If yo u see so mething like Que ry OK, 1 ro w af f e ct e d, 2 warnings (0 .0 0 se c), yo u'll need to go
back to the start o f the lesso n and make sure yo u typed the SET sql_m o de ='T RADIT IONAL';
co mmand. Yo u sho uld also remo ve everything fro m Custo mers and start again—to do this, type
DELET E FROM Cust o m e rs; at the MySQL pro mpt.
Fix yo ur INSERT statement by pro viding the AddressLine1 and City:
Type the fo llo wing at the MySQL pro mpt:
mysql> INSERT INTO Customers
-> (FirstName, LastName, DateAdded, EmailAddress, AddressLine1, City)
-> VALUES ('Jane', 'Adams', NOW(), '[email protected]', '300 N. Michigan', 'Chicago'
);
Query OK, 1 row affected (0.01 sec)
mysql>
Add mo re custo mers—try adding o ne with an AddressLine2.
SELECT
INSERTing data into tables is fine, but chances are yo u want to retrieve info rmatio n as well. In SQL, the keywo rd to get
info rmatio n o ut o f a table is SELECT .
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT * FROM Customers;
+------------+-----------+----------+-----------------+--------------+---------+------+------------+------------------+---------------------+
| CustomerID | FirstName | LastName | AddressLine1
| AddressLine2 | City
| State
| PostalCode | EmailAddress
| DateAdded
|
+------------+-----------+----------+-----------------+--------------+---------+------+------------+------------------+---------------------+
|
21 | John
| Smith
| 123 4th Street | NULL
| Chicago | IL
| 60606
| [email protected] | 2007-09-19 20:36:38 |
|
31 | Jane
| Adams
| 300 N. Michigan | NULL
| Chicago | NULL
| NULL
| [email protected] | 2007-09-19 20:52:36 |
+------------+-----------+----------+-----------------+--------------+---------+------+------------+------------------+---------------------+
2 rows in set (0.00 sec)
mysql>
Note
The Custo merID values yo u see pro bably wo n't match yo ur o wn Custo merIDs, because the co lumn is
an auto increment co lumn.
Yo ur o utput may no t lo o k to o nice—in fact it might be pretty ugly! That's because MySQL may have to wrap the ro ws to
fit yo ur screen. As yo u learn mo re abo ut MySQL, yo u'll disco ver o ther ways to present the info rmatio n. Fo r example,
try SELECT * FROM Cust o m e rs\G. We wo n't get into this in detail here, but fo r an idea o f what's available, see the
MySQL develo per do cumentatio n.
In a SELECT statement (as in many co mputer co mmands), the asterisk (*) means "all co lumns." Thus the SQL
statement yo u entered co uld be translated to English as "retrieve data fro m all co lumns, fro m the table called
Custo mers."
Of co urse, the list returned fro m this SELECT statement is pretty lo ng, so let's o mit the address info rmatio n fo r no w.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT CustomerID, FirstName, LastName, EmailAddress FROM Customers;
+------------+-----------+----------+------------------+
| CustomerID | FirstName | LastName | EmailAddress
|
+------------+-----------+----------+------------------+
|
21 | John
| Smith
| [email protected] |
|
31 | Jane
| Adams
| [email protected] |
+------------+-----------+----------+------------------+
2 rows in set (0.00 sec)
mysql>
OBSERVE:
mysql> SELECT CustomerID, FirstName, LastName, EmailAddress FROM Customers;
This time, MySQL o nly retrieves the co lumns yo u specified (Cust o m e rID, First Nam e , Last Nam e , and
Em ailAddre ss).
What if yo u o nly want to retrieve custo mers fro m Illino is? The SELECT statement can include a WHERE clause that
enables yo u to filter yo ur ro ws.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT CustomerID, FirstName, LastName, EmailAddress, State FROM Customers
-> WHERE State='IL';
+------------+-----------+----------+------------------+-------+
| CustomerID | FirstName | LastName | EmailAddress
| State |
+------------+-----------+----------+------------------+-------+
|
21 | John
| Smith
| [email protected] | IL
|
+------------+-----------+----------+------------------+-------+
1 row in set (0.01 sec)
mysql>
OBSERVE:
mysql> SELECT CustomerID, FirstName, LastName, EmailAddress, State FROM Customers
-> WHERE State='IL';
The results o nly include ro ws WHERE the St at e is e qual t o 'IL.'
This time Ms. Adams isn't included because we didn't specify a state fo r her. We kno w Chicago is in Illino is, but SQL
do esn't!
What if yo u o nly want to see yo ur custo mers fro m Illino is who have a gmail address? Remember that email
addresses at gmail end with gmail.co m.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT CustomerID, FirstName, LastName, EmailAddress, State FROM Customers
-> WHERE State='IL' AND EmailAddress LIKE '%gmail.com';
Empty set (0.00 sec)
mysql>
We do n't have any custo mers in Illino is with gmail acco unts, so no ro ws were returned. This query sho ws so mething
new.
OBSERVE:
mysql> SELECT CustomerID, FirstName, LastName, EmailAddress, State FROM Customers
WHERE State='IL' AND EmailAddress LIKE '%gmail.com';
AND is a co njunctio n that co nnects the two queries, to return o nly custo mers in Illino is AND with email addresses at
gmail.
Note
Yo u can also use OR in the WHERE clause. Other co mpariso ns yo u can do include IS NULL, IS NOT
NULL, != (no t equals), and < o r >.
LIKE do esn't do an exact match o n a co lumn. The special character % means "anything" to SQL, so Em ailAddre ss
LIKE '% gm ail.co m ' co uld be translated to English as "EmailAddress that ends with gmail.co m."
Update
No w yo u have data in yo ur tables, but at so me po int this data might change. Suppo se, fo r example, that yo ur custo mer
Jo hn Smith tells yo u that his email address has changed. It used to be 'jo hn@ho tmail.co m,' but no w it's
'jo [email protected] m.' Let's UPDAT E his ro w in the Custo mers table.
In the fo llo wing example, be sure to change the Custo merID fro m id to whatever Custo merID yo ur individual Jo hn
Smith was given.
Type the fo llo wing at the MySQL pro mpt:
mysql> UPDATE Customers
-> SET EmailAddress='[email protected]'
-> WHERE CustomerID=id;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql>
OBSERVE:
mysql> UPDATE Customers
-> SET EmailAddress='[email protected]'
-> WHERE CustomerID=id;
UPDATE statements have two impo rtant parts: the co lum n updat e s, and the WHERE clause. The co lum n updat e s
specify the new values fo r the given co lumns. The WHERE clause tells the database which ro ws in the database yo u
want to update.
Let's check to make sure the data was updated.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT CustomerID, FirstName, LastName, EmailAddress FROM Customers;
+------------+-----------+----------+------------------+
| CustomerID | FirstName | LastName | EmailAddress
|
+------------+-----------+----------+------------------+
|
21 | John
| Smith
| [email protected]
|
|
31 | Jane
| Adams
| [email protected] |
+------------+-----------+----------+------------------+
2 rows in set (0.00 sec)
mysql>
Yes, it has been updated.
The WHERE clause is no t required, but if yo u do n't pro vide o ne, every ro w in the database will be updated. If yo u want
to update o nly o ne ro w, yo u'll need to specify eno ugh co nditio ns in yo ur WHERE clause to limit yo ur change to that
o ne ro w.
T ip
If yo u're no t sure ho w to limit yo ur UPDATE statement co rrectly, write it as a SELECT statement first. If yo ur
SELECT statement returns the intended ro ws, chances are yo ur UPDATE statement will o nly change the
intended ro ws as well.
Yo u can change multiple co lumns as well. Befo re we do , let's write a SELECT statement to make sure o ur WHERE
clause is co rrect. Once again, be sure to change the Custo merID fro m id to whatever Custo merID yo ur individual Jo hn
Smith was given.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT *
-> FROM Customers
-> WHERE CustomerID=21;
+------------+-----------+----------+----------------+--------------+---------+-------+
------------+----------------+---------------------+
| CustomerID | FirstName | LastName | AddressLine1
| AddressLine2 | City
| State |
PostalCode | EmailAddress
| DateAdded
|
+------------+-----------+----------+----------------+--------------+---------+-------+
------------+----------------+---------------------+
|
21 | John
| Smith
| 123 4th Street | NULL
| Chicago | IL
|
60606
| [email protected] | 2007-09-19 20:36:38 |
+------------+-----------+----------+----------------+--------------+---------+-------+
------------+----------------+---------------------+
1 row in set (0.00 sec)
mysql>
One ro w was returned, with the co rrect custo mer.
No w that we're co nfident that we've written the co rrect WHERE clause, let's rewrite the SELECT statement as an
UPDATE statement.
Type the fo llo wing at the MySQL pro mpt:
mysql> UPDATE Customers
-> SET EmailAddress='[email protected]', City='Evanston'
-> WHERE CustomerID=id;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql>
Yo ur results sho w that o ne ro w was matched, and o ne ro w was changed.
If yo u need additio nal co nfirmatio n that the change to o k place, write ano ther SELECT query to check fo r yo urself!
Delete
No w that yo u have data in yo ur tables and have altered that data, ho w do yo u get rid o f it? Perhaps yo ur custo mer Ms.
Adams wants to be remo ved fro m yo ur system. o f 31. Do uble-check her Custo merID with SELECT and replace id in
the co mmand with her Custo merID fro m yo ur system.
Type the fo llo wing at the MySQL pro mpt:
mysql> DELETE FROM Customers
-> WHERE CustomerID=id;
Query OK, 1 row affected (0.00 sec)
mysql>
Is the data really go ne? Let's find o ut.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT CustomerID, FirstName, LastName, EmailAddress FROM Customers;
+------------+-----------+----------+---------------------+
| CustomerID | FirstName | LastName | EmailAddress
|
+------------+-----------+----------+---------------------+
|
21 | John
| Smith
| [email protected] |
+------------+-----------+----------+---------------------+
1 row in set (0.00 sec)
mysql>
Yep, it's go ne!
Take a mo ment to reflect o n the wo rk yo u've just do ne. Yo u added data to yo ur tables, retrieved it, filtered it, updated so me
ro ws, and deleted so me o ld reco rds. In the next lab yo u'll learn ho w to keep yo ur data secure and co nsistent thro ugh the use o f
transactio ns. See yo u there!
Copyright © 1998-2014 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
Transactions
Making Sure Your Commands Behave
Welco me back! In the last lesso n yo u learned ho w to sto re and retrieve data fro m yo ur database. Yo u also learned to
create tables in yo ur database to track custo mers, invento ry, and sales. In this lesso n we'll discuss the steps yo u can
take to make sure the data in yo ur database is always co rrect and up-to -date, even if many peo ple are wo rking with the
data at the same time.
Fo r this lesso n, yo u'll need to have two Unix terminals o pen at the same time. The two sessio ns will be o pen in
different tabs. To tell them apart, use the po sitio n o f the tabs, and the tabs' names ("Terminal1" and "Terminal2," o r
similar). Lo g into MySQL and be sure to set the 'traditio nal' mo de in each Unix terminal! When yo u switch to a new
terminal yo u will need to click in it befo re yo u can type in it.
Let's go back to o ur bo o ksto re. When a bo o k is so ld, several things need to happen:
1. Check pro duct invento ry to make sure the item is in sto ck.
2. Create an o rder.
3. Add the pro duct to the o rder item table.
4. Update invento ry to reflect the new quantity in sto ck.
5. Check the invento ry level again so the sales staff is alerted when sto ck gets lo w.
But what happens if two peo ple try to purchase the same bo o k at the same time? Who gets the bo o k? What happens if
yo u add invento ry to the database when so meo ne purchases a bo o k?
In the database wo rld, transactions are used to gro up related co mmands so all co mmands execute o r all co mmands
do no t execute. There is no in-between.
ACID
Databases must maintain fo ur pro perties: At o m icit y, Co nsist e ncy, Iso lat io n, and Durabilit y. To help
yo u remember this, use the acro nym ACID.
At o m icit y: Transactio ns canno t be divided o r split. Transactio ns either succeed o r fail as a single unit.
Co nsist e ncy: Databases o nly sto re data that is co nsistent with the rules defined fo r sto ring data. Fo r
instance, if an invento ry table isn't allo wed to have negative quantities, then no ro ws will be allo wed to have
negative quantities.
Iso lat io n: Transactio ns are independent o f the o utside wo rld. No o utside change can cause an unexpected
change within o ur transactio n. When making a sale, no o ther sales can change the quantity in invento ry until
this sale has been co mpleted.
Durabilit y: Once a database transactio n co mmits, the data is secure in the database.
All databases handle Ato micity, Co nsistency, and Durability internally and auto matically. The Iso latio n
pro perty depends o n the user—it's usually set to a secure level by default, but depending o n yo ur
requirements, yo u can raise o r lo wer it.
Note
MySQL is a unique database because it do esn't always suppo rt ACID pro perties. Depending o n
the versio n o f MySQL being used and the way yo ur database is set up, transactio ns may no t
secure yo ur data. To ensure MySQL will secure yo ur data, always use the Inno DB engine.
T ransaction Isolation Levels
There are fo ur primary transactio n iso latio n levels suppo rted by databases.
The first is called read uncommitted. It is the fastest, but least safe level. Transactio ns run with this iso latio n level are
no t guaranteed to o ccur independently o f o ther transactio ns. This means that o ne sale transactio n is allo wed to "dirty
read" the results o f o ther inco mplete sale transactio ns. (A "dirty read" is when the database gives yo u data that has no t
yet been co mmitted to disk.) This iso latio n level is o nly used in certain circumstances where yo u do n't necessarily
care if the data is inco rrect.
The next transactio n level, called read committed, is slightly safer than read unco mmitted. Dirty reads are no t po ssible
under this iso latio n level. If yo u run a query at the beginning o f yo ur transactio n, and run the same query at the end o f
the transactio n, the results wo n't be the same if ano ther transactio n begins and co mmits in the middle o f yo ur
transactio n.
Repeatable read is usually the default transactio n iso latio n level. In this iso latio n level, yo u canno t get dirty reads, and
no o ther transactio ns can change ro ws during yo ur transactio n.
The highest level o f safety, and the slo west transactio n level, is serializable. Under this iso latio n level, each 'read' and
'write' to the database o ccurs in sequence. This iso latio n level can cause perfo rmance issues, since yo ur transactio n
might have to wait fo r so meo ne else's transactio n to co mplete.
Using T ransactions
Befo re yo u query the database, yo u sho uld specify yo ur transactio n iso latio n level. In MySQL this is do ne via the SET
co mmand.
Be sure yo u are in the first o f yo ur two Unix terminals befo re executing these first co mmands.
Type the fo llo wing at the MySQL pro mpt in the first Unix terminal:
mysql> SET transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)
mysql>
This co mmand do esn't return any ro ws.
Mo st database servers allo w yo u to pro cess many SQL statements to gether as a single batch. In MySQL yo u begin a
batch with the ST ART T RANSACT ION statement, and end it with COMMIT , o r undo it with ROLLBACK. As always,
yo u must end each individual SQL statement with a semico lo n (;).
Let's create a simple transactio n.
Type the fo llo wing at the MySQL pro mpt in first Unix terminal:
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT LastName FROM Customers;
+----------+
| LastName |
+----------+
| Smith
|
+----------+
1 row in set (0.01 sec)
mysql> COMMIT;
Query OK, 0 rows affected (0.01 sec)
mysql>
Note
It's o kay if the results returned fro m yo ur query are different fro m this example.
OBSERVE:
mysql> START TRANSACTION;
mysql> SELECT LastName FROM Customers;
mysql> COMMIT;
First, yo u ST ART T RANSACT ION. In this batch yo u are o nly executing o ne statement, to return the co unt fro m the
Cust o m e rs table. Ho wever, yo u co uld do additio nal wo rk in yo ur batch by adding mo re SQL statements. Finally, yo u
end yo ur batch with COMMIT ;.
Of co urse, this example o nly selected data fro m the database—it didn't update o r add data. What happens when yo u
use a transactio n with an INSERT statement? To find o ut, yo u'll use bo th Unix terminals.
Type the fo llo wing at the MySQL pro mpt in the first Unix terminal:
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO Customers
-> (FirstName, LastName, AddressLine1, City, State, PostalCode, DateAdded, EmailAdd
ress)
-> VALUES ('John', 'Doe', '123 4th Street', 'Chicago', 'IL', '60606', NOW(), 'johnd
[email protected]');
Query OK, 1 row affected (0.00 sec)
mysql>
Next, o pen a seco nd Unix terminal sessio n, start mysql, and set sql_mo de='traditio nal'.
Type the fo llo wing at the MySQL pro mpt in the seco nd Unix terminal:
mysql> SELECT FirstName, LastName FROM Customers;
+-----------+----------+
| FirstName | LastName |
+-----------+----------+
| John
| Smith
|
+-----------+----------+
1 row in set (0.00 sec)
mysql>
Yo ur table may have mo re ro ws than the table sho wn abo ve, but yo u sho uld see that J o hn Do e is no t there.
If yo ur transactio n iso latio n level was set co rrectly, yo u won't see any ro ws fo r Jo hn Do e. This is the co rrect result,
since we set the re ad co m m it t e d iso latio n level befo re we started the batch.
Note
If yo u do see Jo hn Do e, yo u pro bably missed the step where yo u entered SET t ransact io n iso lat io n
le ve l re ad co m m it t e d; o n the first terminal. Switch back to the first terminal, delete Jo hn Do e, and try
again fro m the beginning.
No w switch back to the first Unix terminal, where yo u typed in the INSERT statement.
Type the fo llo wing at the MySQL pro mpt in the first Unix terminal:
mysql> COMMIT;
Query OK, 0 rows affected (0.00 sec)
mysql>
Switch back to the seco nd Unix terminal, where yo u typed in the SELECT statement and run it again (yo u can use the
up arro w o n yo ur keybo ard to repeat the co mmand).
Type the fo llo wing at the MySQL pro mpt in the seco nd Unix terminal:
mysql> SELECT FirstName, LastName FROM Customers;
+-----------+----------+
| FirstName | LastName |
+-----------+----------+
| John
| Smith
|
| John
| Doe
|
+-----------+----------+
2 rows in set (0.00 sec)
mysql>
There is o ne o ther way to end yo ur batch—yo u can undo yo ur changes with the ROLLBACK statement.
Make sure yo u are in the first Unix terminal.
Type the fo llo wing at the MySQL pro mpt in the first Unix terminal:
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO Customers
-> (FirstName, LastName, AddressLine1, City, State, PostalCode, DateAdded, EmailAdd
ress)
-> VALUES ('Becky', 'Stein', '123 4th Street', 'Chicago', 'IL', '60606', NOW(), 'bs
[email protected]');
Query OK, 1 row affected (0.01 sec)
mysql> ROLLBACK;
Query OK, 0 rows affected (0.00 sec)
mysql>
No w, switch to the seco nd Unix terminal and repeat the SELECT:
Type the fo llo wing at the MySQL pro mpt in the seco nd Unix terminal:
mysql> SELECT FirstName, LastName FROM Customers;
+-----------+----------+
| FirstName | LastName |
+-----------+----------+
| John
| Smith
|
| John
| Doe
|
+-----------+----------+
2 rows in set (0.00 sec)
mysql>
Yo ur o utput may be different fro m the abo ve, but since yo u rolled back the transactio n, yo u do n't see any ro ws fo r
Becky Stein.
Committing and rolling back
Yo u might be asking, "so when do I use COMMIT and ROLLBACK?"
Transactio ns are usually used in applicatio ns o r in sto red pro cedures. Yo ur applicatio n will begin a
transactio n, then execute a query. If that query was successful, the applicatio n executes the next query. If any
query fails, the transactio n is ro lled back. If all queries succeed, the transactio n is co mmitted.
Using transactio ns fo r this means yo ur applicatio n do esn't have to try to undo any database wo rk if there is a
pro blem. The database do es the hard wo rk fo r yo u!
Yo u've learned a very po werful way to make sure yo ur data stays secure. In the next lesso n yo u'll learn ho w to co mbine data
fro m all o f yo ur tables in po werful and meaningful ways. Se e yo u t he n!
Copyright © 1998-2014 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
Joins
Combining T ables with a Join
In this lesso n, yo u'll learn ho w to co mbine data fro m many tables into a single query.
Wo uldn't it be nice to be able to write a query that wo uld allo w yo u to see the current invento ry o f the bo o k sto re? Until
no w the o nly way yo u had to find this info rmatio n was by writing two queries: o ne to list the pro ducts in the sto re, and
ano ther to list the quantities in the sto re.
Befo re we begin this lesso n, let's clear the pro ducts and invento ry table and start fresh. We haven't "o fficially" added
any reco rds to these tables, but if yo u've added any, yo u can delete them using the DELET E keywo rd yo u learned
abo ut earlier.
Type the fo llo wing at the MySQL pro mpt:
mysql> DELETE FROM Inventory;
Query OK, 15 rows affected (0.07 sec)
mysql> DELETE FROM Products;
Query OK, 15 rows affected (0.00 sec)
No w that o ur tables are empty, let's create so me new data. O'Reilly has a very nice bo o k catalo g, so let's bo rro w a few
descriptio ns fro m that. We'll do wnlo ad an SQL file to save us so me time. This text file co ntains many INSERT
statements that we'll submit to the database server, instead o f typing each and every INSERT co mmand o urselves.
First, get back to the Unix pro mpt.
Type the fo llo wing at the MySQL pro mpt:
mysql> exit;
Bye
cold1:~$
Next, we'll grab the file fro m O'Reilly's servers using the curl co mmand.
Type the fo llo wing at the Unix pro mpt:
cold1:~$ curl -L https://courses.oreillyschool.com/dba1/downloads/products.sql > produc
ts.sql
% Total
% Received % Xferd Average Speed
Time
Time
Time Current
Dload Upload
Total
Spent
Left Speed
100 9520 100 9520
0
0 53816
0 --:--:-- --:--:-- --:--:-- 178k
cold1:~$
Once that file has do wnlo aded, we'll use the m ysql co mmand to impo rt the pro ducts (replace username with yo ur
username). If the data is impo rted successfully, yo u'll see no results.
Type the fo llo wing at the Unix pro mpt:
cold1:~$ mysql -h sql -p -u username username < products.sql
Enter password:
cold1:~$
Next, insert the data fo r invento ries. Lo g back into MySQL, and be sure to set yo ur sql_m o de !
Type the fo llo wing at the MySQL pro mpt:
mysql> INSERT INTO Inventory values ('artofsql', 52);
Query OK, 1 row affected (0.01 sec)
mysql> INSERT INTO Inventory values ('databaseid', 0);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO Inventory values ('mysqlspp', 5);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO Inventory values ('sqlhks', 32);
Query OK, 1 row affected (0.01 sec)
mysql> INSERT INTO Inventory values ('sqltuning', 105);
Query OK, 1 row affected (0.01 sec)
mysql>
To co mbine two tables in o ne query, yo u use a J OIN. A jo in between the Pro ducts table and Invento ry table will match
every ro w in Pro ducts with every ro w in Invento ry. Let's try it o ut!
INTERACTIVE SESSION:
mysql> SELECT * FROM Products JOIN Inventory;
+-------------+------------------------------------+-----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------+-----------------+
| ProductCode | Title
| Category
| Description
| Price | productcode | QuantityInSt
ock |
+-------------+------------------------------------+-----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------+-----------------+
| databaseid | Database in Depth
| Database Theory |This book sheds l
ight on the principles behind the relational model, which is fundamental to all databas
e-backed applications--and, consequently, most of the work that goes on in the computin
g world today. Database in Depth: The Relational Model for Practitioners goes beyond th
e hype and gets to the heart of how relational databases actually work. Ideal for exper
ienced database developers and designers, this concise guide gives you a clear view of
the technology--a view that's not influenced by any vendor or product. Featuring an ext
ensive set of exercises, it will help you: * understand why and how the relational mode
l is still directly relevant to modern database technology (and will remain so for the
foreseeable future) * see why and how the SQL standard is seriously deficient * use the
best current theoretical knowledge in the design of their databases and database appli
cations * make informed decisions in their daily database professional activities Datab
ase in Depth will appeal not only to database developers and designers, but also to a d
iverse field of professionals and academics, including database administrators (DBAs),
information modelers, database consultants, and more. Virtually everyone who deals with
relational databases should have at least a passing understanding of the fundamentals
of working with relational models. Author C.J. Date has been involved with the relation
al model from its earliest days. An exceptionally clear-thinking writer, Date lays out
principle and theory in a manner that is easily understood. Few others can speak as aut
horitatively the topic of relational databases as Date can. | 29.95 | artofsql
|
52 |
| sqlhks
| SQL Hacks
| SQL
|Whether you're ru
nning Access, MySQL, SQL Server, Oracle, or PostgreSQL, this book will help you push th
e limits of traditional SQL to squeeze data effectively from your database. The book of
fers 100 hacks -- unique tips and tools -- that bring you the knowledge of experts who
apply what they know in the real world to help you take full advantage of the expressiv
e power of SQL. You'll find practical techniques to address complex data manipulation p
roblems. Learn how to: * Wrangle data in the most efficient way possible * Aggregate an
d organize your data for meaningful and accurate reporting * Make the most of subquerie
s, joins, and unions * Stay on top of the performance of your queries and the server th
at runs them * Avoid common SQL security pitfalls, including the dreaded SQL injection
attack Let SQL Hacks serve as your toolbox for digging up and manipulating data. If you
love to tinker and optimize, SQL is the perfect technology and SQL Hacks is the must-h
ave book for you. | 29.99 | artofsql
|
52 |
| artofsql
| The Art of SQL
| Database Theory |For all the buzz
about trendy IT techniques, data processing is still at the core of our systems, especi
ally now that enterprises all over the world are confronted with exploding volumes of d
ata. Database performance has become a major headache, and most IT departments believe
that developers should provide simple SQL code to solve immediate problems and let DBAs
tune any "bad SQL" later. In The Art of SQL, author and SQL expert Stephane Faroult ar
gues that this "safe approach" only leads to disaster. His insightful book, named after
Art of War by Sun Tzu, contends that writing quick inefficient code is sweeping the di
rt under the rug. SQL code may run for 5 to 10 years, surviving several major releases
of the database management system and on several generations of hardware. The code must
be fast and sound from the start, and that requires a firm understanding of SQL and re
lational theory. The Art of SQL offers best practices that teach experienced SQL users
to focus on strategy rather than specifics. Faroult's approach takes a page from Sun Tz
u's classic treatise by viewing database design as a military campaign. You need knowle
dge, skills, and talent. Talent can't be taught, but every strategist from Sun Tzu to m
odern-day generals believed that it can be nurtured through the experience of others. T
hey passed on their experience acquired in the field through basic principles that serv
ed as guiding stars amid the sound and fury of battle. This is what Faroult does with S
QL. Like a successful battle plan, good architectural choices are based on contingencie
s. What if the volume of this or that table increases unexpectedly? What if, following
a merger, the number of users doubles? What if you want to keep several years of data o
nline? Faroult's way of looking at SQL performance may be unconventional and unique, bu
t he's deadly serious about writing good SQL and using SQL well. The Art of SQL is not
a cookbook, listing problems and giving recipes. The aim is to get you-and your manager
-to raise good questions. | 44.99 | artofsql
|
52 |
| sqltuning
| SQL Tuning
| Database Theory |A poorly performi
ng database application not only costs users time, but also has an impact on other appl
ications running on the same computer or the same network. SQL Tuning provides an essen
tial next step for SQL developers and database administrators who want to extend their
SQL tuning expertise and get the most from their database applications. There are two b
asic issues to focus on when tuning SQL: how to find and interpret the execution plan o
f an SQL statement and how to change SQL to get a specific alternate execution plan. SQ
L Tuning provides answers to these questions and addresses a third issue that's even mo
re important: how to find the optimal execution plan for the query to use. Author Dan T
ow outlines a timesaving method he's developed for finding the optimum execution plan-rapidly and systematically--regardless of the complexity of the SQL or the database pla
tform being used. You'll learn how to understand and control SQL execution plans and ho
w to diagram SQL queries to deduce the best execution plan for a query. Key chapters in
the book include exercises to reinforce the concepts you've learned. SQL Tuning conclu
des by addressing special concerns and unique solutions to "unsolvable problems." Wheth
er you are a programmer who develops SQL-based applications or a database administrator
or other who troubleshoots poorly tuned applications, SQL Tuning will arm you with a r
eliable and deterministic method for tuning your SQL queries to gain optimal performanc
e. | 39.95 | artofsql
|
52 |
| mysqlspp
| MySQL Stored Procedure Programming | MySQL
|The implementatio
n of stored procedures in MySQL 5.0 a huge milestone -- one that is expected to lead to
widespread enterprise adoption of the already extremely popular MySQL database. If you
are serious about building the web-based database applications of the future, you need
to get up to speed quickly on how stored procedures work -- and how to build them the
right way. This book, destined to be the bible of stored procedure development, is a re
source that no real MySQL programmer can afford to do without. In the decade since MySQ
L burst on the scene, it has become the dominant open source database, with capabilitie
s and performance rivaling those of commercial RDBMS offerings like Oracle and SQL Serv
er. Along with Linux and PHP, MySQL is at the heart of millions of applications. And no
w, with support for stored procedures, functions, and triggers in MySQL 5.0, MySQL offe
rs the programming power needed for true enterprise use. MySQL's new procedural languag
e has a straightforward syntax, making it easy to write simple programs. But it's not s
o easy to write secure, easily maintained, high-performance, and bug-free programs. Few
in the MySQL world have substantial experience yet with stored procedures, but Guy Har
rison and Steven Feuerstein have decades of combined expertise. In MySQL Stored Procedu
re Programming, they put that hard-won experience to good use. Packed with code example
s and covering everything from language basics to application building to advanced tuni
ng and best practices, this highly readable book is the one-stop guide to MySQL develop
ment. It consists of four major sections: * MySQL stored programming fundamentals -- tu
torial, basic statements, SQL in stored programs, and error handling * Building MySQL s
tored programs -- transaction handling, built-in functions, stored functions, and trigg
ers * MySQL stored programs in applications -- using stored programs with PHP, Java, Pe
rl, Python, and .NET (C# and VB.NET) * Optimizing MySQL stored programs -- security, ba
sic and advanced SQL tuning, optimizing stored program code, and programming best pract
ices A companion web site contains many thousands of lines of code, that you can put to
use immediately. Guy Harrison is Chief Architect of Database Solutions at Quest Softwa
re and a frequent speaker and writer on MySQL topics. Steven Feuerstein is the author o
f Oracle PL/SQL Programming, the classic reference for Oracle stored programming for mo
re than ten years. Both have decades of experience as database developers, and between
them they have authored a dozen books. | 44.99 | artofsql
|
52 |
| databaseid | Database in Depth
| Database Theory |This book sheds l
ight on the principles behind the relational model, which is fundamental to all databas
e-backed applications--and, consequently, most of the work that goes on in the computin
g world today. Database in Depth: The Relational Model for Practitioners goes beyond th
e hype and gets to the heart of how relational databases actually work. Ideal for exper
ienced database developers and designers, this concise guide gives you a clear view of
the technology--a view that's not influenced by any vendor or product. Featuring an ext
ensive set of exercises, it will help you: * understand why and how the relational mode
l is still directly relevant to modern database technology (and will remain so for the
foreseeable future) * see why and how the SQL standard is seriously deficient * use the
best current theoretical knowledge in the design of their databases and database appli
cations * make informed decisions in their daily database professional activities Datab
ase in Depth will appeal not only to database developers and designers, but also to a d
iverse field of professionals and academics, including database administrators (DBAs),
information modelers, database consultants, and more. Virtually everyone who deals with
relational databases should have at least a passing understanding of the fundamentals
of working with relational models. Author C.J. Date has been involved with the relation
al model from its earliest days. An exceptionally clear-thinking writer, Date lays out
principle and theory in a manner that is easily understood. Few others can speak as aut
horitatively the topic of relational databases as Date can. | 29.95 | databaseid |
0 |
| sqlhks
| SQL Hacks
| SQL
|Whether you're ru
nning Access, MySQL, SQL Server, Oracle, or PostgreSQL, this book will help you push th
e limits of traditional SQL to squeeze data effectively from your database. The book of
fers 100 hacks -- unique tips and tools -- that bring you the knowledge of experts who
apply what they know in the real world to help you take full advantage of the expressiv
e power of SQL. You'll find practical techniques to address complex data manipulation p
roblems. Learn how to: * Wrangle data in the most efficient way possible * Aggregate an
d organize your data for meaningful and accurate reporting * Make the most of subquerie
s, joins, and unions * Stay on top of the performance of your queries and the server th
at runs them * Avoid common SQL security pitfalls, including the dreaded SQL injection
attack Let SQL Hacks serve as your toolbox for digging up and manipulating data. If you
love to tinker and optimize, SQL is the perfect technology and SQL Hacks is the must-h
ave book for you. | 29.99 | databaseid |
0 |
| artofsql
| The Art of SQL
| Database Theory |For all the buzz
about trendy IT techniques, data processing is still at the core of our systems, especi
ally now that enterprises all over the world are confronted with exploding volumes of d
ata. Database performance has become a major headache, and most IT departments believe
that developers should provide simple SQL code to solve immediate problems and let DBAs
tune any "bad SQL" later. In The Art of SQL, author and SQL expert Stephane Faroult ar
gues that this "safe approach" only leads to disaster. His insightful book, named after
Art of War by Sun Tzu, contends that writing quick inefficient code is sweeping the di
rt under the rug. SQL code may run for 5 to 10 years, surviving several major releases
of the database management system and on several generations of hardware. The code must
be fast and sound from the start, and that requires a firm understanding of SQL and re
lational theory. The Art of SQL offers best practices that teach experienced SQL users
to focus on strategy rather than specifics. Faroult's approach takes a page from Sun Tz
u's classic treatise by viewing database design as a military campaign. You need knowle
dge, skills, and talent. Talent can't be taught, but every strategist from Sun Tzu to m
odern-day generals believed that it can be nurtured through the experience of others. T
hey passed on their experience acquired in the field through basic principles that serv
ed as guiding stars amid the sound and fury of battle. This is what Faroult does with S
QL. Like a successful battle plan, good architectural choices are based on contingencie
s. What if the volume of this or that table increases unexpectedly? What if, following
a merger, the number of users doubles? What if you want to keep several years of data o
nline? Faroult's way of looking at SQL performance may be unconventional and unique, bu
t he's deadly serious about writing good SQL and using SQL well. The Art of SQL is not
a cookbook, listing problems and giving recipes. The aim is to get you-and your manager
-to raise good questions. | 44.99 | databaseid |
0 |
| sqltuning
| SQL Tuning
| Database Theory |A poorly performi
ng database application not only costs users time, but also has an impact on other appl
ications running on the same computer or the same network. SQL Tuning provides an essen
tial next step for SQL developers and database administrators who want to extend their
SQL tuning expertise and get the most from their database applications. There are two b
asic issues to focus on when tuning SQL: how to find and interpret the execution plan o
f an SQL statement and how to change SQL to get a specific alternate execution plan. SQ
L Tuning provides answers to these questions and addresses a third issue that's even mo
re important: how to find the optimal execution plan for the query to use. Author Dan T
ow outlines a timesaving method he's developed for finding the optimum execution plan-rapidly and systematically--regardless of the complexity of the SQL or the database pla
tform being used. You'll learn how to understand and control SQL execution plans and ho
w to diagram SQL queries to deduce the best execution plan for a query. Key chapters in
the book include exercises to reinforce the concepts you've learned. SQL Tuning conclu
des by addressing special concerns and unique solutions to "unsolvable problems." Wheth
er you are a programmer who develops SQL-based applications or a database administrator
or other who troubleshoots poorly tuned applications, SQL Tuning will arm you with a r
eliable and deterministic method for tuning your SQL queries to gain optimal performanc
e. | 39.95 | databaseid |
0 |
| mysqlspp
| MySQL Stored Procedure Programming | MySQL
|The implementatio
n of stored procedures in MySQL 5.0 a huge milestone -- one that is expected to lead to
widespread enterprise adoption of the already extremely popular MySQL database. If you
are serious about building the web-based database applications of the future, you need
to get up to speed quickly on how stored procedures work -- and how to build them the
right way. This book, destined to be the bible of stored procedure development, is a re
source that no real MySQL programmer can afford to do without. In the decade since MySQ
L burst on the scene, it has become the dominant open source database, with capabilitie
s and performance rivaling those of commercial RDBMS offerings like Oracle and SQL Serv
er. Along with Linux and PHP, MySQL is at the heart of millions of applications. And no
w, with support for stored procedures, functions, and triggers in MySQL 5.0, MySQL offe
rs the programming power needed for true enterprise use. MySQL's new procedural languag
e has a straightforward syntax, making it easy to write simple programs. But it's not s
o easy to write secure, easily maintained, high-performance, and bug-free programs. Few
in the MySQL world have substantial experience yet with stored procedures, but Guy Har
rison and Steven Feuerstein have decades of combined expertise. In MySQL Stored Procedu
re Programming, they put that hard-won experience to good use. Packed with code example
s and covering everything from language basics to application building to advanced tuni
ng and best practices, this highly readable book is the one-stop guide to MySQL develop
ment. It consists of four major sections: * MySQL stored programming fundamentals -- tu
torial, basic statements, SQL in stored programs, and error handling * Building MySQL s
tored programs -- transaction handling, built-in functions, stored functions, and trigg
ers * MySQL stored programs in applications -- using stored programs with PHP, Java, Pe
rl, Python, and .NET (C# and VB.NET) * Optimizing MySQL stored programs -- security, ba
sic and advanced SQL tuning, optimizing stored program code, and programming best pract
ices A companion web site contains many thousands of lines of code, that you can put to
use immediately. Guy Harrison is Chief Architect of Database Solutions at Quest Softwa
re and a frequent speaker and writer on MySQL topics. Steven Feuerstein is the author o
f Oracle PL/SQL Programming, the classic reference for Oracle stored programming for mo
re than ten years. Both have decades of experience as database developers, and between
them they have authored a dozen books. | 44.99 | databaseid |
0 |
| databaseid | Database in Depth
| Database Theory |This book sheds l
ight on the principles behind the relational model, which is fundamental to all databas
e-backed applications--and, consequently, most of the work that goes on in the computin
g world today. Database in Depth: The Relational Model for Practitioners goes beyond th
e hype and gets to the heart of how relational databases actually work. Ideal for exper
ienced database developers and designers, this concise guide gives you a clear view of
the technology--a view that's not influenced by any vendor or product. Featuring an ext
ensive set of exercises, it will help you: * understand why and how the relational mode
l is still directly relevant to modern database technology (and will remain so for the
foreseeable future) * see why and how the SQL standard is seriously deficient * use the
best current theoretical knowledge in the design of their databases and database appli
cations * make informed decisions in their daily database professional activities Datab
ase in Depth will appeal not only to database developers and designers, but also to a d
iverse field of professionals and academics, including database administrators (DBAs),
information modelers, database consultants, and more. Virtually everyone who deals with
relational databases should have at least a passing understanding of the fundamentals
of working with relational models. Author C.J. Date has been involved with the relation
al model from its earliest days. An exceptionally clear-thinking writer, Date lays out
principle and theory in a manner that is easily understood. Few others can speak as aut
horitatively the topic of relational databases as Date can. | 29.95 | mysqlspp
|
5 |
| sqlhks
| SQL Hacks
| SQL
|Whether you're ru
nning Access, MySQL, SQL Server, Oracle, or PostgreSQL, this book will help you push th
e limits of traditional SQL to squeeze data effectively from your database. The book of
fers 100 hacks -- unique tips and tools -- that bring you the knowledge of experts who
apply what they know in the real world to help you take full advantage of the expressiv
e power of SQL. You'll find practical techniques to address complex data manipulation p
roblems. Learn how to: * Wrangle data in the most efficient way possible * Aggregate an
d organize your data for meaningful and accurate reporting * Make the most of subquerie
s, joins, and unions * Stay on top of the performance of your queries and the server th
at runs them * Avoid common SQL security pitfalls, including the dreaded SQL injection
attack Let SQL Hacks serve as your toolbox for digging up and manipulating data. If you
love to tinker and optimize, SQL is the perfect technology and SQL Hacks is the must-h
ave book for you. | 29.99 | mysqlspp
|
5 |
| artofsql
| The Art of SQL
| Database Theory |For all the buzz
about trendy IT techniques, data processing is still at the core of our systems, especi
ally now that enterprises all over the world are confronted with exploding volumes of d
ata. Database performance has become a major headache, and most IT departments believe
that developers should provide simple SQL code to solve immediate problems and let DBAs
tune any "bad SQL" later. In The Art of SQL, author and SQL expert Stephane Faroult ar
gues that this "safe approach" only leads to disaster. His insightful book, named after
Art of War by Sun Tzu, contends that writing quick inefficient code is sweeping the di
rt under the rug. SQL code may run for 5 to 10 years, surviving several major releases
of the database management system and on several generations of hardware. The code must
be fast and sound from the start, and that requires a firm understanding of SQL and re
lational theory. The Art of SQL offers best practices that teach experienced SQL users
to focus on strategy rather than specifics. Faroult's approach takes a page from Sun Tz
u's classic treatise by viewing database design as a military campaign. You need knowle
dge, skills, and talent. Talent can't be taught, but every strategist from Sun Tzu to m
odern-day generals believed that it can be nurtured through the experience of others. T
hey passed on their experience acquired in the field through basic principles that serv
ed as guiding stars amid the sound and fury of battle. This is what Faroult does with S
QL. Like a successful battle plan, good architectural choices are based on contingencie
s. What if the volume of this or that table increases unexpectedly? What if, following
a merger, the number of users doubles? What if you want to keep several years of data o
nline? Faroult's way of looking at SQL performance may be unconventional and unique, bu
t he's deadly serious about writing good SQL and using SQL well. The Art of SQL is not
a cookbook, listing problems and giving recipes. The aim is to get you-and your manager
-to raise good questions. | 44.99 | mysqlspp
|
5 |
| sqltuning
| SQL Tuning
| Database Theory |A poorly performi
ng database application not only costs users time, but also has an impact on other appl
ications running on the same computer or the same network. SQL Tuning provides an essen
tial next step for SQL developers and database administrators who want to extend their
SQL tuning expertise and get the most from their database applications. There are two b
asic issues to focus on when tuning SQL: how to find and interpret the execution plan o
f an SQL statement and how to change SQL to get a specific alternate execution plan. SQ
L Tuning provides answers to these questions and addresses a third issue that's even mo
re important: how to find the optimal execution plan for the query to use. Author Dan T
ow outlines a timesaving method he's developed for finding the optimum execution plan-rapidly and systematically--regardless of the complexity of the SQL or the database pla
tform being used. You'll learn how to understand and control SQL execution plans and ho
w to diagram SQL queries to deduce the best execution plan for a query. Key chapters in
the book include exercises to reinforce the concepts you've learned. SQL Tuning conclu
des by addressing special concerns and unique solutions to "unsolvable problems." Wheth
er you are a programmer who develops SQL-based applications or a database administrator
or other who troubleshoots poorly tuned applications, SQL Tuning will arm you with a r
eliable and deterministic method for tuning your SQL queries to gain optimal performanc
e. | 39.95 | mysqlspp
|
5 |
| mysqlspp
| MySQL Stored Procedure Programming | MySQL
|The implementatio
n of stored procedures in MySQL 5.0 a huge milestone -- one that is expected to lead to
widespread enterprise adoption of the already extremely popular MySQL database. If you
are serious about building the web-based database applications of the future, you need
to get up to speed quickly on how stored procedures work -- and how to build them the
right way. This book, destined to be the bible of stored procedure development, is a re
source that no real MySQL programmer can afford to do without. In the decade since MySQ
L burst on the scene, it has become the dominant open source database, with capabilitie
s and performance rivaling those of commercial RDBMS offerings like Oracle and SQL Serv
er. Along with Linux and PHP, MySQL is at the heart of millions of applications. And no
w, with support for stored procedures, functions, and triggers in MySQL 5.0, MySQL offe
rs the programming power needed for true enterprise use. MySQL's new procedural languag
e has a straightforward syntax, making it easy to write simple programs. But it's not s
o easy to write secure, easily maintained, high-performance, and bug-free programs. Few
in the MySQL world have substantial experience yet with stored procedures, but Guy Har
rison and Steven Feuerstein have decades of combined expertise. In MySQL Stored Procedu
re Programming, they put that hard-won experience to good use. Packed with code example
s and covering everything from language basics to application building to advanced tuni
ng and best practices, this highly readable book is the one-stop guide to MySQL develop
ment. It consists of four major sections: * MySQL stored programming fundamentals -- tu
torial, basic statements, SQL in stored programs, and error handling * Building MySQL s
tored programs -- transaction handling, built-in functions, stored functions, and trigg
ers * MySQL stored programs in applications -- using stored programs with PHP, Java, Pe
rl, Python, and .NET (C# and VB.NET) * Optimizing MySQL stored programs -- security, ba
sic and advanced SQL tuning, optimizing stored program code, and programming best pract
ices A companion web site contains many thousands of lines of code, that you can put to
use immediately. Guy Harrison is Chief Architect of Database Solutions at Quest Softwa
re and a frequent speaker and writer on MySQL topics. Steven Feuerstein is the author o
f Oracle PL/SQL Programming, the classic reference for Oracle stored programming for mo
re than ten years. Both have decades of experience as database developers, and between
them they have authored a dozen books. | 44.99 | mysqlspp
|
5 |
| databaseid | Database in Depth
| Database Theory |This book sheds l
ight on the principles behind the relational model, which is fundamental to all databas
e-backed applications--and, consequently, most of the work that goes on in the computin
g world today. Database in Depth: The Relational Model for Practitioners goes beyond th
e hype and gets to the heart of how relational databases actually work. Ideal for exper
ienced database developers and designers, this concise guide gives you a clear view of
the technology--a view that's not influenced by any vendor or product. Featuring an ext
ensive set of exercises, it will help you: * understand why and how the relational mode
l is still directly relevant to modern database technology (and will remain so for the
foreseeable future) * see why and how the SQL standard is seriously deficient * use the
best current theoretical knowledge in the design of their databases and database appli
cations * make informed decisions in their daily database professional activities Datab
ase in Depth will appeal not only to database developers and designers, but also to a d
iverse field of professionals and academics, including database administrators (DBAs),
information modelers, database consultants, and more. Virtually everyone who deals with
relational databases should have at least a passing understanding of the fundamentals
of working with relational models. Author C.J. Date has been involved with the relation
al model from its earliest days. An exceptionally clear-thinking writer, Date lays out
principle and theory in a manner that is easily understood. Few others can speak as aut
horitatively the topic of relational databases as Date can. | 29.95 | sqlhks
|
32 |
| sqlhks
| SQL Hacks
| SQL
|Whether you're ru
nning Access, MySQL, SQL Server, Oracle, or PostgreSQL, this book will help you push th
e limits of traditional SQL to squeeze data effectively from your database. The book of
fers 100 hacks -- unique tips and tools -- that bring you the knowledge of experts who
apply what they know in the real world to help you take full advantage of the expressiv
e power of SQL. You'll find practical techniques to address complex data manipulation p
roblems. Learn how to: * Wrangle data in the most efficient way possible * Aggregate an
d organize your data for meaningful and accurate reporting * Make the most of subquerie
s, joins, and unions * Stay on top of the performance of your queries and the server th
at runs them * Avoid common SQL security pitfalls, including the dreaded SQL injection
attack Let SQL Hacks serve as your toolbox for digging up and manipulating data. If you
love to tinker and optimize, SQL is the perfect technology and SQL Hacks is the must-h
ave book for you. | 29.99 | sqlhks
|
32 |
| artofsql
| The Art of SQL
| Database Theory |For all the buzz
about trendy IT techniques, data processing is still at the core of our systems, especi
ally now that enterprises all over the world are confronted with exploding volumes of d
ata. Database performance has become a major headache, and most IT departments believe
that developers should provide simple SQL code to solve immediate problems and let DBAs
tune any "bad SQL" later. In The Art of SQL, author and SQL expert Stephane Faroult ar
gues that this "safe approach" only leads to disaster. His insightful book, named after
Art of War by Sun Tzu, contends that writing quick inefficient code is sweeping the di
rt under the rug. SQL code may run for 5 to 10 years, surviving several major releases
of the database management system and on several generations of hardware. The code must
be fast and sound from the start, and that requires a firm understanding of SQL and re
lational theory. The Art of SQL offers best practices that teach experienced SQL users
to focus on strategy rather than specifics. Faroult's approach takes a page from Sun Tz
u's classic treatise by viewing database design as a military campaign. You need knowle
dge, skills, and talent. Talent can't be taught, but every strategist from Sun Tzu to m
odern-day generals believed that it can be nurtured through the experience of others. T
hey passed on their experience acquired in the field through basic principles that serv
ed as guiding stars amid the sound and fury of battle. This is what Faroult does with S
QL. Like a successful battle plan, good architectural choices are based on contingencie
s. What if the volume of this or that table increases unexpectedly? What if, following
a merger, the number of users doubles? What if you want to keep several years of data o
nline? Faroult's way of looking at SQL performance may be unconventional and unique, bu
t he's deadly serious about writing good SQL and using SQL well. The Art of SQL is not
a cookbook, listing problems and giving recipes. The aim is to get you-and your manager
-to raise good questions. | 44.99 | sqlhks
|
32 |
| sqltuning
| SQL Tuning
| Database Theory |A poorly performi
ng database application not only costs users time, but also has an impact on other appl
ications running on the same computer or the same network. SQL Tuning provides an essen
tial next step for SQL developers and database administrators who want to extend their
SQL tuning expertise and get the most from their database applications. There are two b
asic issues to focus on when tuning SQL: how to find and interpret the execution plan o
f an SQL statement and how to change SQL to get a specific alternate execution plan. SQ
L Tuning provides answers to these questions and addresses a third issue that's even mo
re important: how to find the optimal execution plan for the query to use. Author Dan T
ow outlines a timesaving method he's developed for finding the optimum execution plan--
rapidly and systematically--regardless of the complexity of the SQL or the database pla
tform being used. You'll learn how to understand and control SQL execution plans and ho
w to diagram SQL queries to deduce the best execution plan for a query. Key chapters in
the book include exercises to reinforce the concepts you've learned. SQL Tuning conclu
des by addressing special concerns and unique solutions to "unsolvable problems." Wheth
er you are a programmer who develops SQL-based applications or a database administrator
or other who troubleshoots poorly tuned applications, SQL Tuning will arm you with a r
eliable and deterministic method for tuning your SQL queries to gain optimal performanc
e. | 39.95 | sqlhks
|
32 |
| mysqlspp
| MySQL Stored Procedure Programming | MySQL
|The implementatio
n of stored procedures in MySQL 5.0 a huge milestone -- one that is expected to lead to
widespread enterprise adoption of the already extremely popular MySQL database. If you
are serious about building the web-based database applications of the future, you need
to get up to speed quickly on how stored procedures work -- and how to build them the
right way. This book, destined to be the bible of stored procedure development, is a re
source that no real MySQL programmer can afford to do without. In the decade since MySQ
L burst on the scene, it has become the dominant open source database, with capabilitie
s and performance rivaling those of commercial RDBMS offerings like Oracle and SQL Serv
er. Along with Linux and PHP, MySQL is at the heart of millions of applications. And no
w, with support for stored procedures, functions, and triggers in MySQL 5.0, MySQL offe
rs the programming power needed for true enterprise use. MySQL's new procedural languag
e has a straightforward syntax, making it easy to write simple programs. But it's not s
o easy to write secure, easily maintained, high-performance, and bug-free programs. Few
in the MySQL world have substantial experience yet with stored procedures, but Guy Har
rison and Steven Feuerstein have decades of combined expertise. In MySQL Stored Procedu
re Programming, they put that hard-won experience to good use. Packed with code example
s and covering everything from language basics to application building to advanced tuni
ng and best practices, this highly readable book is the one-stop guide to MySQL develop
ment. It consists of four major sections: * MySQL stored programming fundamentals -- tu
torial, basic statements, SQL in stored programs, and error handling * Building MySQL s
tored programs -- transaction handling, built-in functions, stored functions, and trigg
ers * MySQL stored programs in applications -- using stored programs with PHP, Java, Pe
rl, Python, and .NET (C# and VB.NET) * Optimizing MySQL stored programs -- security, ba
sic and advanced SQL tuning, optimizing stored program code, and programming best pract
ices A companion web site contains many thousands of lines of code, that you can put to
use immediately. Guy Harrison is Chief Architect of Database Solutions at Quest Softwa
re and a frequent speaker and writer on MySQL topics. Steven Feuerstein is the author o
f Oracle PL/SQL Programming, the classic reference for Oracle stored programming for mo
re than ten years. Both have decades of experience as database developers, and between
them they have authored a dozen books. | 44.99 | sqlhks
|
32 |
| databaseid | Database in Depth
| Database Theory |This book sheds l
ight on the principles behind the relational model, which is fundamental to all databas
e-backed applications--and, consequently, most of the work that goes on in the computin
g world today. Database in Depth: The Relational Model for Practitioners goes beyond th
e hype and gets to the heart of how relational databases actually work. Ideal for exper
ienced database developers and designers, this concise guide gives you a clear view of
the technology--a view that's not influenced by any vendor or product. Featuring an ext
ensive set of exercises, it will help you: * understand why and how the relational mode
l is still directly relevant to modern database technology (and will remain so for the
foreseeable future) * see why and how the SQL standard is seriously deficient * use the
best current theoretical knowledge in the design of their databases and database appli
cations * make informed decisions in their daily database professional activities Datab
ase in Depth will appeal not only to database developers and designers, but also to a d
iverse field of professionals and academics, including database administrators (DBAs),
information modelers, database consultants, and more. Virtually everyone who deals with
relational databases should have at least a passing understanding of the fundamentals
of working with relational models. Author C.J. Date has been involved with the relation
al model from its earliest days. An exceptionally clear-thinking writer, Date lays out
principle and theory in a manner that is easily understood. Few others can speak as aut
horitatively the topic of relational databases as Date can. | 29.95 | sqltuning
|
105 |
| sqlhks
| SQL Hacks
| SQL
|Whether you're ru
nning Access, MySQL, SQL Server, Oracle, or PostgreSQL, this book will help you push th
e limits of traditional SQL to squeeze data effectively from your database. The book of
fers 100 hacks -- unique tips and tools -- that bring you the knowledge of experts who
apply what they know in the real world to help you take full advantage of the expressiv
e power of SQL. You'll find practical techniques to address complex data manipulation p
roblems. Learn how to: * Wrangle data in the most efficient way possible * Aggregate an
d organize your data for meaningful and accurate reporting * Make the most of subquerie
s, joins, and unions * Stay on top of the performance of your queries and the server th
at runs them * Avoid common SQL security pitfalls, including the dreaded SQL injection
attack Let SQL Hacks serve as your toolbox for digging up and manipulating data. If you
love to tinker and optimize, SQL is the perfect technology and SQL Hacks is the must-h
ave book for you. | 29.99 | sqltuning
|
105 |
| artofsql
| The Art of SQL
| Database Theory |For all the buzz
about trendy IT techniques, data processing is still at the core of our systems, especi
ally now that enterprises all over the world are confronted with exploding volumes of d
ata. Database performance has become a major headache, and most IT departments believe
that developers should provide simple SQL code to solve immediate problems and let DBAs
tune any "bad SQL" later. In The Art of SQL, author and SQL expert Stephane Faroult ar
gues that this "safe approach" only leads to disaster. His insightful book, named after
Art of War by Sun Tzu, contends that writing quick inefficient code is sweeping the di
rt under the rug. SQL code may run for 5 to 10 years, surviving several major releases
of the database management system and on several generations of hardware. The code must
be fast and sound from the start, and that requires a firm understanding of SQL and re
lational theory. The Art of SQL offers best practices that teach experienced SQL users
to focus on strategy rather than specifics. Faroult's approach takes a page from Sun Tz
u's classic treatise by viewing database design as a military campaign. You need knowle
dge, skills, and talent. Talent can't be taught, but every strategist from Sun Tzu to m
odern-day generals believed that it can be nurtured through the experience of others. T
hey passed on their experience acquired in the field through basic principles that serv
ed as guiding stars amid the sound and fury of battle. This is what Faroult does with S
QL. Like a successful battle plan, good architectural choices are based on contingencie
s. What if the volume of this or that table increases unexpectedly? What if, following
a merger, the number of users doubles? What if you want to keep several years of data o
nline? Faroult's way of looking at SQL performance may be unconventional and unique, bu
t he's deadly serious about writing good SQL and using SQL well. The Art of SQL is not
a cookbook, listing problems and giving recipes. The aim is to get you-and your manager
-to raise good questions. | 44.99 | sqltuning
|
105 |
| sqltuning
| SQL Tuning
| Database Theory |A poorly performi
ng database application not only costs users time, but also has an impact on other appl
ications running on the same computer or the same network. SQL Tuning provides an essen
tial next step for SQL developers and database administrators who want to extend their
SQL tuning expertise and get the most from their database applications. There are two b
asic issues to focus on when tuning SQL: how to find and interpret the execution plan o
f an SQL statement and how to change SQL to get a specific alternate execution plan. SQ
L Tuning provides answers to these questions and addresses a third issue that's even mo
re important: how to find the optimal execution plan for the query to use. Author Dan T
ow outlines a timesaving method he's developed for finding the optimum execution plan-rapidly and systematically--regardless of the complexity of the SQL or the database pla
tform being used. You'll learn how to understand and control SQL execution plans and ho
w to diagram SQL queries to deduce the best execution plan for a query. Key chapters in
the book include exercises to reinforce the concepts you've learned. SQL Tuning conclu
des by addressing special concerns and unique solutions to "unsolvable problems." Wheth
er you are a programmer who develops SQL-based applications or a database administrator
or other who troubleshoots poorly tuned applications, SQL Tuning will arm you with a r
eliable and deterministic method for tuning your SQL queries to gain optimal performanc
e. | 39.95 | sqltuning
|
105 |
| mysqlspp
| MySQL Stored Procedure Programming | MySQL
|The implementatio
n of stored procedures in MySQL 5.0 a huge milestone -- one that is expected to lead to
widespread enterprise adoption of the already extremely popular MySQL database. If you
are serious about building the web-based database applications of the future, you need
to get up to speed quickly on how stored procedures work -- and how to build them the
right way. This book, destined to be the bible of stored procedure development, is a re
source that no real MySQL programmer can afford to do without. In the decade since MySQ
L burst on the scene, it has become the dominant open source database, with capabilitie
s and performance rivaling those of commercial RDBMS offerings like Oracle and SQL Serv
er. Along with Linux and PHP, MySQL is at the heart of millions of applications. And no
w, with support for stored procedures, functions, and triggers in MySQL 5.0, MySQL offe
rs the programming power needed for true enterprise use. MySQL's new procedural languag
e has a straightforward syntax, making it easy to write simple programs. But it's not s
o easy to write secure, easily maintained, high-performance, and bug-free programs. Few
in the MySQL world have substantial experience yet with stored procedures, but Guy Har
rison and Steven Feuerstein have decades of combined expertise. In MySQL Stored Procedu
re Programming, they put that hard-won experience to good use. Packed with code example
s and covering everything from language basics to application building to advanced tuni
ng and best practices, this highly readable book is the one-stop guide to MySQL develop
ment. It consists of four major sections: * MySQL stored programming fundamentals -- tu
torial, basic statements, SQL in stored programs, and error handling * Building MySQL s
tored programs -- transaction handling, built-in functions, stored functions, and trigg
ers * MySQL stored programs in applications -- using stored programs with PHP, Java, Pe
rl, Python, and .NET (C# and VB.NET) * Optimizing MySQL stored programs -- security, ba
sic and advanced SQL tuning, optimizing stored program code, and programming best pract
ices A companion web site contains many thousands of lines of code, that you can put to
use immediately. Guy Harrison is Chief Architect of Database Solutions at Quest Softwa
re and a frequent speaker and writer on MySQL topics. Steven Feuerstein is the author o
f Oracle PL/SQL Programming, the classic reference for Oracle stored programming for mo
re than ten years. Both have decades of experience as database developers, and between
them they have authored a dozen books. | 44.99 | sqltuning
|
105 |
+-------------+------------------------------------+-----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------+-------------+-----------------+
25 rows in set (0.00 sec)
mysql>
The database gave yo u the exact info rmatio n yo u requested—it matched every ro w in the Pro ducts table with every ro w
in the Invento ry table. Five ro ws in Pro ducts times five ro ws in Invento ry (5 x 5) = 25 ro ws. This is the cartesian product
o f tho se two tables. Graphically, a cartesian pro duct lo o ks like this:
Fo r jo ins to be effective, yo u need to specify ho w to link tables to gether. Yo u do this by specifying the join columns.
Note
Yo u can jo in nearly any co lumn, with nearly any data type. Usually, fo r perfo rmance reaso ns, we o nly
want to jo in o n o ur primary key (o r ano ther key).
We kno w that the Pro ducts and Invento ry tables have a co mmo n co lumn: Pro ductCo de. We'll jo in o n this co lumn. We'll
also specify the co lumns we want to view instead o f requesting all co lumns.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT Products.ProductCode, Products.Title, Products.Price, I.QuantityInStock a
s Qty
-> FROM Products
-> JOIN Inventory as I on (Products.ProductCode = I.ProductCode);
+-------------+------------------------------------+-------+-----+
| ProductCode | Title
| Price | Qty |
+-------------+------------------------------------+-------+-----+
| artofsql
| The Art of SQL
| 44.99 | 52 |
| databaseid | Database in Depth
| 29.95 |
0 |
| mysqlspp
| MySQL Stored Procedure Programming | 44.99 |
5 |
| sqlhks
| SQL Hacks
| 29.99 | 32 |
| sqltuning
| SQL Tuning
| 39.95 | 105 |
+-------------+------------------------------------+-------+-----+
5 rows in set (0.00 sec)
mysql>
Yo u see the five ro ws fro m the Invento ry and Pro ducts tables that have the same Pro ductCo de. Yo ur results might be
in a different o rder, because we didn't ask the database to return the results in any particular o rder. Let's lo o k a little
clo ser.
OBSERVE:
mysql> SELECT Products.ProductCode, Products.Title, Products.Price, I.QuantityInStock a
s Qty
-> FROM Products
-> JOIN Inventory as I on (Products.ProductCode = I.ProductCode);
No tice that we listed the Pro ductCo de co lumn as Pro duct s.Pro ductCo de? Different tables might have co lumns with
the same names, so SQL requires us to reference a specific table and co lumn. We do this by using the
TableName.ColumnName syntax.
There is a sho rtcut available. Yo u can specify a sho rter name fo r a table as a table alias. In o ur example we created an
alias fo r Invento ry called I by typing Inve nt o ry as I.
Yo u can also specify a column alias using the same syntax. See ho w we renamed the Quant it yInSt o ck co lumn?
Finally, we specify the co lumns we want to jo in o n by using the o n keywo rd: o n (Pro duct s.Pro duct Co de =
I.Pro duct Co de ). Graphically, a jo in co uld lo o k so mething like this:
Co ngratulatio ns, yo u've written o ne query to get yo ur pro duct and invento ry info rmatio n!
Other Joins
Left Joins
What happens if so meo ne at the bo o ksto re has created a ro w in the Pro ducts table fo r a new bo o k, but hasn't
entered a co rrespo nding ro w in Invento ry?
Let's see fo r o urselves by adding o ne mo re bo o k to the Pro duct table. We'll do wnlo ad this o ne as well.
Type the fo llo wing at the MySQL pro mpt:
mysql> exit;
Bye
cold1:~$ curl -L http://courses.oreillyschool.com/dba1/downloads/products-1.sql
> products-1.sql
% Total
% Received % Xferd Average Speed
Time
Time
Time Current
Dload Upload
Total
Spent
Left Speed
101 1219 101 1219
0
0
9718
0 --:--:-- --:--:-- --:--:-- 1190k
cold1:~$
Once that file has do wnlo aded, use the m ysql co mmand to impo rt the pro ducts.
Type the fo llo wing at the Unix pro mpt:
cold1:~$ mysql -h sql -p -u username username < products-1.sql
Enter password:
cold1:~$
Again, if the impo rt is successful, yo u see no results. This added a reco rd to the Pro ducts table fo r
relatio naldb, "The Relatio nal Database Dictio nary."
Once yo u have that data impo rted, reco nnect to MySQL. Be sure to set sql_m o de ='t radit io nal' again.
No w run yo ur previo us query to retrieve the pro duct quantities. Here it is again (using table aliases this time):
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT P.ProductCode, P.Title, P.Price, I.QuantityInStock as Qty
-> FROM Products as P
-> JOIN Inventory as I on (P.ProductCode = I.ProductCode);
+-------------+------------------------------------+-------+-----+
| ProductCode | Title
| Price | Qty |
+-------------+------------------------------------+-------+-----+
| artofsql
| The Art of SQL
| 44.99 | 52 |
| databaseid | Database in Depth
| 29.95 |
0 |
| mysqlspp
| MySQL Stored Procedure Programming | 44.99 |
5 |
| sqlhks
| SQL Hacks
| 29.99 | 32 |
| sqltuning
| SQL Tuning
| 39.95 | 105 |
+-------------+------------------------------------+-------+-----+
5 rows in set (0.00 sec)
mysql>
Yo u ran the insert statement, but yo ur results are the same as befo re!
The database is do ing exactly what yo u asked it to do —it's sho wing yo u every ro w fro m Invento ry and
Pro ducts where the pro duct co de is the same. Since the invento ry table do esn't have a ro w with
Pro duct Co de ='re lat io naldb', no ro w is returned fo r that bo o k.
It wo uld be nice to see such a ro w, tho ugh. Fo rtunately there is a way we can make this happen—the LEFT
JOIN. The left jo in tells the database to return all ro ws fro m the first o r LEFT table, even if a co rrespo nding ro w
do esn't exist in the seco nd o r RIGHT table. Graphically, a left jo in lo o ks like this:
Let's try a left jo in.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT P.ProductCode, P.Title, P.Price, I.QuantityInStock as Qty
-> FROM Products as P
-> LEFT JOIN Inventory as I on (P.ProductCode = I.ProductCode);
+--------------+------------------------------------+-------+------+
| ProductCode | Title
| Price | Qty |
+--------------+------------------------------------+-------+------+
| artofsql
| The Art of SQL
| 44.99 |
52 |
| databaseid
| Database in Depth
| 29.95 |
0 |
| mysqlspp
| MySQL Stored Procedure Programming | 44.99 |
5 |
| relationaldb | The Relational Database Dictionary | 14.99 | NULL |
| sqlhks
| SQL Hacks
| 29.99 |
32 |
| sqltuning
| SQL Tuning
| 39.95 | 105 |
+--------------+------------------------------------+-------+------+
6 rows in set (0.00 sec)
mysql>
No w the missing ro w fro m Pro ducts is returned, alo ng with a NULL quantity since no co rrespo nding ro w
exists in the Invento ry table. Yo ur results may be so rted differently—that is OK.
Full Outer Joins / Union
What if yo u wanted to jo in the Pro ducts and Invento ry tables, sho wing ro ws fro m Pro ducts that do n't match
ro ws in Invento ry, and ro ws in Invento ry that do n't match ro ws in Pro ducts? This is called a FULL OUTER
JOIN. Graphically, a full outer join lo o ks like this:
Befo re we try o ut a full o uter jo in, let's create an entry in Invento ry that do esn't match anything in Pro ducts.
Type the fo llo wing at the MySQL pro mpt:
mysql> INSERT INTO Inventory VALUES ('Q4440', 14);
Query OK, 1 row affected (0.01 sec)
mysql>
Note
Usually yo u wo uldn't want a ro w to be in invento ry unless there was already a co rrespo nding
ro w in Pro ducts. The database has a way yo u can enfo rce this rule, called a foreign key
constraint. We'll discuss this in a future co urse.
No w let's try to query o ur tables.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT P.ProductCode, I.QuantityInStock, P.Title, P.Price
-> FROM Products as P
-> FULL OUTER JOIN Inventory as I on (P.ProductCode = I.ProductCode);
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near 'FULL
OUTER JOIN Inventory as I on (P.ProductCode = I.ProductCode)' at line 3
mysql>
Unfo rtunately, MySQL do esn't suppo rt full o uter jo ins. As with mo st pro gramming languages, there is ano ther
way to perfo rm this query. Fo rtunately, MySQL do es suppo rt the UNION keywo rd.
A union will co mbine two select statements into o ne resulting data set. The o nly restrictio n is that the two
queries must return the same number o f co lumns o f the same data type. Fo r o ur full o uter jo in pro blem, we
can use o ur previo us LEFT JOIN query to retrieve Pro ducts and Invento ry, and unio n tho se results with a new
query that is just the o ppo site: a LEFT JOIN o f Invento ry o n Pro ducts.
First, let's write a LEFT JOIN query o f Invento ry o n Pro ducts. We'll make sure to specify exactly the same
co lumns as o ur previo us query, except ProductCode. We'll reference the ProductCode fro m Invento ry instead
o f Pro ducts this time.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT I.ProductCode, I.QuantityInStock, P.Title, P.Price
-> FROM Inventory as I
-> LEFT JOIN Products as P on (P.ProductCode = I.ProductCode)
-> WHERE P.ProductCode IS NULL;
+-------------+-----------------+-------+-------+
| ProductCode | QuantityInStock | Title | Price |
+-------------+-----------------+-------+-------+
| Q4440
|
14 | NULL | NULL |
+-------------+-----------------+-------+-------+
1 row in set (0.00 sec)
mysql>
Fo r this query we added a WHERE clause that limits o ur data set to ro ws fro m Invento ry that do n't have
co rrespo nding ro ws in Pro ducts. If we didn't include this WHERE clause, we wo uld get duplicates in o ur
UNIONed data set because o ur previo us query includes matching ro ws.
This is exactly what we want—o nly the ro ws fro m Invento ry that do n't co rrespo nd to ro ws in Pro ducts. No w
we can co mbine o ur two queries.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT P.ProductCode, I.QuantityInStock, P.Title, P.Price
-> FROM Products as P
-> LEFT JOIN Inventory as I on (P.ProductCode = I.ProductCode)
-> UNION ALL
-> SELECT I.ProductCode, I.QuantityInStock, P.Title, P.Price
-> FROM Inventory as I
-> LEFT JOIN Products as P on (P.ProductCode = I.ProductCode)
-> WHERE P.ProductCode IS NULL;
+--------------+-----------------+------------------------------------+-------+
| ProductCode | QuantityInStock | Title
| Price |
+--------------+-----------------+------------------------------------+-------+
| artofsql
|
52 | The Art of SQL
| 44.99 |
| databaseid
|
0 | Database in Depth
| 29.95 |
| mysqlspp
|
5 | MySQL Stored Procedure Programming | 44.99 |
| relationaldb |
NULL | The Relational Database Dictionary | 14.99 |
| sqlhks
|
32 | SQL Hacks
| 29.99 |
| sqltuning
|
105 | SQL Tuning
| 39.95 |
| Q4440
|
14 | NULL
| NULL |
+--------------+-----------------+------------------------------------+-------+
7 rows in set (0.02 sec)
mysql>
Take a clo ser lo o k at the co mmand and the results:
OBSERVE:
mysql> SELECT P.ProductCode, I.QuantityInStock, P.Title, P.Price
-> FROM Products as P
-> LEFT JOIN Inventory as I on (P.ProductCode = I.ProductCode)
-> UNION ALL
-> SELECT I.ProductCode, I.QuantityInStock, P.Title, P.Price
-> FROM Inventory as I
-> LEFT JOIN Products as P on (P.ProductCode = I.ProductCode)
-> WHERE P.ProductCode IS NULL;
+--------------+-----------------+------------------------------------+-------+
| ProductCode | QuantityInStock | Title
| Price |
+--------------+-----------------+------------------------------------+-------+
| artofsql
|
52 | The Art of SQL
| 44.99 |
| databaseid
|
0 | Database in Depth
| 29.95 |
| mysqlspp
|
5 | MySQL Stored Procedure Programming | 44.99 |
| relationaldb |
NULL | The Relational Database Dictionary | 14.99 |
| sqlhks
|
32 | SQL Hacks
| 29.99 |
| sqltuning
|
105 | SQL Tuning
| 39.95 |
| Q4440
|
14 | NULL
| NULL |
+--------------+-----------------+------------------------------------+-------+
7 rows in set (0.02 sec)
First yo u see o ur pre vio us que ry, then the UNION ALL keywo rd, and then o ur ne w que ry.
This is o ur full o uter jo in—ro ws in Pro ducts that do n't match ro ws in Invento ry, and ro ws in Invento ry that
do n't match ro ws in Pro ducts. The f irst six ro ws are fro m the first query, and the last ro w is fro m the
seco nd query.
Yo u've learned a lo t in this lesso n! In the next lesso n yo u'll learn ho w to further co mbine yo ur data in meaningful ways to
answer many new business questio ns. See yo u there!
Copyright © 1998-2014 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
Aggregates, Functions, and Conditionals
In this lesso n yo u'll learn several mo re ways yo u can query yo ur data.
Aggregating Data
Aggregate functio ns create summaries fro m yo ur ro ws and co lumns o f data. The simplest aggregate functio n is
COUNT, which is a ro w co unt. Let's try it o ut by retrieving the number o f ro ws (pro ducts) ro ws in the Pro ducts table.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT COUNT(*) FROM Products;
+----------+
| COUNT(*) |
+----------+
|
6 |
+----------+
1 row in set (0.00 sec)
mysql>
Note
If yo u've changed the Pro ducts table fro m the last lesso n, yo u'll see a different number.
Here, the COUNT aggregate has given us the number o f ro ws in the Pro ducts table. It wo uld be nice to be able to
answer mo re co mplex questio ns, such as "Ho w many pro ducts are in each catego ry?" To answer that questio n, we
must GROUP BY the Catego ry co lumn o n the Pro ducts table.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT Category, COUNT(*) as NumberOfProducts
-> FROM Products
-> GROUP BY Category;
+-----------------+------------------+
| Category
| NumberOfProducts |
+-----------------+------------------+
| Database Theory |
3 |
| MySQL
|
1 |
| SQL
|
2 |
+-----------------+------------------+
3 rows in set (0.00 sec)
mysql>
There are three bo o ks in the "Database Theo ry" catego ry, o ne in "MySQL," and two in "SQL."
What if yo u want to find the average price and the maximum price o f the pro ducts in each catego ry? Yo u can use
multiple aggregates in the same query.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT Category, AVG(Price) as AveragePrice, MAX(Price) as MaximumPrice
-> FROM Products
-> GROUP BY Category;
+-----------------+--------------+--------------+
| Category
| AveragePrice | MaximumPrice |
+-----------------+--------------+--------------+
| Database Theory |
38.296667 |
44.99 |
| MySQL
|
44.990000 |
44.99 |
| SQL
|
22.490000 |
29.99 |
+-----------------+--------------+--------------+
3 rows in set (0.00 sec)
mysql>
OBSERVE:
mysql> SELECT Category, AVG(Price) as AveragePrice, MAX(Price) as MaximumPrice
-> FROM Products
-> GROUP BY Category;
In this query, we specified the co lumns o n which we wo uld like to apply the aggregate. The AVG aggregate is o ver the
Price co lumn, and so is the MAX aggregate.
MySQL allo ws yo u to o mit the GROUP BY clause in so me queries, but if yo u o mit GROUP BY, yo ur query may no t
return the same results. Try it:
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT Category, AVG(Price) as AveragePrice, MAX(Price) as MaximumPrice
-> FROM Products;
+-----------------+--------------+--------------+
| Category
| AveragePrice | MaximumPrice |
+-----------------+--------------+--------------+
| Database Theory |
34.143333 |
44.99 |
+-----------------+--------------+--------------+
1 row in set (0.00 sec)
mysql>
Yo u o nly see o ne result ro w.
If yo u want, yo u can disable this MySQL-specific behavio r by changing the SQL_MODE.
Type the fo llo wing at the MySQL pro mpt:
mysql> set SQL_MODE='ONLY_FULL_GROUP_BY';
Query OK, 0 rows affected (0.00 sec)
mysql>
No w when yo u run a query witho ut a GROUP BY yo u will see an erro r (assuming yo ur sql_mo de is still set to
'ONLY_FULL_GROUP_BY').
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT Category, AVG(Price) as AveragePrice, MAX(Price) as MaximumPrice
-> FROM Products;
ERROR 1140 (42000): Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP col
umns is illegal if there is no GROUP BY clause
Fo r mo re info rmatio n abo ut MySQL's use o f GROUP BY, see MySQL's web site.
There are many mo re useful aggregate functio ns, such as SUM and MIN. See MySQL's web site fo r additio nal
aggregate functio ns. Be sure to take so me time and experiment with these!
Functions
While aggregates allo w yo u to summarize many ro ws o f info rmatio n, functio ns allo w yo u to create brand-new
co lumns o f data. The sto re keeps track o f pro ducts, and the number o f pro ducts in invento ry. Suppo se yo ur manager
wants to kno w the do llar value o f the pro ducts in sto ck.
In the last lesso n we used a jo in to sho w the pro ducts alo ng with the quantity in sto ck. Let's write that query again.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT P.ProductCode, P.Price, I.QuantityInStock as Qty
-> FROM Products as P
-> LEFT JOIN Inventory as I on (P.ProductCode = I.ProductCode);
+--------------+-------+------+
| ProductCode | Price | Qty |
+--------------+-------+------+
| artofsql
| 44.99 |
52 |
| databaseid
| 29.95 |
0 |
| mysqlspp
| 44.99 |
5 |
| relationaldb | 14.99 | NULL |
| sqlhks
| 29.99 |
32 |
| sqltuning
| 39.95 | 105 |
+--------------+-------+------+
6 rows in set (0.00 sec)
mysql>
The do llar value fo r a pro duct is the Price times the Quantity. Let's add this "Do llar Value" to o ur query.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT P.ProductCode, P.Price, I.QuantityInStock as Qty, P.Price * I.QuantityInS
tock as DollarValue
-> FROM Products as P
-> LEFT JOIN Inventory as I on (P.ProductCode = I.ProductCode);
+--------------+-------+------+-------------+
| ProductCode | Price | Qty | DollarValue |
+--------------+-------+------+-------------+
| artofsql
| 44.99 |
52 |
2339.48 |
| databaseid
| 29.95 |
0 |
0.00 |
| mysqlspp
| 44.99 |
5 |
224.95 |
| relationaldb | 14.99 | NULL |
NULL |
| sqlhks
| 29.99 |
32 |
959.68 |
| sqltuning
| 39.95 | 105 |
4194.75 |
+--------------+-------+------+-------------+
6 rows in set (0.00 sec)
mysql>
OBSERVE:
P.Price * I.QuantityInStock as DollarValue
The result includes has a new Do llarValue co lumn which is the pro duct o f Price and Quant it y.
It might seem strange to have a NULL Do llarValue. But it is the desired result, since Qty is NULL fo r that ro w.
So ho w can we find the to tal do llar value fo r o ur pro ducts? Let's co mbine o ur functio n with the SUM aggregate!
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT P.ProductCode, P.Price, I.QuantityInStock as Qty, SUM(P.Price * I.Quantit
yInStock) as DollarValue
-> FROM Products as P
-> LEFT JOIN Inventory as I on (P.ProductCode = I.ProductCode);
ERROR 1140 (42000): Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP col
umns is illegal if there is no GROUP BY clause
mysql>
We are asking fo r a summary o f all ro ws in the Pro ducts and Invento ry tables, alo ng with the Pro ductCo de, Price, and
QuantityInSto ck. This do esn't make sense—what is the Pro ductCo de fo r the total sum? The database canno t give yo u
a co rrect answer, so yo u get the no nsensical result.
To co rrect this pro blem, yo u have two o ptio ns: yo u can remo ve the extra co lumns fro m yo ur query, o r yo u can
GROUP BY tho se co lumns. Since we are lo o king fo r the to tal o f all ro ws, let's remo ve the co lumns.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT SUM(P.Price * I.QuantityInStock) as TotalDollarValue
-> FROM Products as P
-> LEFT JOIN Inventory as I on (P.ProductCode = I.ProductCode);
+------------------+
| TotalDollarValue |
+------------------+
|
7718.86 |
+------------------+
1 row in set (0.00 sec)
mysql>
This query is much better, and gives us the desired result.
MySQL has many functio ns that o perate o n strings, numbers, and dates. Yo u can find mo re info rmatio n abo ut these
functio ns at the MySQL web site.
Conditionals
No w that yo u kno w abo ut aggregates and functio ns, yo u're able to answer so me interesting questio ns! Suppo se yo ur
bo ss has a new invento ry pro blem fo r yo u to so lve. If there are less than 10 pro ducts in the sto re, she wants the sto re
manager to reo rder. If there are between 10 and 50 pro ducts, the invento ry level is fine. If there are 50 o r mo re
pro ducts, the manager needs to send the extra sto ck to the wareho use.
Ho w do we query the database to find the details abo ut the invento ry? One way is to use a CASE statement.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT P.ProductCode, P.Title, I.QuantityInStock as Qty,
-> CASE WHEN I.QuantityInStock < 10 THEN 'Reorder'
->
WHEN I.QuantityInStock >= 10 AND I.QuantityInStock < 50 THEN 'In Stock'
->
WHEN I.QuantityInStock >= 50 THEN 'Extra to Warehouse'
-> END as Action
-> FROM Products as P
-> LEFT JOIN Inventory as I on (P.ProductCode = I.ProductCode);
+--------------+------------------------------------+------+--------------------+
| ProductCode | Title
| Qty | Action
|
+--------------+------------------------------------+------+--------------------+
| artofsql
| The Art of SQL
|
52 | Extra to Warehouse |
| databaseid
| Database in Depth
|
0 | Reorder
|
| mysqlspp
| MySQL Stored Procedure Programming |
5 | Reorder
|
| relationaldb | The Relational Database Dictionary | NULL | NULL
|
| sqlhks
| SQL Hacks
|
32 | In Stock
|
| sqltuning
| SQL Tuning
| 105 | Extra to Warehouse |
+--------------+------------------------------------+------+--------------------+
6 rows in set (0.01 sec)
OBSERVE:
mysql>
->
->
->
->
->
->
SELECT P.ProductCode, P.Title, I.QuantityInStock as Qty,
CASE WHEN I.QuantityInStock < 10 THEN 'Reorder'
WHEN I.QuantityInStock >= 10 AND I.QuantityInStock < 50 THEN 'In Stock'
WHEN I.QuantityInStock >= 50 THEN 'Extra to warehouse'
END as Action
FROM Products as P
LEFT JOIN Inventory as I on (P.ProductCode = I.ProductCode);
CASE statements have two parts—co m pariso ns and re sult s. Co m pariso ns are checked in o rder. As so o n as a
TRUE co mpariso n is fo und, the co rrespo nding re sult is returned.
This is almo st the result we are lo o king fo r; ho wever, that NULL fo r "The Relatio nal Database Dictio nary" is tro ubling.
Since we have never had invento ry fo r that bo o k, we sho uld set the actio n to be "Place Initial Order." But remember,
we're dealing with NULLs so we have to be careful.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT P.ProductCode, P.Title, IFNULL(I.QuantityInStock, 0) as Qty,
-> CASE WHEN I.QuantityInStock IS NULL THEN 'Place Initial Order'
->
WHEN I.QuantityInStock < 10 THEN 'Reorder'
->
WHEN I.QuantityInStock >= 10 AND I.QuantityInStock < 50 THEN 'In Stock'
->
WHEN I.QuantityInStock >= 50 THEN 'Extra to warehouse'
-> END as Action
-> FROM Products as P
-> LEFT JOIN Inventory as I on (P.ProductCode = I.ProductCode);
+--------------+------------------------------------+-----+---------------------+
| ProductCode | Title
| Qty | Action
|
+--------------+------------------------------------+-----+---------------------+
| artofsql
| The Art of SQL
| 52 | Extra to warehouse |
| databaseid
| Database in Depth
|
0 | Reorder
|
| mysqlspp
| MySQL Stored Procedure Programming |
5 | Reorder
|
| relationaldb | The Relational Database Dictionary |
0 | Place Initial Order |
| sqlhks
| SQL Hacks
| 32 | In Stock
|
| sqltuning
| SQL Tuning
| 105 | Extra to warehouse |
+--------------+------------------------------------+-----+---------------------+
6 rows in set (0.00 sec)
OBSERVE:
mysql> SELECT P.ProductCode, P.Title, IFNULL(I.QuantityInStock, 0) as Qty,
-> CASE WHEN I.QuantityInStock IS NULL THEN 'Place Initial Order'
We used the IFNULL co nditio nal to check the QuantityInSto ck co lumn. NULLs in that co lumn are replaced by zero s
(0 ). We also added a co mpariso n to the CASE statement—I.Quant it yInSt o ck IS NULL—to display the actio n "Place
Initial Order."
In this lesso n, yo u learned ho w to co mbine data fro m yo ur co lumns in meaningful ways to create new co lumns o f data and
summaries o f ro ws. In the next lesso n, yo u'll learn o ne way to sto re yo ur new queries in the database fo r future use. See yo u
then!
Copyright © 1998-2014 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
Subqueries and Views
In the past few lesso ns, we've learned mo re co mplex ways to query o ur databases. In this lesso n we'll examine o ne mo re way
to query o ur databases, as well as a way to save o ur co mplex queries.
Querying Queries
Yo ur small bo o k sto re do esn't have a lo t o f sto rage ro o m. Yo u o ccasio nally need to query the database to find o ut
which pro ducts yo u have the highest quantity o f in invento ry. Remember when we wro te a query to return the invento ry
levels fo r each pro duct in o ur catalo g? Let's try it again, just in case yo u fo rgo t.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT P.ProductCode, I.QuantityInStock as Qty, P.Title, P.Price
-> FROM Products as P
-> LEFT JOIN Inventory as I on (P.ProductCode = I.ProductCode);
+--------------+------+------------------------------------+-------+
| ProductCode | Qty | Title
| Price |
+--------------+------+------------------------------------+-------+
| artofsql
|
52 | The Art of SQL
| 44.99 |
| databaseid
|
0 | Database in Depth
| 29.95 |
| mysqlspp
|
5 | MySQL Stored Procedure Programming | 44.99 |
| relationaldb | NULL | The Relational Database Dictionary | 14.99 |
| sqlhks
|
32 | SQL Hacks
| 29.99 |
| sqltuning
| 105 | SQL Tuning
| 39.95 |
+--------------+------+------------------------------------+-------+
6 rows in set (0.00 sec)
mysql>
Yo u co uld scan all o f the returned items to find the o ne with the largest quantity. But it wo uld be even better to return a
single ro w. We learned earlier abo ut aggregate functio ns such as MAX. Let's try using it to return the desired result.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT P.ProductCode, MAX(I.QuantityInStock) as Qty, P.Title, P.Price
-> FROM Products as P
-> LEFT JOIN Inventory as I on (P.ProductCode = I.ProductCode)
-> GROUP BY I.ProductCode, P.Title, P.Price;
+-------------+------+------------------------------------+-------+
| ProductCode | Qty | Title
| Price |
+-------------+------+------------------------------------+-------+
| artofsql
|
52 | The Art of SQL
| 44.99 |
| databaseid |
0 | Database in Depth
| 29.95 |
| mysqlspp
|
5 | MySQL Stored Procedure Programming | 44.99 |
| relationaldb| NULL | The Relational Database Dictionary | 14.99 |
| sqlhks
|
32 | SQL Hacks
| 29.99 |
| sqltuning
| 105 | SQL Tuning
| 39.95 |
+-------------+------+------------------------------------+-------+
6 rows in set (0.00 sec)
mysql>
OBSERVE:
mysql>
->
->
->
SELECT P.ProductCode, MAX(I.QuantityInStock) as Qty, P.Title, P.Price
FROM Products as P
LEFT JOIN Inventory as I on (P.ProductCode = I.ProductCode)
GROUP BY I.ProductCode, P.Title, P.Price;
Since we're using the MAX aggregate with no n-aggregate co lumns, we need to use a co rrespo nding GROUP BY
clause. In English, the GROUP BY wo uld ro ughly translate to "fo r each Pro ductCo de, Title, and Price co mbinatio n
GROUP, sho w me the MAX(Price)."
The o rder may no t be the same, but the same six ro ws are returned. And as it turns o ut we answered a different
questio n—fo r each ro w in Pro ducts, we returned the co rrespo nding MAX quantity fro m Invento ry. We really just wanted
the single pro duct with the maximum quantity in Invento ry.
In o rder to return this info rmatio n, let's try to restrict o ur query with a WHERE clause:
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT P.ProductCode, I.QuantityInStock as Qty, P.Title, P.Price
-> FROM Products as P
-> LEFT JOIN Inventory as I on (P.ProductCode = I.ProductCode)
-> WHERE I.QuantityInStock = MAX(I.QuantityInStock);
ERROR 1111 (HY000): Invalid use of group function
mysql>
This query isn't quite right either. Fear no t, there is ho pe! We can co rrect this erro r if we use a subquery.
If yo u think abo ut tables and query results, yo u'll realize that they are essentially the same. Bo th co ntain ro ws and
co lumns o f data. It wo uld seem lo gical to be able to query the results fro m a query. And as the pro gramming go ds
wo uld have it, yo u can! Yo u do this using a subquery.
In o rder to return the pro duct with the greatest quantity, let's query the results o f a query. But befo re we do that, let's
make sure that the subquery is co rrect. First, find the maximum QuantityInSto ck in Invento ry.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT MAX(QuantityInStock) FROM Inventory;
+----------------------+
| MAX(QuantityInStock) |
+----------------------+
|
105 |
+----------------------+
1 row in set (0.00 sec)
mysql>
That lo o ks go o d! No w that we kno w the MAX(Quant it yinSt o ck) fro m Invento ry, the query co uld essentially be
rewritten like so :
OBSERVE:
SELECT P.ProductCode, I.QuantityInStock as Qty, P.Title, P.Price
FROM Products as P
LEFT JOIN Inventory as I on (P.ProductCode = I.ProductCode)
WHERE I.QuantityInStock = 105;
While this query might return the desired result no w, o n a live system it wo n't wo rk reliably. After all, the QuantityInSto ck
might change befo re we get a chance to run the query. Instead let's use a subquery. Type the fo llo wing query into the
edito r:
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT P.ProductCode, I.QuantityInStock as Qty, P.Title, P.Price
-> FROM Products as P
-> LEFT JOIN Inventory as I on (P.ProductCode = I.ProductCode)
-> WHERE I.QuantityInStock = (SELECT MAX(QuantityInStock) FROM Inventory);
+-------------+------+------------+-------+
| ProductCode | Qty | Title
| Price |
+-------------+------+------------+-------+
| sqltuning
| 105 | SQL Tuning | 39.95 |
+-------------+------+------------+-------+
1 row in set (0.02 sec)
mysql>
There yo u have it! Exactly the results we wanted.
Views
We've learned a lo t o f co mplex ways to write queries. It can be cumberso me to rewrite these queries. Since query
results lo o k just like a table, wo uldn't it be nice to be able to sto re a query definitio n in the database, and access it just
like a table?
Views so lve o ur pro blem. Views are a great way to tuck away co mplex query lo gic into the database. Database
Administrato rs lo ve views because they can be used to hide sensitive co lumns o f data (such as so cial security
numbers) fro m certain users.
Creating a View
Remember when yo u used a jo in to query the pro ducts and invento ry tables? Let's run that query again.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT P.ProductCode, P.Title, P.Price, I.QuantityInStock as Qty
-> FROM Products as P
-> LEFT JOIN Inventory as I on (P.ProductCode = I.ProductCode);
+--------------+------------------------------------+-------+------+
| ProductCode | Title
| Price | Qty |
+--------------+------------------------------------+-------+------+
| artofsql
| The Art of SQL
| 44.99 |
52 |
| databaseid
| Database in Depth
| 29.95 |
0 |
| mysqlspp
| MySQL Stored Procedure Programming | 44.99 |
5 |
| relationaldb | The Relational Database Dictionary | 14.99 | NULL |
| sqlhks
| SQL Hacks
| 29.99 |
32 |
| sqltuning
| SQL Tuning
| 39.95 | 105 |
+--------------+------------------------------------+-------+------+
6 rows in set (0.00 sec)
mysql>
(Of co urse, if the data in yo ur tables has changed, yo ur results will be different.)
This data is very useful, but typing that query is cumberso me. We'll sto re the query in a new view called
ProdInventory. The syntax fo r creating a view is pretty straightfo rward: CREAT E VIEW name AS query.
Type the fo llo wing at the MySQL pro mpt:
mysql> CREATE VIEW ProdInventory AS
-> SELECT P.ProductCode, P.Title, P.Price, I.QuantityInStock as Qty
-> from Products as P
-> LEFT JOIN Inventory as I on (P.ProductCode = I.ProductCode);
Query OK, 0 rows affected (0.07 sec)
mysql>
That's it! Yo u created the view.
Since a view is mo re o r less like a table, yo u can query it like a table.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT * FROM ProdInventory;
+--------------+------------------------------------+-------+------+
| ProductCode | Title
| Price | Qty |
+--------------+------------------------------------+-------+------+
| artofsql
| The Art of SQL
| 44.99 |
52 |
| databaseid
| Database in Depth
| 29.95 |
0 |
| mysqlspp
| MySQL Stored Procedure Programming | 44.99 |
5 |
| relationaldb | The Relational Database Dictionary | 14.99 | NULL |
| sqlhks
| SQL Hacks
| 29.99 |
32 |
| sqltuning
| SQL Tuning
| 39.95 | 105 |
+--------------+------------------------------------+-------+------+
6 rows in set (0.00 sec)
mysql>
Restrictions on Views
Views are nearly identical to tables, ho wever, there are so me impo rtant differences.
First, yo u canno t always INSERT into a view. If yo ur view co ntains jo ins, yo u wo n't be able to insert data into
all o f the jo ined tables. Yo u may be able to insert into o ne o f the tables, but it's usually best to avo id INSERTs
to views.
Seco nd, views are sensitive to changes in the database. Fo r example, in the Pro dInvento ry view, if the Title
co lumn is changed to "Pro ductTitle," the view will give an erro r.
Dropping a View
The view we created befo re is nice; ho wever, the name is a little co nfusing. Instead o f calling it
Pro dInve nt o ry (which might be interpreted as Pro duct io n Inve nt o ry), let's call it Pro duct Inve nt o ry.
Remo ving a view fro m the database is similar to remo ving a table—yo u use the DROP VIEW IF EXIST S
co mmand.
Type the fo llo wing at the MySQL pro mpt:
mysql> DROP VIEW IF EXISTS ProdInventory;
Query OK, 0 rows affected (0.00 sec)
mysql>
We are no w free to add o ur view called Pro duct Inve nt o ry.
Type the fo llo wing at the MySQL pro mpt:
mysql> CREATE VIEW ProductInventory AS
SELECT P.ProductCode, P.Title, P.Price, I.QuantityInStock as Qty
FROM Products as P
LEFT JOIN Inventory as I on (P.ProductCode = I.ProductCode);
Query OK, 0 rows affected (0.00 sec)
mysql>
No w yo u've learned ano ther way to query yo ur data. Yo u've also learned abo ut the po wer o f views—ano ther way the database
wo rks fo r yo u, instead o f yo u wo rking fo r yo ur database. In the next lesso n we'll expand o n that idea and learn ho w to sto re
co mplex lo gic in the database. Stay tuned!
Copyright © 1998-2014 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
Stored Procedures
In the last lesso n we learned ho w to use a view to save co mplex query lo gic in the database. While views are really useful, they
can't be used to sto re a sequence o f steps that so metimes need to be perfo rmed with data. In this lesso n yo u'll learn ho w to
use stored procedures.
Using Stored Procedures
Motivations
Sto red pro cedures are like functio ns fo r the database. They have a set o f parameters, perfo rm a set o f tasks,
and may return a set o f results. Co de reuse is impo rtant, and sto red pro cedures pro vide a kind o f co de reuse
that is similar to what functio ns and classes do in o ther languages.
Techno lo gies (especially web techno lo gies) co me and go , but data do esn't change much. The pro cess o f
tracking sto re invento ry is essentially the same to day as it was in 19 9 8 , 19 8 8 , o r 19 78 . But the techno lo gy
has changed pretty dramatically—invento ry tracking was do ne o n paper in 19 78 , then maybe o n a greenscreen co mputer in 19 8 8 , and then in a Windo ws applicatio n in 19 9 8 , but to day, invento ry tracking is likely to
be do ne using a web bro wser and a Windo ws applicatio n . Sto red pro cedures created back in 19 8 8 wo uld
still functio n to day, twenty-plus years and three user interfaces later because data itself hasn't change much,
but the fro nt-end techno lo gy sure did!
Sto red pro cedures, in additio n to helping us track data, are also used to secure data. In business, fo r
example, access to database tables co uld be disallo wed specifically to make sure that access is gained o nly
thro ugh a sto red pro cedures. Since the database user is kno wn to the server, sensitive info rmatio n (such as
ho urly salary rates) wo uldn't be returned to users o utside o f the human reso urces staff. This security applies
to all access thro ugh a Windo ws applicatio n, thro ugh a web site, o r thro ugh co mmand-line to o ls.
Sto red pro cedures have yet ano ther advantage: speed. By keeping lo gic next to the data, database servers
do n't have to send massive amo unts o f info rmatio n to applicatio ns (and back) fo r pro cessing. This might no t
matter fo r small databases with o nly a few hundred ro ws, but it is critical fo r databases that co ntain millio ns o r
billio ns o f ro ws.
Creating Stored Procedures
Setup
Befo re we can create a pro cedure we'll have to make a small change to o ur MySQL enviro nment. MySQL
usually expects a semico lo n at the end o f a statement. Since sto red pro cedures can encapsulate many
statements, we'll have to tell MySQL to use so mething else to separate statements as we enter them. To do
this we'll use the special de lim it e r keywo rd.
Type the fo llo wing at the MySQL pro mpt:
mysql> DELIMITER //
mysql>
This co mmand do esn't return anything, but yo u'll no tice a difference after yo u run a query.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT ProductCode,Title FROM Products;
->
To submit the query to the server, yo u need to enter the delimiter, //. Once yo u do , yo ur query will be
evaluated, and yo u'll see results.
Type the fo llo wing at the MySQL pro mpt:
-> //
+--------------+------------------------------------+
| ProductCode | Title
|
+--------------+------------------------------------+
| artofsql
| The Art of SQL
|
| databaseid
| Database in Depth
|
| mysqlspp
| MySQL Stored Procedure Programming |
| relationaldb | The Relational Database Dictionary |
| sqlhks
| SQL Hacks
|
| sqltuning
| SQL Tuning
|
+--------------+------------------------------------+
6 rows in set (0.00 sec)
mysql>
Duplicating our View
A perfectly valid use o f a sto red pro cedure is to sto re a query fo r repeated use. A view co uld be used fo r this
use as well, ho wever mo st databases can o ptimize sto red pro cedures in ways that are no t po ssible with view
o r ad-ho c queries.
Let's take o ur Pro ductInvento ry view and turn it into a basic sto red pro cedure. Belo w is the query behind that
view. Try it o ut to refresh yo ur memo ry.
INTERACTIVE SESSION:
mysql> SELECT P.ProductCode, P.Title, P.Price, I.QuantityInStock as Qty
-> FROM Products as P
-> LEFT JOIN Inventory as I on (P.ProductCode = I.ProductCode)//
+--------------+------------------------------------+-------+------+
| ProductCode | Title
| Price | Qty |
+--------------+------------------------------------+-------+------+
| artofsql
| The Art of SQL
| 44.99 |
52 |
| databaseid
| Database in Depth
| 29.95 |
0 |
| mysqlspp
| MySQL Stored Procedure Programming | 44.99 |
5 |
| relationaldb | The Relational Database Dictionary | 14.99 | NULL |
| sqlhks
| SQL Hacks
| 29.99 |
32 |
| sqltuning
| SQL Tuning
| 39.95 | 105 |
+--------------+------------------------------------+-------+------+
6 rows in set (0.00 sec)
mysql>
Let's dive right in and create o ur pro cedure. We'll do so by using CREATE PROCEDURE.
Type the fo llo wing at the MySQL pro mpt:
mysql> CREATE PROCEDURE CurrentProductInventory ()
-> BEGIN
-> SELECT P.ProductCode, P.Title, P.Price, I.QuantityInStock as Qty
-> FROM Products AS P
-> LEFT JOIN Inventory as I on (P.ProductCode = I.ProductCode);
-> END;
-> //
Query OK, 0 rows affected (0.00 sec)
mysql>
OBSERVE:
mysql>
->
->
->
->
->
->
CREATE PROCEDURE CurrentProductInventory ()
BEGIN
SELECT P.ProductCode, P.Title, P.Price, I.QuantityInStock as Qty
FROM Products AS P
LEFT JOIN Inventory as I on (P.ProductCode = I.ProductCode);
END;
//
First we used the CREAT E PROCEDURE keywo rd, fo llo wed by the name o f o ur pro cedure
—Curre nt Pro duct Inve nt o ry. A pair o f empty parentheses () tells MySQL that o ur pro cedure wo n't have
any parameters.
Next, the BEGIN keywo rd tells MySQL that we are go ing to write o ne o r mo re statements that sho uld be
treated as a blo ck. The END; keywo rd marks the end o f that blo ck. Finally, we end o ur entry with the //
delimiter.
No w let's run the pro cedure, using the CALL keywo rd. We still need to type in the delimiters, since we haven't
reset that MySQL o ptio n.
Type the fo llo wing at the MySQL pro mpt:
mysql> CALL CurrentProductInventory ();
-> //
+--------------+------------------------------------+-------+------+
| ProductCode | Title
| Price | Qty |
+--------------+------------------------------------+-------+------+
| artofsql
| The Art of SQL
| 44.99 |
52 |
| databaseid
| Database in Depth
| 29.95 |
0 |
| mysqlspp
| MySQL Stored Procedure Programming | 44.99 |
5 |
| relationaldb | The Relational Database Dictionary | 14.99 | NULL |
| sqlhks
| SQL Hacks
| 29.99 |
32 |
| sqltuning
| SQL Tuning
| 39.95 | 105 |
+--------------+------------------------------------+-------+------+
6 rows in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql>
Make sure yo u type the pro cedure name—Curre nt Pro duct Inve nt o ry—co rrectly, and that yo u type in an
empty set o f parentheses () to tell MySQL that o ur pro cedure do esn't take any parameters.
Parameters
Using a sto red pro cedure to return results like a view can be helpful; ho wever, sto red pro cedures are much
mo re po werful if they accept parameters.
In the first few lesso ns, we designed a sto re structure to keep track o f pro ducts and invento ry in two tables,
then we entered data into tho se two tables manually. While this pro cess will wo rk, it's clunky and erro r-pro ne.
Instead o f adding pro ducts to the system manually into two tables, we co uld use a sto red pro cedure.
Adding a pro duct requires inserting data into two tables—Pro ducts and Invento ry. Do ne separately, the
queries lo o k like this:
OBSERVE:
INSERT INTO Products (ProductCode, Title, Category, Description, Price)
VALUES ('mysqlian', 'MySQL in a Nutshell', 'MySQL', 'MySQL in a Nutshell covers
all MySQL functions, as well as MySQL
administration.', 39.95);
INSERT INTO Inventory (ProductCode, QuantityInStock)
VALUES ('mysqlian', 52);
In o rder to add a pro duct, we need to kno w the fo llo wing info rmatio n:
Pro duct Co de
Title
Catego ry
Descriptio n
Price
Quantity
Quantity
These bits o f info rmatio n will beco me parameters. Here's a skeleto n fo r o ur sto red pro cedure.
OBSERVE:
CREATE PROCEDURE CreateProduct (
ProductCode varchar(20),
Title varchar(50),
Category varchar(30),
Description text,
Price decimal (9,2),
Quantity int
)
BEGIN
END;
//
We have each o f o ur param e t e rs, fo llo wed by a dat a t ype that matches o ur table definitio n. No w let's
co mplete this pro cedure by filling in o ur two queries.
Type the fo llo wing at the MySQL pro mpt:
mysql> CREATE PROCEDURE CreateProduct (
->
ProductCode varchar(20),
->
Title varchar(50),
->
Category varchar(30),
->
Description text,
->
Price decimal (9,2),
->
Quantity int
-> )
-> BEGIN
->
INSERT INTO Products (ProductCode, Title, Category, Description, Price)
->
VALUES (ProductCode, Title, Category, Description, Price);
->
INSERT INTO Inventory (ProductCode, QuantityInStock)
->
VALUES (ProductCode, Quantity);
-> END;
-> //
Query OK, 0 rows affected (0.00 sec)
mysql>
Calling this pro cedure is similar to calling the last o ne. Try it witho ut any parameters:
Type the fo llo wing at the MySQL pro mpt:
mysql> CALL CreateProduct ();
-> //
ERROR 1318 (42000): Incorrect number of arguments for PROCEDURE certjosh.CreateP
roduct; expected 6, got 0
mysql>
This pro cedure has six parameters, and requires all six.
Note
We just created the pro cedure, so we kno w the names and data types o f the parameters fo r o ur
pro cedure. If yo u need to check the definitio n o f a pro cedure, yo u can do so by using sho w
cre at e pro ce dure procedure name.
Let's call the pro cedure with parameters this time. The example belo w has o ne parameter per line to facilitate
o ur discussio n, but yo u can enter all parameters o n o ne line if yo u like.
Type the fo llo wing at the MySQL pro mpt:
mysql> CALL CreateProduct (
->
"mysqlian",
->
"MySQL in a Nutshell",
->
"MySQL",
->
"MySQL in a Nutshell covers all MySQL functions, as well as MySQL admin
istration.",
->
39.95,
->
52
->
);
-> //
Query OK, 1 row affected (0.00 sec)
mysql>
But wait ! Didn't the sto red pro cedure create two ro ws—o ne in Pro duct and o ne in Invento ry? Check by
running the previo us Curre nt Pro duct Inve nt o ry sto red pro cedure.
Type the fo llo wing at the MySQL pro mpt:
mysql> CALL CurrentProductInventory ();
-> //
+--------------+------------------------------------+-------+------+
| ProductCode | Title
| Price | Qty |
+--------------+------------------------------------+-------+------+
| artofsql
| The Art of SQL
| 44.99 |
52 |
| databaseid
| Database in Depth
| 29.95 |
0 |
| mysqlian
| MySQL in a Nutshell
| 39.95 |
52 |
| mysqlspp
| MySQL Stored Procedure Programming | 44.99 |
5 |
| relationaldb | The Relational Database Dictionary | 14.99 | NULL |
| sqlhks
| SQL Hacks
| 29.99 |
32 |
| sqltuning
| SQL Tuning
| 39.95 | 105 |
+--------------+------------------------------------+-------+------+
7 rows in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql>
It seems that two ro ws were inserted after all. MySQL's respo nses can so metimes be misleading.
Variables
Mo st pro gramming languages have so me co ncept o f a variable; SQL is no different. Variables can be very
useful in sto red pro cedures, where they can be used to sto re intermediate results. Variables in MySQL are not
case-sensitive, so a variable named m yVariable is the same as o ne named MyVARIABLE.
Our Inve nt o ry table currently has two co lumns: Pro ductCo de and QuantityInSto ck. Suppo se yo ur manager
wants to update invento ry by title instead o f by Pro ductCo de. We co uld make a sto red pro cedure to make this
task easier.
First, let's write so me co de to capture a Pro ductCo de fo r a pro duct.
Type the fo llo wing at the MySQL pro mpt:
mysql> CREATE PROCEDURE GetProductCode (
->
product_title varchar(50)
-> )
-> BEGIN
->
DECLARE product_code varchar(20);
->
->
SELECT ProductCode into product_code
->
FROM Products
->
WHERE Title = product_title;
->
->
SELECT product_code as ProductCode;
-> END;
-> //
Query OK, 0 rows affected (0.00 sec)
mysql>
OBSERVE:
...
->
->
->
->
->
->
->
DECLARE product_code varchar(20);
SELECT ProductCode into product_code
FROM Products
WHERE Title = product_title;
SELECT product_code as ProductCode;
...
The DECLARE statement in o ur pro cedure tells MySQL that we are using a variable named pro duct _co de ,
who se type is varchar(20 ). Later, we use a SELECT statement to view the results.
Let's try the new pro cedure. We'll lo o k up the title SQL Hacks.
Type the fo llo wing at the MySQL pro mpt:
mysql> call GetProductCode('SQL Hacks');
-> //
+-------------+
| ProductCode |
+-------------+
| sqlhks
|
+-------------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql>
Lo o king go o d! The pro duct co de is co rrect, so let's rewrite o ur pro cedure to accept o ne new parameter called
Ne wQuant it yInSt o ck and update o ur invento ry table.
Remo ve o ur o ld pro cedure befo re we co ntinue.
Type the fo llo wing at the MySQL pro mpt:
mysql> DROP PROCEDURE IF EXISTS GetProductCode;
-> //
Query OK, 0 rows affected (0.00 sec)
mysql>
No w, create the new pro cedure.
Type the fo llo wing at the MySQL pro mpt:
mysql> CREATE PROCEDURE UpdateInventory(
->
product_title varchar(50),
->
NewQuantityInStock int
-> )
-> BEGIN
->
DECLARE product_code varchar(20);
->
->
SELECT ProductCode into product_code
->
FROM Products
->
WHERE Title = product_title;
->
->
UPDATE Inventory SET QuantityInStock=NewQuantityInStock
->
WHERE ProductCode = product_code;
-> END;
-> //
Query OK, 0 rows affected (0.00 sec)
mysql>
There are two new bits: the Ne wQuant it yInSt o ck parameter, and the UPDAT E statement that sets the new
quantity in sto ck.
Befo re we try the pro cedure, let's manually reset the QuantityInSto ck fo r "sqlhks."
Type the fo llo wing at the MySQL pro mpt:
mysql> UPDATE Inventory SET QuantityInStock=32
-> WHERE ProductCode = 'sqlhks';
-> //
Query OK, 0 rows affected (0.01 sec)
Rows matched: 1 Changed: 0 Warnings: 0
mysql>
With that do ne, we can test o ur pro cedure. Let's try to set o ur invento ry to 9 9 .
Type the fo llo wing at the MySQL pro mpt:
mysql> call UpdateInventory('SQL Hacks',99);
-> //
Query OK, 1 row affected (0.01 sec)
mysql>
Was the invento ry updated? Let's check it o ut.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT * FROM Inventory WHERE ProductCode='sqlhks';
-> //
+-------------+-----------------+
| ProductCode | QuantityInStock |
+-------------+-----------------+
| sqlhks
|
99 |
+-------------+-----------------+
1 row in set (0.00 sec)
mysql>
Sure eno ugh, it wo rked perfectly!
Lo o ks go o d! Yo u may be asking yo urself, "what happens if there are two bo o ks with the same title?" Since
the pro duct title isn't the primary key, that co uld happen. Add a pro duct to yo ur invento ry, and run
Updat e Inve nt o ry to see what happens, and then think abo ut ho w yo u co uld handle this pro blem.
Yo u've learned a lo t in this lesso n! Yo u're o n yo ur way to creating po werful and reliable database applicatio ns. In the next
lesso n, we'll learn abo ut two co ncepts impo rtant to many end users: ho w to PIVOT and UNPIVOT yo ur data.
Copyright © 1998-2014 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
PIVOT and UNPIVOT
Welco me back! In the last few lesso ns we've been lo o king into the different ways we can write queries and pro cedures to
interact with o ur data. In this lesso n we'll learn abo ut two data manipulatio n techniques—pivot and unpivot.
PIVOT ing Data
Pivo ting data is the pro cess o f aggregating o r mo ving ro ws o f data into co lumns. Suppo se o ur sto re keeps track o f
sales data. The bo ss o nly cares abo ut Unit s So ld, and he really wants to kno w ho w many units were so ld in the
No rt h and ho w many were so ld in the So ut h. Business users and pro grammers o ften view data in drastically
different ways.
Pro grammers might think in ro ws and co lumns o f data, such as the fo llo wing table with sales data by regio n and date:
Re gio n
Quart e r
Unit s So ld
No rth
20 0 7-0 3-31 15,0 8 9
No rth
20 0 7-0 6 -30 18 ,79 5
No rth
20 0 7-0 9 -30 19 ,0 6 5
No rth
20 0 7-12-31
So uth
20 0 7-0 3-31 20 ,0 15
So uth
20 0 7-0 6 -30 19 ,8 0 6
So uth
20 0 7-0 9 -30 21,0 53
So uth
20 0 7-12-31
19 ,9 8 7
23,0 6 8
Sho wing the data in this way is useful, especially to pro grammers, but many business users may want to co mpare the
units so ld by regio n and by date. It's difficult to lo o k at the previo us table and co mpare seco nd quarter 20 0 7 sales fo r
the No rth and So uth regio ns.
Business users wo uld pro bably prefer to see the data this way:
Re gio n
Unit s So ld Unit s So ld Unit s So ld Unit s So ld
20 0 7 -Q1
20 0 7 -Q2
20 0 7 -Q3
20 0 7 -Q4
No rth
15,0 8 9
18 ,79 5
19 ,0 6 5
19 ,9 8 7
So uth
20 ,0 15
19 ,8 0 6
21,0 53
23,0 6 8
This representatio n sho ws exactly the same data, but no w it's easy fo r business users to see that fo r 20 0 7-Q2 the
So uth o utso ld the No rth by 1,0 11 units. Graphically, a pivo t may lo o k like this:
Majo r databases such as Oracle and SQL Server no w have PIVOT keywo rds added to their SQL dialects. While
MySQL do esn't currently have that keywo rd, yo u can still pivo t yo ur data witho ut much tro uble.
Let's start by adding a simple table fo r o ur demo nstratio ns. We'll use the same data and same basic structure as the
first table.
Note
If yo u haven't clo sed the terminal sessio n since the last lesso n, set yo ur delimiter back fro m "//" to ";".
Type the fo llo wing at the MySQL pro mpt:
mysql> CREATE TABLE SalesAnalysis
-> (
->
Region varchar(10) NOT NULL,
->
Quarter date NOT NULL,
->
UnitsSold integer NOT NULL
-> ) ENGINE=INNODB;
Query OK, 0 rows affected (0.01 sec)
mysql>
Once yo u have the table created, po pulate it with o ur sample data.
T ip
Remember yo u can use the Up arro w key to repeat a co mmand in mysql and then edit the co mmand. Fo r
example, after yo u enter the first co mmand belo w, press the up arro w key and then edit the Quarter date
and the UnitsSo ld integer to create the next co mmand.
Type the fo llo wing at the MySQL pro mpt:
mysql> INSERT INTO SalesAnalysis values ('NORTH', '2007-03-31',15089);
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO SalesAnalysis VALUES ('NORTH', '2007-06-30',18795);
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO SalesAnalysis VALUES ('NORTH', '2007-09-30',19065);
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO SalesAnalysis VALUES ('NORTH', '2007-12-31',19987);
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO SalesAnalysis VALUES ('SOUTH', '2007-03-31',20015);
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO SalesAnalysis VALUES ('SOUTH', '2007-06-30',19806);
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO SalesAnalysis VALUES ('SOUTH', '2007-09-30',21053);
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO SalesAnalysis VALUES ('SOUTH', '2007-12-31',23068);
Query OK, 0 rows affected (0.01 sec)
mysql>
Check that yo u entered everything co rrectly:
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT * FROM SalesAnalysis;
+--------+------------+-----------+
| Region | Quarter
| UnitsSold |
+--------+------------+-----------+
| NORTH | 2007-03-31 |
15089 |
| NORTH | 2007-06-30 |
18795 |
| NORTH | 2007-09-30 |
19065 |
| NORTH | 2007-12-31 |
19987 |
| SOUTH | 2007-03-31 |
20015 |
| SOUTH | 2007-06-30 |
19806 |
| SOUTH | 2007-09-30 |
21053 |
| SOUTH | 2007-12-31 |
23068 |
+--------+------------+-----------+
8 rows in set (0.00 sec)
mysql>
No w that we have so me sample data, ho w do we go abo ut pivo ting the ro ws into co lumns? If yo u recall fro m the
previo us lesso ns, we've already learned ho w to use the CASE statement and aggregates. We'll use bo th o f tho se
features to co me up with o ur PIVOT.
The co lumn we want to pivo t is Unit sSo ld, and we want to pivo t that co lumn by the Quart e r co lumn. We'll add fo ur
new co lumns named 20 0 7 -Q1, 20 0 7 -Q2, 20 0 7 -Q3, and 20 0 7 -Q4 , and use a CASE statement to allo cate UnitsSo ld
to each o f tho se new co lumns. Let's try it!
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT Region,
-> CASE WHEN Quarter='2007-03-31' THEN UnitsSold
-> CASE WHEN Quarter='2007-06-30' THEN UnitsSold
-> CASE WHEN Quarter='2007-09-30' THEN UnitsSold
-> CASE WHEN Quarter='2007-12-31' THEN UnitsSold
-> FROM SalesAnalysis;
+--------+---------+---------+---------+---------+
| Region | 2007-Q1 | 2007-Q2 | 2007-Q3 | 2007-Q4 |
+--------+---------+---------+---------+---------+
| NORTH |
15089 |
NULL |
NULL |
NULL |
| NORTH |
NULL |
18795 |
NULL |
NULL |
| NORTH |
NULL |
NULL |
19065 |
NULL |
| NORTH |
NULL |
NULL |
NULL |
19987 |
| SOUTH |
20015 |
NULL |
NULL |
NULL |
| SOUTH |
NULL |
19806 |
NULL |
NULL |
| SOUTH |
NULL |
NULL |
21053 |
NULL |
| SOUTH |
NULL |
NULL |
NULL |
23068 |
+--------+---------+---------+---------+---------+
8 rows in set (0.00 sec)
END
END
END
END
AS
AS
AS
AS
'2007-Q1',
'2007-Q2',
'2007-Q3',
'2007-Q4'
END
END
END
END
AS
AS
AS
AS
'2007-Q1',
'2007-Q2',
'2007-Q3',
'2007-Q4'
mysql>
Let's lo o k a little clo ser.
OBSERVE:
mysql>
->
->
->
->
->
SELECT Region,
CASE WHEN Quarter='2007-03-31'
CASE WHEN Quarter='2007-06-30'
CASE WHEN Quarter='2007-09-30'
CASE WHEN Quarter='2007-12-31'
FROM SalesAnalysis;
THEN
THEN
THEN
THEN
UnitsSold
UnitsSold
UnitsSold
UnitsSold
Here, the UnitsSo ld in the f irst quart e r are entered into the new '20 0 7 -Q1' co lumn, the UnitsSo ld in the se co nd
quart e r are put into the new '20 0 7 -Q2' co lumn, and so o n. But the results are no t exactly co rrect—they still co ntain as
many ro ws as the o riginal table, with a bunch o f NULL values in between the useful values.
Ho w can we co llapse this into meaningful data? We'll use an aggregate! In this example we can use SUM to add up
o ur new co lumns, gro uped by the regio n. Fo r go o d practice, we sho uld also add an ELSE clause to the CASE
statement. Instead o f using NULL, we'll use zero .
Let's try o ur updated pivo t!
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT Region,
-> SUM(CASE WHEN Quarter='2007-03-31' THEN UnitsSold
-> SUM(CASE WHEN Quarter='2007-06-30' THEN UnitsSold
-> SUM(CASE WHEN Quarter='2007-09-30' THEN UnitsSold
-> SUM(CASE WHEN Quarter='2007-12-31' THEN UnitsSold
-> FROM SalesAnalysis
-> GROUP BY Region;
+--------+---------+---------+---------+---------+
| Region | 2007-Q1 | 2007-Q2 | 2007-Q3 | 2007-Q4 |
+--------+---------+---------+---------+---------+
| NORTH |
15089 |
18795 |
19065 |
19987 |
| SOUTH |
20015 |
19806 |
21053 |
23068 |
+--------+---------+---------+---------+---------+
2 rows in set (0.00 sec)
mysql>
ELSE
ELSE
ELSE
ELSE
0
0
0
0
END)
END)
END)
END)
AS
AS
AS
AS
'2007-Q1',
'2007-Q2',
'2007-Q3',
'2007-Q4'
This o ne lo o ks much better, and returns the co rrect results. Our business users will be very happy.
UNPIVOT ing Data
As yo u just saw, pivo ting data changes ro ws into co lumns. Unpivoting data changes co lumns into ro ws. This is very
useful when yo ur business users give yo u a set o f data and ask yo u to impo rt it into a traditio nal database fo rmat.
Unpivo ting lo o ks so mething like this:
Note
If yo u pivo t data, yo u canno t necessarily unpivo t the result to get back to the o riginal data. Remember that
when yo u pivo t data, yo u aggregate ro ws into a single co lumn. It may no t be po ssible to deaggregate that
co lumn back to several ro ws.
In the pivo t example fro m earlier in the lesso n, we wo rked with sales data by regio n and quarter. Suppo se this data
was impo rted fro m a system directly in that fo rmat. What wo uld that lo o k like? Let's save o ur previo us query as a view
in o rder to o bserve this co nditio n.
Type the fo llo wing at the MySQL pro mpt:
mysql> CREATE VIEW SalesDataPivot AS
-> SELECT Region,
-> SUM(CASE WHEN Quarter='2007-03-31'
-> SUM(CASE WHEN Quarter='2007-06-30'
-> SUM(CASE WHEN Quarter='2007-09-30'
-> SUM(CASE WHEN Quarter='2007-12-31'
-> FROM SalesAnalysis
-> GROUP BY Region;
Query OK, 0 rows affected (0.01 sec)
mysql>
THEN
THEN
THEN
THEN
UnitsSold
UnitsSold
UnitsSold
UnitsSold
ELSE
ELSE
ELSE
ELSE
0
0
0
0
END)
END)
END)
END)
AS
AS
AS
AS
'2007-Q1',
'2007-Q2',
'2007-Q3',
'2007-Q4'
Run a quick query using this new view to make sure yo u see the same results.
No w that we have o ur view in place, we can co nstruct o ur query to unpivo t the data. Since MySQL do esn't have an
UNPIVOT o perato r, we'll have to do it the o ld-fashio ned way by using a few queries and UNION statements. We'll write
fo ur queries—o ne fo r each o f the co lumns to be unpivo ted. Then we'll add a new co lumn called Quart e r to each
query.
First let's try to unpivo t the first quarter o f data—'20 0 7-Q1'.
WARNING
Be sure to type the co rrect character fo r the co lumn 20 0 7 -Q1. MySQL requires co lumn names to
be quo ted with a backwards apo stro phe (`) because the co lumn name starts with a number and
co ntains a dash. Do n't co nfuse the backwards apo stro phe character with the plain apo stro phe (')
character. The backwards apo stro phe key is usually lo cated near the Esc key o n yo ur keybo ard.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT Region,
-> '2007-03-31' AS Quarter,
-> `2007-Q1` AS UnitsSold
-> FROM SalesDataPivot;
+--------+------------+-----------+
| Region | Quarter
| UnitsSold |
+--------+------------+-----------+
| NORTH | 2007-03-31 |
15089 |
| SOUTH | 2007-03-31 |
20015 |
+--------+------------+-----------+
2 rows in set (0.00 sec)
mysql>
OBSERVE:
mysql>
->
->
->
SELECT Region,
'2007-03-31' AS Quarter,
`2007-Q1` AS UnitsSold
FROM SalesDataPivot;
Here, we added a new co lumn named Quart e r and renamed the co lumn `20 0 7 -Q1` "UnitsSo ld".
Lo o ks great! No w we can co mbine this with three mo re queries, and a UNION statement to co llect all o f the results.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT Region, '2007-03-31' AS
-> FROM SalesDataPivot
->
UNION
-> SELECT Region, '2007-06-30' AS
-> FROM SalesDataPivot
->
UNION
-> SELECT Region, '2007-09-30' AS
-> FROM SalesDataPivot
->
UNION
-> SELECT Region, '2007-12-31' AS
-> FROM SalesDataPivot;
+--------+------------+-----------+
| Region | Quarter
| UnitsSold |
+--------+------------+-----------+
| NORTH | 2007-03-31 |
15089 |
| SOUTH | 2007-03-31 |
20015 |
| NORTH | 2007-06-30 |
18795 |
| SOUTH | 2007-06-30 |
19806 |
| NORTH | 2007-09-30 |
19065 |
| SOUTH | 2007-09-30 |
21053 |
| NORTH | 2007-12-31 |
19987 |
| SOUTH | 2007-12-31 |
23068 |
+--------+------------+-----------+
8 rows in set (0.00 sec)
mysql>
Quarter, `2007-Q1` AS UnitsSold
Quarter, `2007-Q2` AS UnitsSold
Quarter, `2007-Q3` AS UnitsSold
Quarter, `2007-Q4` AS UnitsSold
This is exactly the same data that is sto red in the SalesAnalysis table!
We did it! We successfully pivo ted the data, then unpivo ted it to its o riginal fo rm.
Yo u've learned yet ano ther way to query the data in yo ur database. MySQL o ffers additio nal ways to facilitate yo ur database
applicatio ns—user defined types, functio ns, and extensio ns are all ways to expand the ways yo u sto re and interact with yo ur
data. See yo u in the next lesso n!
Copyright © 1998-2014 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
Full Text
We've co vered a lo t o f info rmatio n in the co urse so far, and learned many ways to sto re and interact with yo ur data. In this
lesso n we'll co ver o ne mo re to o l in the SQL to o l bo x: full-text indexes.
Creating Full-T ext Indexes
Yo u may want to create a full-text index to enable quick searches thro ugh large amo unts o f text. Staff wo rking in a
bo o ksto re are usually kno wledgeable abo ut many autho rs and to pics, but they can benefit fro m the use an efficient
search to o l. We can help them by pro viding a text search o f all info rmatio n asso ciated with each bo o k including the
title, autho r, bo o k descriptio n, and catego ry.
Instead o f creating a co mplex search o n all o f the database fields, a full-text index lets yo u query all included fields at
o nce.
Note
Full-text indexes are no t a replacement fo r no rmal indexes and queries. Like the name suggests, they are
o nly go o d at o ne thing: searching full-text.
The versio n o f MySQL we currently use has so me restrictio ns o n full-text indexes. The mo st impo rtant restrictio n is
that full-text indexes can o nly be used with the MyISAM engine. Befo re we can use this index o n o ur Pro ducts table,
we'll have to make sure the table type is MyISAM. MySQL versio n 5.6 .4 and later can use full-text indexes o n Inno DB
tables to o .
Type the fo llo wing at the MySQL pro mpt:
mysql> ALTER TABLE Products ENGINE=MyISAM;
Query OK, 7 rows affected (0.01 sec)
Records: 7 Duplicates: 0 Warnings: 0
mysql>
(It's OK if yo u get a warning here.)
Befo re we start experimenting with full-text indexes, we'll add so me pro ducts with lo ng descriptio ns. First, delete
existing ro ws fro m the Pro ducts and Invento ry tables.
Type the fo llo wing at the MySQL pro mpt:
mysql> DELETE FROM Products;
Query OK, 7 rows affected (0.00 sec)
mysql> DELETE FROM Inventory;
Query OK, 7 rows affected (0.01 sec)
mysql>
To avo id a lo t o f typing, we'll do wnlo ad an SQL file that co ntains new pro ducts with lo ng descriptio ns. Open a seco nd
Unix Terminal to do wnlo ad a special SQL file fo r this lesso n.
Type the fo llo wing at the Unix pro mpt in the seco nd Unix Terminal:
cold1:~$ curl http://courses.oreillyschool.com/dba1/downloads/products-10.sql > product
s-10.sql
% Total
% Received % Xferd Average Speed
Time
Time
Time Current
Dload Upload
Total
Spent
Left Speed
100 11829 100 11829
0
0 94214
0 --:--:-- --:--:-- --:--:-- 5775k
cold1:~$
Once yo u have do wnlo aded the file, use the mysql co mmand to impo rt the pro ducts.
Type the fo llo wing at the Unix pro mpt in the seco nd Unix Terminal:
cold1:~$ mysql -h sql -p -u username username < products-10.sql
Enter password:
cold1:~$
If the impo rt is successful, yo u see no results.
No w that we have so me data, let's create o ur full-text index. We need to tell the database server which co lumns we are
interested in searching. We co uld search thro ugh all char, varchar, and text co lumns, but o ur users will primarily search
o n title and descriptio n.
Switch back to the first terminal sessio n.
Type the fo llo wing at the MySQL pro mpt:
mysql> ALTER TABLE Products ADD FULLTEXT (Title, Description);
Query OK, 7 rows affected (0.01 sec)
Records: 7 Duplicates: 0 Warnings: 0
mysql>
OBSERVE:
mysql> ALTER TABLE Products ADD FULLTEXT (Title, Description);
We added FULLT EXT to the T it le and De script io n co lumns.
That's all there is to it! No w yo u're ready to write so me queries.
Querying Full-T ext Indexes
The syntax to use a full-text index in a query is straightfo rward. The magic is in the WHERE clause.
OBSERVE:
WHERE MATCH(column 1, column 2...column n)
AGAINST('comma-separated list of search criteria');
Since the bo o ks in the Pro ducts table are all o n the to pic o f databases, try searching fo r "relatio nal database."
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT ProductCode, Title, Price FROM Products
-> WHERE MATCH(Title,Description)
-> AGAINST('relational databases');
+--------------+------------------------------------+-------+
| ProductCode | Title
| Price |
+--------------+------------------------------------+-------+
| databaseid
| Database in Depth
| 29.95 |
| relationaldb | The Relational Database Dictionary | 14.99 |
| artofsql
| The Art of SQL
| 44.99 |
+--------------+------------------------------------+-------+
3 rows in set (0.02 sec)
mysql>
Take a peek at the descriptio ns fo r these bo o ks—all have so me mentio n o f the phrase "relatio nal database."
Let's co mpare the query we just executed to the o ther way o f searching fo r this info rmatio n—using the LIKE o perato r.
Yo u pro bably remember that the % percent symbo l matches anything when using the LIKE o perato r.
Type the fo llo wing at the MySQL pro mpt:
mysql> select ProductCode, Title, Price FROM Products
-> WHERE title like '%relational%databases%' OR description like '%relational%datab
ases%';
+--------------+------------------------------------+-------+
| ProductCode | Title
| Price |
+--------------+------------------------------------+-------+
| relationaldb | The Relational Database Dictionary | 14.99 |
| databaseid
| Database in Depth
| 29.95 |
+--------------+------------------------------------+-------+
2 rows in set (0.00 sec)
mysql>
Only two ro ws were returned! If yo u suspect that the full-text index is do ing so me extra wo rk, yo u are co rrect. Full-text
indexes take the language being indexed into acco unt in o rder to return relevant results. By default, a natural language
search is perfo rmed, meaning similar wo rds such as "database" and "databases" wo uld be co nsidered a match.
While that type o f match is po ssible when using LIKE, it leads to so me tricky SQL co de!
The full-text index has these o ptimizatio ns to help perfo rmance:
Wo rds less than five characters in length are igno red. (This minimum length can be changed.)
Sto p wo rds such as "the" and even "co nsidering" are igno red by default. (The list o f sto p wo rds can be
o verridden.)
Fo r a list o f default sto p wo rds, check o ut MySQL's web site.
Note
Since o ur Pro ducts table is small, using full-text index pro bably do esn't affect speed and efficiency much.
Ho wever, o n a large table with a pro perly planned full-text index, the impact o n perfo rmance can be
significant.
Try expanding the criteria—add "o racle" to the search.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT ProductCode, Title, Price FROM Products
-> WHERE MATCH(Title,Description)
-> AGAINST('relational databases, oracle');
+--------------+------------------------------------+-------+
| ProductCode | Title
| Price |
+--------------+------------------------------------+-------+
| databaseid
| Database in Depth
| 29.95 |
| relationaldb | The Relational Database Dictionary | 14.99 |
| mysqlspp
| MySQL Stored Procedure Programming | 44.99 |
| sqlhks
| SQL Hacks
| 29.99 |
| artofsql
| The Art of SQL
| 44.99 |
+--------------+------------------------------------+-------+
5 rows in set (0.00 sec)
mysql>
This time five bo o ks matched the criteria.
The next questio n yo u might ask is ho w can I rank m y m at che s in o rde r o f re le vance ?
The answer: include MAT CH...AGAINST in the selected co lumns:
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT ProductCode, Title, Price,
-> MATCH(Title,Description) AGAINST('relational databases') as Relevance
-> FROM Products
-> WHERE MATCH(Title,Description) AGAINST('relational databases');
+--------------+------------------------------------+-------+-------------------+
| ProductCode | Title
| Price | Relevance
|
+--------------+------------------------------------+-------+-------------------+
| databaseid
| Database in Depth
| 29.95 | 1.31360828876495 |
| relationaldb | The Relational Database Dictionary | 14.99 | 0.812412083148956 |
| artofsql
| The Art of SQL
| 44.99 | 0.108494639396667 |
+--------------+------------------------------------+-------+-------------------+
3 rows in set (0.00 sec)
mysql>
No w yo u can see ho w well yo ur search criteria matches the full-text index. Fo r MySQL, relevance numbers are always
flo ating-po int numbers, greater than o r equal to zero . A relevance o f zero indicates no match.
Note
It may seem like MySQL wo uld execute the full-text search twice in the previo us query. As lo ng as bo th
MAT CH...AGAINST sectio ns are exactly the same, o nly o ne query will execute.
Yo u've just learned ho w yo u can use full-text indexes to pro vide a fast and po werful way to search yo ur data. In the next lesso n,
yo u'll learn ho w to peek into the INFORMATION_SCHEMA tables MySQL maintains to learn mo re abo ut yo ur tables and
co lumns. See yo u there!
Copyright © 1998-2014 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
Information About the Database
Welco me back! So far, we've learned ho w to create and po pulate tables, use views, and create sto red pro cedures. Tables are
made up o f ro ws and co lumns. A view is a sto red versio n o f a query, and a sto red pro cedure is a sequence o f steps kept in the
database. All o f this info rmatio n is metadata—data abo ut data—extra info rmatio n that describes o ur database.
INFORMAT ION_SCHEMA
A descriptio n o f o ur database co uld be written in English like this: "tables and pro cedures used to keep track o f bo o k
invento ry in o ur sto re." It also co uld be co mpo sed in the fo rm o f a list:
Invento ry
Pro ducts
CreatePro duct
...
When yo u think abo ut it, this data co uld be o rganized in ro ws and co lumns, just like a database table itself! This is
useful because we can use o ur standard query to o ls to access all aspects o f o ur database.
MySQL and o ther databases (at least tho se that claim to suppo rt so me SQL:20 0 3 features) pro vide a windo w into
database metadata thro ugh the INFORMAT ION_SCHEMA.
A schema is a co llectio n o f tables, fields, and the relatio nships between fields and tables. In MySQL, an
INFORMAT ION_SCHEMA is a pseudo -database. It do esn't physically exist, but yo u are able to co nnect to it. Yo u can
query any table in the INFORMATION_SCHEMA, but yo u can't update, alter, o r delete anything.
T ABLES
Suppo se yo ur bo ss sto ps by yo ur desk o ne afterno o n. He heard abo ut the fancy full-text indexes yo u used in
the previo us lesso n, and he wants to kno w which tables use the MyISAM engine and which o nes use the
Inno DB engine. INFORMAT ION_SCHEMA enables yo u to answer this questio n quickly.
Let's take a peek at o ur tables by querying the TABLES table in INFORMATION_SCHEMA. In the fo llo wing list,
be sure to replace username with yo ur o wn username.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT table_name, table_type, engine
-> FROM INFORMATION_SCHEMA.TABLES
-> WHERE table_schema='username';
+-------------------+------------+--------+
| table_name
| table_type | engine |
+-------------------+------------+--------+
| Customers
| BASE TABLE | InnoDB |
| Inventory
| BASE TABLE | InnoDB |
| OrderLine
| BASE TABLE | InnoDB |
| Orders
| BASE TABLE | InnoDB |
| ProductInventory | VIEW
| NULL
|
| Products
| BASE TABLE | MyISAM |
| SalesAnalysis
| BASE TABLE | MyISAM |
| SalesDataPivot
| VIEW
| NULL
|
...
| test
| BASE TABLE | MyISAM |
+-------------------+------------+--------+
31 rows in set (1.29 sec)
mysql>
So me o f the ro ws have been o mitted fo r clarity, and yo u may see a different number o f ro ws.
With o ne sho rt query we were able to get the exact info rmatio n we needed. No w, suppo se yo ur bo ss o nly
wants the names o f the tables that do not suppo rt full-text indexes. We can easily add to the WHERE clause to
o ur previo us query to answer that questio n:
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT table_name, table_type, engine
-> FROM INFORMATION_SCHEMA.TABLES
-> WHERE table_schema='username' AND engine='InnoDB';
+------------+------------+--------+
| table_name | table_type | engine |
+------------+------------+--------+
| Customers | BASE TABLE | InnoDB |
| Inventory | BASE TABLE | InnoDB |
| OrderLine | BASE TABLE | InnoDB |
| Orders
| BASE TABLE | InnoDB |
+------------+------------+--------+
4 rows in set (1.00 sec)
We have fo ur tables that do no t suppo rt full-text indexing, and o ur bo ss has his answer in abo ut o ne seco nd!
COLUMNS
Well, yo ur bo ss was very impressed with ho w quickly yo u were able to pro vide the info rmatio n he requested,
so he's co me directly to yo u with his next query request. It seems he is wo rried that certain co lumns in the
Pro ducts table are no t large eno ugh to ho ld all o f the data fo r a new bo o k—St e al T his Co m put e r Bo o k
4 .0 : What T he y Wo n't T e ll Yo u Abo ut t he Int e rne t . He may be right—that title is very lo ng!
To find this info rmatio n fast, we'll peek into the COLUMNS table o f INFORMATION_SCHEMA.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT column_name, data_type, character_maximum_length
-> FROM INFORMATION_SCHEMA.COLUMNS
-> WHERE table_name='Products' AND table_schema='username';
+-------------+-----------+--------------------------+
| column_name | data_type | character_maximum_length |
+-------------+-----------+--------------------------+
| ProductCode | char
|
20 |
| Title
| varchar
|
50 |
| Category
| varchar
|
30 |
| Description | text
|
65535 |
| Price
| decimal
|
NULL |
+-------------+-----------+--------------------------+
5 rows in set (1.36 sec)
mysql>
A quick visual inspectio n sho ws that the T it le co lumn may no t be lo ng eno ugh. Let's refine o ur query to
return all co lumns that aren't lo ng eno ugh to co ntain the title. To do this, we'll use the length functio n—it
returns an integer co unt o f a string's length.
Note
Be sure to include a backslash (\) befo re the apo stro phe (') in the title. The backslash "escapes"
the apo stro phe so MySQL wo n't think it's the end o f the title.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT column_name, data_type, character_maximum_length
-> FROM INFORMATION_SCHEMA.COLUMNS
-> WHERE table_name='Products'
-> AND character_maximum_length < length('Steal This Computer Book 4.0: What
They Won\'t Tell You About the Internet');
+-------------+-----------+--------------------------+
| column_name | data_type | character_maximum_length |
+-------------+-----------+--------------------------+
| ProductCode | char
|
20 |
| Title
| varchar
|
50 |
| Category
| varchar
|
30 |
+-------------+-----------+--------------------------+
3 rows in set (0.99 sec)
mysql>
The title co lumn was way to o sho rt. The Pro ductCo de and Catego ry may also need to be increased. Yo ur
bo ss is extremely happy with yo ur wo rk!
VIEWS
Later in the day yo ur bo ss sto ps by yet again. This time he is co ncerned abo ut the views being used in the
applicatio n. He wants to kno w exactly which views have been created, and which views allo w UPDATE,
DELETE, and perhaps INSERT queries. Once again yo u turn to INFORMATION_SCHEMA—this time to the
VIEWS table.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT table_name, is_updatable, view_definition
-> FROM INFORMATION_SCHEMA.VIEWS WHERE table_schema='username';
+------------------+--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| table_name
| is_updatable | view_definition
|
+------------------+--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ProductInventory | NO
| /* ALGORITHM=UNDEFINED */ select `P`.`Produc
tCode` AS `ProductCode`,`P`.`Title` AS `Title`,`P`.`Price` AS `Price`,`I`.`Quant
ityInStock` AS `Qty` from (`certjosh`.`Products` `P` left join `certjosh`.`Inven
tory` `I` on((`P`.`ProductCode` = `I`.`ProductCode`)))
|
| SalesDataPivot
| NO
| /* ALGORITHM=UNDEFINED */ select `certjosh`.
`SalesAnalysis`.`Region` AS `Region`,sum((case when (`certjosh`.`SalesAnalysis`.
`Quarter` = _latin1'2007-03-31') then `certjosh`.`SalesAnalysis`.`UnitsSold` els
e 0 end)) AS `2007-Q1`,sum((case when (`certjosh`.`SalesAnalysis`.`Quarter` = _l
atin1'2007-06-30') then `certjosh`.`SalesAnalysis`.`UnitsSold` else 0 end)) AS `
2007-Q2`,sum((case when (`certjosh`.`SalesAnalysis`.`Quarter` = _latin1'2007-0930') then `certjosh`.`SalesAnalysis`.`UnitsSold` else 0 end)) AS `2007-Q3`,sum((
case when (`certjosh`.`SalesAnalysis`.`Quarter` = _latin1'2007-12-31') then `cer
tjosh`.`SalesAnalysis`.`UnitsSold` else 0 end)) AS `2007-Q4` from `certjosh`.`Sa
lesAnalysis` group by `certjosh`.`SalesAnalysis`.`Region` |
+------------------+--------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
2 rows in set (1.02 sec)
mysql>
Yo u kno w yo u'll have to make this o utput mo re readable befo re yo u hand it o ver to yo ur bo ss. Fo rtunately, he
do esn't need to see the who le view definitio n, just the first several characters. We can use substring to skip
the first few characters and limit the descriptio n to a to tal o f 50 characters.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT table_name, is_updatable,
-> substring(view_definition,27,50) AS definition
-> FROM INFORMATION_SCHEMA.VIEWS
-> WHERE table_schema='username';
+------------------+--------------+---------------------------------------------------+
| table_name
| is_updatable | definition
|
+------------------+--------------+---------------------------------------------------+
| ProductInventory | YES
| S `ProductCode`,`P`.`Title` AS `Title`,`P`.`
Price` |
| SalesDataPivot
| NO
| lysis`.`Region` AS `Region`,sum((case when (
`smill |
+------------------+--------------+---------------------------------------------------+
2 rows in set (0.99 sec)
mysql>
That's much easier o n the eyes!
Yo u give the results to yo ur bo ss, who is still very impressed with yo ur wo rk, and pro mises to have a talk with
yo u so o n abo ut yo ur future with the co mpany.
ROUT INES
It's nearing 5:0 0 PM, and yo ur bo ss co mes by yo ur desk fo r o ne last piece o f info rmatio n. A lazy develo per
really wants to rename the "QuantityInSto ck" co lumn to "Qty" to save typing. Yo ur bo ss wants to kno w ho w
many pro cedures will have to be changed if the co lumn is renamed.
Yo u tell him yo u'll lo o k into it, and will give him an answer by the end o f the day. Fo r this task yo u'll use the
ROUTINES table fro m INFORMATION_SCHEMA. So me o f the pro cedures can be quite lo ng, so let's end o ur
query with \G to request the "lo ng" o utput fro m MySQL instead o f the "wide" o utput.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT routine_name, routine_type, routine_definition
-> FROM INFORMATION_SCHEMA.ROUTINES \G
*************************** 1. row ***************************
routine_name: CreateProduct
routine_type: PROCEDURE
routine_definition: BEGIN
insert into Products (ProductCode, Title, Category, Description, Price)
values (ProductCode, Title, Category, Description, Price);
insert into Inventory (ProductCode, QuantityInStock)
values (ProductCode, Quantity);
END
*************************** 2. row ***************************
routine_name: CurrentProductInventory
routine_type: PROCEDURE
routine_definition: BEGIN
select P.ProductCode, P.Title, P.Price, I.QuantityInStock as Qty
from Products as P
LEFT JOIN Inventory as I on (P.ProductCode = I.ProductCode);
END
2 rows in set (0.00 sec)
mysql>
Yo ur results might be slightly different, but they sho uld lo o k similar.
These are exactly the results we want. Our bo ss do esn't want to spend a lo t o f time reading thro ugh the
pro cedure definitio ns to see where "QuantityInSto ck" is being used, so we'll add a calculated co lumn to
pro vide that info rmatio n.
Type the fo llo wing at the MySQL pro mpt:
mysql> SELECT routine_name, routine_type,
-> CASE WHEN routine_definition LIKE '%QuantityInStock%' THEN 1 ELSE 0 END
->
AS Uses_QuantityInStock
-> FROM INFORMATION_SCHEMA.ROUTINES;
+-------------------------+--------------+----------------------+
| routine_name
| routine_type | Uses_QuantityInStock |
+-------------------------+--------------+----------------------+
| CreateProduct
| PROCEDURE
|
1 |
| CurrentProductInventory | PROCEDURE
|
1 |
+-------------------------+--------------+----------------------+
2 rows in set (0.00 sec)
mysql>
It lo o ks like we have so me wo rk to do if we decide to rename the co lumn, but o nce again yo u've given yo ur
bo ss the info rmatio n he needs. It might be time to ask fo r a raise!
Fo r additio nal info rmatio n o n the INFORMATION_SCHEMA tables in MySQL, check o ut MySQL's web site.
That's it! Yo u've go tten a go o d start o n yo ur database applicatio ns. But yo u pro bably do n't want to sto p no w. This co urse is just
the first in a series designed to give yo u the co nfidence and kno wledge yo u need to use databases effectively. The next lesso n
will be a descriptio n o f yo ur final pro ject. See yo u there!
Copyright © 1998-2014 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.
Final Project
Wo w! Yo u've co me a lo ng way. We've co vered a lo t, and no w it's time fo r yo u to apply yo ur new kno wledge to the final pro ject.
Final Project Specification
Yo u've do ne a go o d jo b at ATunes, and learned a lo t. In o rder to co ntinue yo ur learning, and to share tips and
experiences with databases, yo u decide to create a blo g just fo r databases. Yo u'll publish articles written by many
different peo ple, and allo w visito rs to co mment o n tho se articles.
Yo u have a friend who will make a web site fo r yo u, so the o nly aspect o f the blo g yo u'll have to wo rry abo ut is the
database. Yo u need to create all o f the database o bjects needed to suppo rt the blo g. To co mplete the pro ject, yo u'll
need to create the fo llo wing tables:
1. Art icle Aut ho rs: names, email addresses, so me bio graphical info rmatio n
2. Art icle s: title, sho rt descriptio n (blurb), article text, date (use a full text index o n the blurb)
3. Art icle Cat e go rie s: catego ries are like MySQL, Oracle, SQL Server, Queries, Sto red Pro cedures, etc.
4. Co m m e nt e rs: names, email addresses o f co mmenters
5. Co m m e nt s: No tes left by co mmenters regarding an article
6 . Art icle Vie ws: Lo gs the date and time an article was viewed
Feel free to add additio nal co lumns as yo u see necessary. Make sure yo u use appro priate data types.
After yo u create the tables, po pulate them all with sample data. Create at least five articles. Yo u do n't have to write all o f
the co ntent yo urself—test data is fine.
Note
Make sure yo u created a full text index o n the Article blurb.
Next, write a sto red pro cedure named AddCo m m e nt to add a co mment o n an article, creating an entry in
Co mmenters if it do esn't exist.
Create a view named Art icle Display that displays autho r, the article, and catego ry fo r the article. This view will be
used to display the article o n the web page.
Write the fo llo wing queries:
1. Demo nstrate the use o f the full text index o n the Articles table. One query sho uld sho w successful matches with a
ranking, ano ther query sho uld sho w no matches.
2. Pivo t ArticleViews to display the number o f times an article was viewed in the last 10 , 20 , and 30 days. The o utput
sho uld lo o k so mething like this:
OBSERVE:
Article
New Features in MySQL
Views in Oracle
D10
5
2
D20
10
4
D30
7
1
3. Write a query that sho ws the mo st po pular article—the article that has the mo st ro ws in ArticleViews.
Make sure yo u name yo ur o bjects carefully—yo ur mento r will be lo o king fo r specific names.
Sto re all o f yo ur CREATE, INSERT, and SELECT statements in a file called dba1f inalpro je ct .sql. When yo u finish
hand in this SQL file.
GOOD LUCK!
Copyright © 1998-2014 O'Reilly Media, Inc.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-sa/3.0/legalcode for more information.