1 1 CS3336a, Alex Babanski CS3336a, Alex Babanski <?php echo ...
1 1 CS3336a, Alex Babanski CS3336a, Alex Babanski <?php echo ...
1 1 CS3336a, Alex Babanski CS3336a, Alex Babanski <?php echo ...
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Database is simply a collection of data.<br />
In relational database, data is organized into tables.<br />
Student_ID Name Major Grade<br />
10145 Michael CS 95<br />
10146 Dennis PHYS 75<br />
10147 Boris MATH 89<br />
… … …<br />
Database Management System (DBMS) is a software to maintain<br />
and utilize the collections of data (Oracle, DB2, MySQL)<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Database<br />
The overall collection of data –may consist of many tables<br />
Table<br />
An individual "relation" in the relational database<br />
Relates keys to values.<br />
Table Column<br />
An attribute in the table<br />
Table Row<br />
An entity in the table<br />
Typically has a value for each column<br />
Student_ID Name Major Grade<br />
10145 Michael CS 95<br />
10146 Dennis PHYS 75<br />
10147 Boris MATH 89<br />
… … …<br />
1
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Key<br />
An attribute that uniquely identifies an entity<br />
Example: Student ID 10147 identifies student 'Boris'<br />
Foreign Key<br />
Key used to relate data in one table with data in another table<br />
Schema<br />
A description of a particular collection of data<br />
(a set of table designs that determine a database).<br />
Does not yet include the data –simply shows how it will be<br />
structured in the database<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Transaction<br />
A sequence of database actions (reads/writes).<br />
ACID Properties:<br />
Atomicity (all‐or‐nothing property)<br />
Consistency (rows affected by transaction remain consistent)<br />
Isolation (no transaction interference)<br />
Durability (committed transactions are protected against crashes)<br />
Database Engine ("Storage Engine")<br />
Is the underlying software component for storing, processing and<br />
securing data.<br />
2
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Query Optimization<br />
and Execution<br />
A typical DBMS has a layered architecture.<br />
Each database system has its own variations.<br />
Relational Operators<br />
Files and Access Methods<br />
Buffer Management<br />
Disk Space Management<br />
These layers must consider concurrency<br />
control and recovery.<br />
DB<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Relationships: how does the data in different tables relate<br />
One‐to‐One<br />
An entity in a table corresponds to a single entity in another table.<br />
The relationship is typically established using a foreign key for one or both entities.<br />
Example: If we have a table for Student_Info and a table for Academic_History,<br />
there is a one‐to‐one relationship between them.<br />
One‐to‐Many<br />
An entity in a table corresponds to 1 or more entities in another table.<br />
Example: If the table for Academic_History has an entry for each term, the relationship now<br />
becomes one student to many terms.<br />
3
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Many‐to‐Many<br />
Mu<strong>lt</strong>iple entities in one table correspond to mu<strong>lt</strong>iple entities in another table.<br />
This relationship is often defined by a separate table,<br />
which in fact changes it into 2 One-to-Many relationships<br />
Example: Tables Student_Info and Courses_Taken have a many to many relationship,<br />
since a student can take many courses and each course can be taken by many students.<br />
However, if we create a new table Student_Courses, we can have each entity be a pair:<br />
Student_Id, Course_id<br />
Now Student_Info has a one to many relationship with Student_Courses,<br />
and so does Courses_Taken<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
There is a lot of database theory about how to best create a schema:<br />
• Best modeling the data you are storing<br />
• Storing it most efficiently<br />
• Designing most efficient queries<br />
The process of organizing data to minimize redundancy is called normalization.<br />
We will talk about it later on. Check introduction:<br />
http://babanski.com/files/MySQL‐intro‐to‐database‐normalization.pdf<br />
We are concerned with the fundamentals, and for using MySQL<br />
through PHP and a Web interface.<br />
4
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
MySQL is a Database Management System.<br />
SQL stands for the Structured Query Language.<br />
It defines how to insert, retrieve, modify and delete data<br />
Most Popular open source software: http://www.mysql.com<br />
Who uses it<br />
Virtually every major company/corporation: http://www.mysql.com/why‐mysql/marketshare/<br />
• MySQL is a free and open source relational database management system.<br />
• MySQL has more than 20 million installations.<br />
• MySQL runs as a server providing mu<strong>lt</strong>i‐user access to a number of databases.<br />
• It is a cross platform database server.<br />
• Mu<strong>lt</strong>iple storage engines (MyISAM, InnoDB…)<br />
• Views creation and update<br />
• Transactions with the InnoDB Engine<br />
• Sub Queries / Nested Select<br />
• Primary key and indexing Current Versions: 5.1 (released in 2009), 5.5 (released in 2011)<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
• Create table<br />
• Insert records<br />
• Retrieve records<br />
• Update records<br />
• Delete records<br />
• Modify table<br />
• Join table<br />
• Drop table<br />
• Count, Like, Order by, Group by, limit<br />
• Optimize table<br />
• Advanced (sub‐queries, stored procedures, triggers, views …)<br />
http://dev.mysql.com/doc/refman/5.5/en/differences‐from‐ansi.html<br />
5
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
CSV<br />
The engine stores data in text files using comma‐separated values format.<br />
Memory<br />
The engine creates tables with contents that are stored in memory.<br />
MyISAM<br />
Defau<strong>lt</strong> in 5.1.<br />
Non‐transaction Engine.<br />
No transaction overhead: much faster, lower disk space requirements, less memory required to<br />
perform updates.<br />
Atomicity (all‐or‐nothing property)<br />
Consistency (rows affected by transaction remain consistent)<br />
Isolation (no transaction interference)<br />
Durability (committed transactions are protected against crashes)<br />
InnoDB<br />
Defau<strong>lt</strong> in 5.5.<br />
Transaction‐safe (ACID compliant) Engine.<br />
Safe, can combine many statements with one COMMIT, can execute ROLLBACK, row‐level locking.<br />
http://dev.mysql.com/doc/refman/5.5/en/storage‐engines.html<br />
http://dev.mysql.com/doc/refman/5.1/en/storage‐engine‐compare‐transactions.html<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
A MySQL server can store several databases.<br />
Databases are usually stored as directories (MyISAM).<br />
Tables are stored as files inside each database (directory).<br />
Defau<strong>lt</strong> location for all files: /var/lib/mysql/<br />
Each MyISAM table has three files:<br />
• table.FRM file containing information about the table structure.<br />
• table.MYD file containing the row data.<br />
• table.MYI containing any indexes belonging with this table, as well as some<br />
statistics about the table.<br />
InnoDB:<br />
Data and indexes in tablespaces. Made up of one of more datafiles.<br />
6
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
MySQL allows console access:<br />
mysql –h hostname –u username –p [password]<br />
Typical usage (localhost):<br />
shell> mysql ‐u someusername ‐p<br />
Enter password: *****<br />
Create file .my.cnf<br />
[client]<br />
user="someusername"<br />
pass="1234567"<br />
Server version: 5.xx.xxxx (Debian)<br />
Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.<br />
This software comes with ABSOLUTELY NO WARRANTY.<br />
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.<br />
mysql><br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
CREATE<br />
create databases and tables<br />
ALTER<br />
a<strong>lt</strong>er the structure of a table<br />
INSERT<br />
insert a new row in a table<br />
UPDATE<br />
update rows in a table<br />
SELECT<br />
select table rows based on certain conditions<br />
DELETE<br />
delete one or more rows of a table<br />
Data Manipulation Statements<br />
http://dev.mysql.com/doc/refman/5.5/en/sql‐syntax‐data‐manipulation.html<br />
7
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
CREATE a database:<br />
mysql> CREATE DATABASE databasename;<br />
USE a database:<br />
mysql> USE databasename;<br />
Important!! You need to have permissions to create a database.<br />
Your CS3336.com account doesn't have enough privileges to create a database.<br />
However, you can create as many tables as you want in the database given to you.<br />
For CPANEL users:<br />
In CPANEL databasename starts with login name and '_'.<br />
For instance, if your login name is csab123 then all your databases should start with csab123_<br />
‐ i.e. csab123_db , csab123_db2 , etc<br />
Keep it in mind when you create databases in shell on a server with CPANEL installed.<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
MySQL commands are NOT case‐sensitive.<br />
Often, command keywords are written in all caps, just to<br />
distinguish them from your user‐specific values such as table<br />
and column names. However, this isn’t necessary.<br />
MySQL commands have to end with a semicolon (;).<br />
If you forget this, the system will put an arrow on the next line: ‐><br />
which means it is waiting for you to finish the command.<br />
mysql> show databases<br />
‐><br />
8
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Execute Two statements,<br />
Fist statement –we need to select<br />
database 'babanski_db'<br />
Resu<strong>lt</strong><br />
http://<strong>php</strong>myadmin.cs3336.com<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
What are the current databases on the server<br />
mysql> SHOW databases;<br />
+--------------------+<br />
| Database |<br />
+--------------------+<br />
| information_schema |<br />
+--------------------+<br />
Use PHPMyAdmin SQL statements<br />
http://<strong>php</strong>myadmin.cs3336.com<br />
Create a database (make a directory):<br />
mysql> CREATE database cs3336_db;<br />
Select database to use:<br />
mysql> USE cs3336_db;<br />
Database changed<br />
Can do it as root‐privileged user only<br />
What tables are currently stored in the cs3336_db database<br />
mysql> SHOW tables;<br />
Empty set (0.00 sec)<br />
9
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Show tables in the database (select database first using 'use' command):<br />
mysql> SHOW tables;<br />
Describe structure of a table in the database:<br />
mysql> DESCRIBE tablename;<br />
mysql> use cs3336_hw4;<br />
Database changed<br />
mysql> desc countries;<br />
+-----------+------------------+------+-----+---------+-------+<br />
| Field | Type | Null | Key | Defau<strong>lt</strong> | Extra |<br />
+-----------+------------------+------+-----+---------+-------+<br />
| countryID | char(2) | NO | PRI | | |<br />
| country | varchar(200) | YES | | NULL | |<br />
| active | enum('YES','NO') | NO | | YES | |<br />
+-----------+------------------+------+-----+---------+-------+<br />
3 rows in set (0.00 sec)<br />
Select all data/records from a table:<br />
mysql> SELECT * from tablename;<br />
Use a condition clause to get a specific data/records from a table:<br />
mysql> SELECT * from students WHERE name='Boris';<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Grant access to a database:<br />
mysql> GRANT all on databasename.* to username@localhost identified by 'password';<br />
Grant limited access to a database:<br />
mysql> GRANT select, insert on databasename.* to username@localhost identified by 'password';<br />
Delete user/privileges:<br />
mysql> DROP USER 'username';<br />
Flush privileges!:<br />
mysql> FLUSH privileges;<br />
See a list of the privileges granted to a specific user:<br />
mysql> SHOW GRANTS for 'username'@'localhost';<br />
mysql> show grants for 'root'@'localhost';<br />
+----------------------------------------------------------------------------------------------------------------+<br />
| Grants for root@localhost |<br />
+----------------------------------------------------------------------------------------------------------------+<br />
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY PASSWORD '*ED1B38B………' WITH GRANT OPTION |<br />
| GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION |<br />
+----------------------------------------------------------------------------------------------------------------+<br />
2 rows in set (0.00 sec)<br />
10
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
CHAR () (size < 255 bytes)<br />
VARCHAR() (size < 255 bytes)<br />
BLOB or TEXT (size < 65,535 bytes)<br />
MEDIUMBLOB or MEDIUMTEXT (size < 16,777,215 bytes)<br />
LONGBLOB or LONGTEXT (size < 4 GB)<br />
ENUM (, ,…)<br />
TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT<br />
are integers of 1, 2, 3, 4, and 8 bytes, respectively.<br />
DECIMAL or NUMERIC(M, D)<br />
FLOAT<br />
DOUBLE<br />
DATE (defau<strong>lt</strong> format YYYY‐MM‐DD)<br />
http://dev.mysql.com/doc/refman/5.5/en/data‐types.html<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
File: table.sql<br />
DROP TABLE IF EXISTS `students`;<br />
SET character_set_client = utf8;<br />
CREATE TABLE `students` (<br />
`studentID` int unsigned NOT NULL auto_increment,<br />
`name` varchar(100) NOT NULL defau<strong>lt</strong> '',<br />
`major` varchar(50) NOT NULL defau<strong>lt</strong> '',<br />
`grade` tinyint NOT NULL defau<strong>lt</strong> '0',<br />
PRIMARY KEY (`studentID`)<br />
) ENGINE=MyISAM DEFAULT CHARSET=utf8;<br />
StudentID name major grade<br />
1 Michael CS 95<br />
10146 Dennis PHYS 75<br />
10147 Boris MATH 89<br />
… … …<br />
Import into cs3336_db database using console access:<br />
shell> mysql ‐u username ‐p < table.sql<br />
11
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
CREATE TABLE `students` (<br />
`studentID` int unsigned NOT NULL auto_increment,<br />
`name` varchar(100) NOT NULL defau<strong>lt</strong> '',<br />
`major` varchar(50) NOT NULL defau<strong>lt</strong> '',<br />
`grade` tinyint NOT NULL defau<strong>lt</strong> '0',<br />
PRIMARY KEY (`studentID`)<br />
) ENGINE=MyISAM DEFAULT CHARSET=utf8;<br />
StudentID name major grade<br />
1 Michael CS 95<br />
10146 Dennis PHYS 75<br />
10147 Boris MATH 89<br />
10148 Katya CS 0<br />
INSERT data into the table:<br />
mysql> insert into students values ('','Michael', 'CS', 95);<br />
We 'override' auto_increment<br />
mysql> insert into students values (10146,'Dennis', 'PHYS', 75);<br />
mysql> insert into students (name, major, grade) values ('Boris', 'MATH', 89);<br />
mysql> insert into students set name='Katya', major='CS';<br />
Different syntax<br />
http://dev.mysql.com/doc/refman/5.5/en/insert.html<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
CREATE TABLE `students` (<br />
`studentID` int unsigned NOT NULL auto_increment,<br />
`name` varchar(100) NOT NULL defau<strong>lt</strong> '',<br />
`major` varchar(50) NOT NULL defau<strong>lt</strong> '',<br />
`grade` tinyint NOT NULL defau<strong>lt</strong> '0',<br />
PRIMARY KEY (`studentID`)<br />
) ENGINE=MyISAM DEFAULT CHARSET=utf8;<br />
StudentID name major grade<br />
1 Michael CS 95<br />
10146 Dennis PHYS 75<br />
10147 Boris MATH 89<br />
10148 Katya CS 0<br />
SELECT all records from the table:<br />
mysql> select * from students;<br />
+-----------+---------+-------+-------+<br />
| studentID | name | major | grade |<br />
+-----------+---------+-------+-------+<br />
| 1 | Michael | CS | 95 |<br />
| 10146 | Dennis | PHYS | 75 |<br />
| 10147 | Boris | MATH | 89 |<br />
| 10148 | Katya | CS | 0 |<br />
+-----------+---------+-------+-------+<br />
http://dev.mysql.com/doc/refman/5.5/en/select.html<br />
Use \G modifier for many‐column data:<br />
mysql> select * from students\G;<br />
*************************** 1. row ***************************<br />
studentID: 1<br />
name: Michael<br />
major: CS<br />
grade: 95<br />
*************************** 2. row ***************************<br />
studentID: 10146<br />
name: Dennis<br />
major: PHYS<br />
grade: 75<br />
*************************** 3. row ***************************<br />
studentID: 10147<br />
name: Boris<br />
major: MATH<br />
grade: 89<br />
*************************** 4. row ***************************<br />
studentID: 10148<br />
name: Katya<br />
major: CS<br />
grade: 0<br />
12
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
CREATE TABLE `students` (<br />
`studentID` int unsigned NOT NULL auto_increment,<br />
`name` varchar(100) NOT NULL defau<strong>lt</strong> '',<br />
`major` varchar(50) NOT NULL defau<strong>lt</strong> '',<br />
`grade` tinyint NOT NULL defau<strong>lt</strong> '0',<br />
PRIMARY KEY (`studentID`)<br />
) ENGINE=MyISAM DEFAULT CHARSET=utf8;<br />
StudentID name major grade<br />
1 Michael CS 95<br />
10146 Dennis PHYS 75<br />
10147 Boris MATH 89<br />
10148 Katya CS 0<br />
SELECT specific data/columns from the table:<br />
mysql> select studentID, name from students;<br />
+-----------+---------+<br />
| studentID | name |<br />
+-----------+---------+<br />
| 1 | Michael |<br />
| 10146 | Dennis |<br />
| 10147 | Boris |<br />
| 10148 | Katya |<br />
+-----------+---------+<br />
http://dev.mysql.com/doc/refman/5.5/en/select.html<br />
Important!<br />
Always select only data you need!<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
CREATE TABLE `students` (<br />
`studentID` int unsigned NOT NULL auto_increment,<br />
`name` varchar(100) NOT NULL defau<strong>lt</strong> '',<br />
`major` varchar(50) NOT NULL defau<strong>lt</strong> '',<br />
`grade` tinyint NOT NULL defau<strong>lt</strong> '0',<br />
PRIMARY KEY (`studentID`)<br />
) ENGINE=MyISAM DEFAULT CHARSET=utf8;<br />
StudentID name major grade<br />
1 Michael CS 95<br />
10146 Dennis PHYS 75<br />
10147 Boris MATH 89<br />
10148 Katya CS 0<br />
SELECT specific data from the table and limit output:<br />
mysql> select studentID, name from students limit 2;<br />
+-----------+---------+<br />
| studentID | name |<br />
+-----------+---------+<br />
| 1 | Michael |<br />
| 10146 | Dennis |<br />
+-----------+---------+<br />
Important to create 'pages' with records<br />
Syntax: limit offset, row_count<br />
limit 2 is equivalent to limit 0, 2<br />
http://dev.mysql.com/doc/refman/5.5/en/select.html<br />
13
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
CREATE TABLE `students` (<br />
`studentID` int unsigned NOT NULL auto_increment,<br />
`name` varchar(100) NOT NULL defau<strong>lt</strong> '',<br />
`major` varchar(50) NOT NULL defau<strong>lt</strong> '',<br />
`grade` tinyint NOT NULL defau<strong>lt</strong> '0',<br />
PRIMARY KEY (`studentID`)<br />
) ENGINE=MyISAM DEFAULT CHARSET=utf8;<br />
StudentID name major grade<br />
1 Michael CS 95<br />
10146 Dennis PHYS 75<br />
10147 Boris MATH 89<br />
10148 Katya CS 0<br />
SELECT specific data from the table with WHERE clause:<br />
mysql> select name, major, grade from students where major='cs';<br />
mysql> select name, major, grade from students where major='c%';<br />
+---------+-------+-------+<br />
| name | major | grade |<br />
+---------+-------+-------+<br />
| Michael | CS | 95 |<br />
| Katya | CS | 0 |<br />
+---------+-------+-------+<br />
http://dev.mysql.com/doc/refman/5.5/en/select.html<br />
Question: Is anything wrong with my select<br />
Check Case‐Sensitivity issue!<br />
http://dev.mysql.com/doc/refman/5.0/en/case‐sensitivity.html<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
CREATE TABLE `students` (<br />
`studentID` int unsigned NOT NULL auto_increment,<br />
`name` varchar(100) NOT NULL defau<strong>lt</strong> '',<br />
`major` varchar(50) NOT NULL defau<strong>lt</strong> '',<br />
`grade` tinyint NOT NULL defau<strong>lt</strong> '0',<br />
PRIMARY KEY (`studentID`)<br />
) ENGINE=MyISAM DEFAULT CHARSET=utf8;<br />
StudentID name major grade<br />
1 Michael CS 95<br />
10146 Dennis PHYS 75<br />
10147 Boris MATH 89<br />
10148 Katya CS 0<br />
More examples of WHERE clause:<br />
mysql> select * from students where grade>75;<br />
mysql> select name, grade from students where major in ('CS', 'phys');<br />
mysql> select * from students where name='michael' and major='cs';<br />
mysql> select studentID from students where name='dennis' or major='cs';<br />
http://dev.mysql.com/doc/refman/5.5/en/select.html<br />
14
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
CREATE TABLE `students` (<br />
`studentID` int unsigned NOT NULL auto_increment,<br />
`name` varchar(100) NOT NULL defau<strong>lt</strong> '',<br />
`major` varchar(50) NOT NULL defau<strong>lt</strong> '',<br />
`grade` tinyint NOT NULL defau<strong>lt</strong> '0',<br />
PRIMARY KEY (`studentID`)<br />
) ENGINE=MyISAM DEFAULT CHARSET=utf8;<br />
StudentID name major grade<br />
1 Michael CS 95<br />
10146 Dennis PHYS 75<br />
10147 Boris MATH 89<br />
10148 Katya CS 0<br />
SELECT and ORDER data from the table:<br />
mysql> select * from students order by grade asc;<br />
mysql> select * from students order by grade asc, name desc;<br />
+-----------+---------+-------+-------+<br />
| studentID | name | major | grade |<br />
+-----------+---------+-------+-------+<br />
| 10148 | Katya | CS | 0 |<br />
| 10146 | Dennis | PHYS | 75 |<br />
| 10147 | Boris | MATH | 89 |<br />
| 1 | Michael | CS | 95 |<br />
+-----------+---------+-------+-------+<br />
http://dev.mysql.com/doc/refman/5.5/en/select.html<br />
Secondary rule<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
CREATE TABLE `students` (<br />
`studentID` int unsigned NOT NULL auto_increment,<br />
`name` varchar(100) NOT NULL defau<strong>lt</strong> '',<br />
`major` varchar(50) NOT NULL defau<strong>lt</strong> '',<br />
`grade` tinyint NOT NULL defau<strong>lt</strong> '0',<br />
PRIMARY KEY (`studentID`)<br />
) ENGINE=MyISAM DEFAULT CHARSET=utf8;<br />
StudentID name major grade<br />
1 Michael CS 95<br />
10146 Dennis PHYS 75<br />
10147 Boris MATH 89<br />
10148 Katya CS 0<br />
SELECT , ORDER and apply WHERE clause to the data:<br />
mysql> select * from students where grade>75 order by grade asc;<br />
+-----------+---------+-------+-------+<br />
| studentID | name | major | grade |<br />
+-----------+---------+-------+-------+<br />
| 10147 | Boris | MATH | 89 |<br />
| 1 | Michael | CS | 95 |<br />
+-----------+---------+-------+-------+<br />
http://dev.mysql.com/doc/refman/5.5/en/select.html<br />
15
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
How many students have the same major<br />
StudentID name major grade<br />
1 Michael CS 95<br />
10146 Dennis PHYS 75<br />
10147 Boris MATH 89<br />
10148 Katya CS 0<br />
mysql> select major, count(*) as size from students;<br />
mysql> select major, count(*) as size from students ORDER BY major asc;<br />
Not what we expected!!!<br />
+-------+------+<br />
| major | size |<br />
+-------+------+<br />
| CS | 4 |<br />
+-------+------+<br />
mysql> select major, count(*) as size from students GROUP BY major asc;<br />
+-------+------+<br />
| major | size |<br />
+-------+------+<br />
| CS | 2 |<br />
| MATH | 1 |<br />
| PHYS | 1 |<br />
+-------+------+<br />
Use in conjunction with aggregate functions<br />
http://dev.mysql.com/doc/refman/5.5/en/group‐by‐functions.html<br />
http://dev.mysql.com/doc/refman/5.5/en/group‐by‐functions‐and‐modifiers.html<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
UPDATE data in the table:<br />
StudentID name major grade<br />
1 Michael CS 95<br />
10146 Dennis PHYS 75<br />
10147 Boris MATH 89<br />
10148 Katya CS 0<br />
mysql> update students set grade='65';<br />
mysql> update students set grade='65' where grade>75;<br />
mysql> update students set grade='65' where name='Boris';<br />
mysql> update students set grade='65' where studentID='10147';<br />
mysql> update students set grade='65', major='CS' where studentID='10147';<br />
DELETE data from the table:<br />
mysql> delete from students;<br />
mysql> delete from students where studentID='10147';<br />
mysql> delete from students where studentID'10147';<br />
http://dev.mysql.com/doc/refman/5.5/en/update.html<br />
http://dev.mysql.com/doc/refman/5.5/en/delete.html<br />
16
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
http://dev.mysql.com/doc/refman/5.5/en/functions.html<br />
mysql> select 1+1 as sumoftwo;<br />
+----------+<br />
| sumoftwo |<br />
+----------+<br />
| 2 |<br />
+----------+<br />
mysql> select IF (1 select now() as currentTime;<br />
+---------------------+<br />
| currentTime |<br />
+---------------------+<br />
| 2012-11-16 03:39:35 |<br />
+---------------------+<br />
mysql> select concat_ws('‐', 'Go', 'Canada');<br />
+--------------------------------+<br />
| concat_ws('-', 'Go', 'Canada') |<br />
+--------------------------------+<br />
| Go-Canada |<br />
+--------------------------------+<br />
Operators, Control Flow functions, String Functions, Date and Time Functions<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
MySQL has many functions available to a<strong>lt</strong>er or format the data stored in tables.<br />
When using a MySQL function specify a column name.<br />
Functions are:<br />
• case insensitive<br />
• no space between function name and parentheses<br />
Typical syntax:<br />
Add extra clauses if needed<br />
(WHERE, ORDER BY, etc)<br />
SELECT FUNCTION( columnName ) FROM tableName;<br />
SELECT column1, FUNCTION( column2 ), column3 FROM tableName;<br />
http://dev.mysql.com/doc/refman/5.5/en/functions.html<br />
17
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Name<br />
=<br />
Description<br />
http://dev.mysql.com/doc/refman/5.5/en/non‐typed‐operators.html<br />
Equal operator or Assign a value (as part of a SET statement, or as<br />
part of the SET clause in an UPDATE statement)<br />
:= Assign a value<br />
BETWEEN ... AND ...<br />
Check whether a value is within a range of values<br />
& , ^, |, >>, , = ,
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Function Usage Purpose<br />
CONCAT() CONCAT(x,y,…) Creates a new string of the form xy<br />
CONCAT_WS() CONCAT_WS(separator,x,y) Creates a new strung with separator<br />
CONV() CONV(n, base, to_base) Converts numbers between diff base<br />
TRIM() TRIM(column) Trims space from the beginning and end.<br />
UPPER() UPPER(str) Capitalizes the string<br />
LOWER() LOWER(str) Makes a string lowercase<br />
SUBSTR() SUBSTR(str, pos, len) Returns a substring<br />
LENGTH() LENGTH(str) Returns string length<br />
http://dev.mysql.com/doc/refman/5.5/en/string‐functions.html<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Function Usage Purpose<br />
DAY() / MONTH() DAY(date) / MONTH(date) Returns day/month of the date<br />
CURTIME() CURTIME() Returns the current time<br />
CURDATE() CURDATE() Returns the current date<br />
NOW() NOW() Returns the current date and time<br />
UNIX_TIMESTAMP() UNIX_TIMESTAMP() Returns seconds since 1970‐01‐01<br />
DATE_ADD() DATE_ADD(date, expr) Returns date adjusted by expr<br />
DATE_SUB() DATE_SUB(date,expr) Returns date adjusted by expr<br />
TO_DAYS() TO_DAYS(date) Returns number of days since year 0.<br />
MySQL Defau<strong>lt</strong> Datetime format is: 'YYYY‐MM‐DD HH:MM:SS'<br />
http://dev.mysql.com/doc/refman/5.5/en/date‐and‐time‐functions.html<br />
MySQL uses what is known as a proleptic Gregorian calendar.<br />
19
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Other Important Functions:<br />
• Control Flow Functions:<br />
IF(), IFNULL(), NULLIF(), etc<br />
• Information Functions:<br />
FOUND_ROWS(), LAST_INSERT_ID(), etc<br />
• Encryption and Compression Functions:<br />
AES_DECRYPT(), AES_ENCRYPT(), MD5(), ENCODE(), etc<br />
• XML Functions:<br />
ExtractValue(), UpdateXML()<br />
• Functions and Modifiers for GROUP BY clauses:<br />
COUNT(), SUM(), MAX(), MIN()<br />
http://dev.mysql.com/doc/refman/5.5/en/functions.html<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
• Functions and Modifiers for GROUP BY clauses:<br />
COUNT()<br />
‐ Returns the number of matching entries<br />
SUM()<br />
‐ Returns the sum of matching values<br />
MAX() / MIN() ‐ Returns maximum/minimum value of a group<br />
StudentID name major grade<br />
1 Michael CS 95<br />
10146 Dennis PHYS 75<br />
10147 Boris MATH 89<br />
10148 Katya CS 0<br />
mysql> select MAX(grade) from students;<br />
+------------+<br />
| MAX(grade) |<br />
+------------+<br />
| 95 |<br />
+------------+<br />
mysql> select MAX(grade) from students GROUP BY major;<br />
+------------+<br />
| MAX(grade) |<br />
+------------+<br />
| 95 |<br />
| 89 |<br />
| 75 |<br />
+------------+<br />
http://dev.mysql.com/doc/refman/5.5/en/group‐by‐functions‐and‐modifiers.html<br />
20
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
MySQL supports a number of date and time column formats:<br />
DATE<br />
‐ Stores a date value in the form YYYY‐MM‐DD.<br />
For example 2008‐10‐23.<br />
DATETIME<br />
‐ Stores a date and time value of the form YYYY‐MM‐DD HH:MM:SS.<br />
For example 2008‐10‐23 10:37:22.<br />
The supported range is 1000‐01‐01 00:00:00 to 9999‐12‐31 23:59:59<br />
TIMESTAMP<br />
‐ Similar to DATETIME. The main difference is that it's tied to a time zone.<br />
If you change time_zone on a server then you change TIMESTAMP value.<br />
The supported range is 1970‐01‐01 00:00:00 UTC to 2038‐01‐03 03:14:07 UTC<br />
Acceptable (relaxed) values of date/time:<br />
YYYYMMDDHHMMSS ; YYYY/MM/DD HH*MM*SS; YYYYMMDD ; YYMMDD ; YYYY/MM/DD<br />
For example, '20070523091528' and '070523091528' are interpreted as '2007‐05‐23 09:15:28',<br />
but '071122129015' is illegal (it has a nonsensical minute part) and becomes '0000‐00‐00 00:00:00'.<br />
http://dev.mysql.com/doc/refman/5.5/en/date‐and‐time‐literals.html<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Automatic Initialization and Updating of TIMESTAMP:<br />
http://dev.mysql.com/doc/refman/5.5/en/timestamp‐initialization.html<br />
One TIMESTAMP column in a table can have the current timestamp as the defau<strong>lt</strong> value for initializing the<br />
column, as the auto‐update value, or both.<br />
CREATE TABLE t1 (<br />
ts TIMESTAMP DEFAULT 0<br />
);<br />
The defau<strong>lt</strong> is the given value.<br />
In this case, the column has no automatic properties at all.<br />
CREATE TABLE t1 (<br />
ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP<br />
);<br />
The defau<strong>lt</strong> is the current timestamp.<br />
Column is not automatically updated to the current timestamp.<br />
CREATE TABLE t1 (<br />
ts TIMESTAMP DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP<br />
);<br />
Can be NULL<br />
CREATE TABLE t1 (<br />
ts TIMESTAMP<br />
);<br />
Equivalent to:<br />
ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP<br />
The column is automatically updated to the current<br />
timestamp and has the given constant defau<strong>lt</strong> value.<br />
The column has the current timestamp for its defau<strong>lt</strong> value and is<br />
automatically updated to the current timestamp.<br />
21
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Tutorial on MySQL Date and Time Functions:<br />
http://www.t<strong>echo</strong>topia.com/index.<strong>php</strong>/Working_with_Dates_and_Times_in_MySQL<br />
http://dev.mysql.com/doc/refman/5.5/en/date‐and‐time‐functions.html<br />
Most MySQL indexes (PRIMARY KEY, UNIQUE, INDEX, andFULLTEXT) are stored in B-trees.<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
The whole point of using a database, as opposed to a flat file, is to speed up searches.<br />
One way to markedly increase search speed is to make an index based on your most<br />
common search criteria.<br />
Index is a Data structure that improves the speed of data retrieval from a database table<br />
at the cost of slower writes and increased storage space.<br />
http://dev.mysql.com/doc/refman/5.5/en/optimization‐indexes.html<br />
MySQL indexes: PRIMARY KEY, UNIQUE, INDEX, and FULLTEXT<br />
MySQL uses indexes for these operations:<br />
• To find the rows matching a WHERE clause quickly.<br />
• To eliminate rows from consideration.<br />
• To retrieve rows from other tables when performing joins.<br />
• To find the MIN() or MAX() value for a specific indexed column.<br />
• To sort or group a table.<br />
• In some cases, a query can be optimized to retrieve values without consu<strong>lt</strong>ing the data rows.<br />
22
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
UNIQUE Index (constraint)<br />
All values in the index must be distinct.<br />
An error occurs if you try to add a new row with a key value that matches an existing row.<br />
It permits mu<strong>lt</strong>iple NULL values for columns that can contain NULL.<br />
PRIMARY KEY<br />
Is a unique index (can be mu<strong>lt</strong>i‐column) where all key columns must be defined as NOT NULL.<br />
A table can have only one PRIMARY KEY.<br />
When table is created, an index based on the primary key is automatically constructed.<br />
In the created table, a PRIMARY KEY is placed first, followed by all UNIQUE indexes, and<br />
then the non‐unique indexes.<br />
Primary Key uniquely identifies the rest of the data in any given row.<br />
Example: Social Insurance Number<br />
In InnoDB tables, keep the PRIMARY KEY short to minimize storage overhead for secondary indexes.<br />
Each secondary index entry contains a copy of the primary key.<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Foreign Keys<br />
If a table has many columns, and you query many different combinations of columns, it<br />
might be efficient to split the less‐frequently used data into separate tables with a few<br />
columns each, and relate them back to the main table by duplicating the numeric ID column<br />
from the main table. That way, each small table can have a primary key for fast lookups of its<br />
data, and you can query just the set of columns that you need using a join operation.<br />
Column Indexes / Mu<strong>lt</strong>iple‐Column Indexes<br />
The most common type of index involves a single column, storing copies of the values from<br />
that column in a data structure, allowing fast lookups for the rows with the corresponding<br />
column values.<br />
A mu<strong>lt</strong>iple‐column index can be considered a sorted array. MySQL can use mu<strong>lt</strong>iple‐column<br />
indexes for queries that test all the columns in the index, or queries that test just the first<br />
column, the first two columns, the first three columns, and so on.<br />
23
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Create an Index<br />
• A column contains a wide rage of values,<br />
many NULL values.<br />
• Columns frequently used in a WHERE clause.<br />
• To retrieve rows < 2~4 % of the total rows<br />
Do NOT Create an Index<br />
• Small table<br />
• Rarely used columns<br />
• To retrieve rows > 2~4 % of the total rows<br />
• Frequently updated table.<br />
An index is made from one or more columns, using the syntax<br />
CREATE INDEX index_name ON table_name (column_name1, column_name2, ...)<br />
Confirm Indexes:<br />
mysql> SHOW INDEX from students;<br />
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+<br />
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type |<br />
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+<br />
| students | 0 | PRIMARY | 1 | studentID | A | 4 | NULL | NULL | | BTREE |<br />
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
mysql> EXPLAIN [EXTENDED] SELECT ………<br />
To obtain information about how MySQL executes a SELECT statement.<br />
Information from the optimizer about the query execution plan.<br />
mysql> explain extended select * from students;<br />
+----+-------------+----------+------+---------------+------+---------+------+------+----------+-------+<br />
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | fi<strong>lt</strong>ered | Extra |<br />
+----+-------------+----------+------+---------------+------+---------+------+------+----------+-------+<br />
| 1 | SIMPLE | students | ALL | NULL | NULL | NULL | NULL | 4 | 100.00 | |<br />
+----+-------------+----------+------+---------------+------+---------+------+------+----------+-------+<br />
To show overall estimated cost of query:<br />
mysql> SHOW SESSION STATUS LIKE 'Last_query_cost';<br />
+-----------------+----------+<br />
| Variable_name | Value |<br />
+-----------------+----------+<br />
| Last_query_cost | 0.000000 |<br />
+-----------------+----------+<br />
24
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
MySQL and Client/Server Model:<br />
PHP<br />
Script<br />
Local<br />
Recources<br />
MySQL<br />
Server<br />
MySQL<br />
Server<br />
Remote<br />
Resources<br />
Before you can access a database, a connection to the database must be created.<br />
The interaction with MySQL server consists of the following steps:<br />
• Connect to MySQL server (requires a username and password).<br />
• Select the active database ('use database' analog).<br />
• Perform SQL queries and retrieve resu<strong>lt</strong>s.<br />
• Free Resu<strong>lt</strong>s<br />
• Close connection to MySQL (not needed unless you are using persistent connections)<br />
http://www.<strong>php</strong>.net/manual/en/set.mysqlinfo.<strong>php</strong><br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Connection<br />
$db_link = mysql_connect("localhost", "dbuser", "dbpass");<br />
If ($db_link == false)<br />
die("Could not connect: ". mysql_error());<br />
Database selection:<br />
mysql_select_db("CS3336_db", $db_link) or die("Could not select database:" . mysql_error());<br />
Perform a query:<br />
$query = "SELECT name, major from students where studentID='10147'";<br />
$resu<strong>lt</strong> = mysql_query($query, $db_link);<br />
If (!$resu<strong>lt</strong>) {<br />
<strong>echo</strong> "Could not perform insert: ". mysql_error(); }<br />
else {<br />
$studentID = mysql_insert_id($db_link);<br />
}<br />
mysql_free_resu<strong>lt</strong>($resu<strong>lt</strong>); // Free Resu<strong>lt</strong><br />
StudentID name major grade<br />
1 Michael CS 95<br />
10146 Dennis PHYS 75<br />
10147 Boris MATH 89<br />
10148 Katya CS 0<br />
mysql_close($db_link);<br />
// Close Connection<br />
http://www.<strong>php</strong>.net/manual/en/set.mysqlinfo.<strong>php</strong><br />
25
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Connection<br />
$db_link = mysql_connect("localhost", "dbuser", "dbpass");<br />
If ($db_link == false)<br />
die("Could not connect: ". mysql_error());<br />
Database selection:<br />
mysql_select_db("CS3336_db", $db_link) or die("Could not select database:" . mysql_error());<br />
Processing Mu<strong>lt</strong>iple Records:<br />
$resu<strong>lt</strong> = @mysql_query('Select name, grade as gr FROM students');<br />
while ($row = mysql_fetch_array($resu<strong>lt</strong>)) {<br />
$name=$row['name'];<br />
$grade=$row['gr'];<br />
<strong>echo</strong> "$name $grade" .'';<br />
}<br />
StudentID name major grade<br />
1 Michael CS 95<br />
10146 Dennis PHYS 75<br />
10147 Boris MATH 89<br />
10148 Katya CS 0<br />
There are a number of ways for retrieving the resu<strong>lt</strong>s of a query. The most commonly used are:<br />
• mysql_fetch_assoc() returns an associative array where the keys are the record field names.<br />
• mysql_fetch_object() returns a record as an object. There are object attributes for each record field.<br />
http://www.<strong>php</strong>.net/manual/en/set.mysqlinfo.<strong>php</strong><br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
SQL Injection –Trust NO One!<br />
Usually you would get the data that you put in your database from the user.<br />
Make sure that the data will not break your SQL queries. (SQL Injection)<br />
$sql=" SELECT * FROM students WHERE name = '$badName' "<br />
// What happens when you pass $badName === " ' OR 1;' "<br />
$sql=" SELECT * FROM students WHERE name = '' OR 1;'' "<br />
Always executes!<br />
//What about $badName==" '; DELETE FROM students where 1 or name=' "<br />
mysql_real_escape_string()<br />
a useful function for escaping characters before using a string in an SQL query.<br />
26
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
function prepare_insert_sql (& $sql_arr) {<br />
$sql_fields = implode ( ',', array_keys ( $sql_arr ) );<br />
$sql_values = implode ( ',', array_map ( 'escape_string', array_values ( $sql_arr ) ) );<br />
return "({$sql_fields}) values ({$sql_values})";<br />
}<br />
Recall INSERT syntax:<br />
insert into students (name, major, grade) values ('Boris', 'MATH', 89)<br />
function prepare_update_sql (& $sql_arr) {<br />
$arr=array();<br />
foreach($sql_arr as $key=>$value) {<br />
$arr[]= $key .'='.escape_string($value);<br />
}<br />
return implode(', ', array_values($arr));<br />
}<br />
$sql_arr= array (<br />
'name'=>'Boris',<br />
'major'=>'Math',<br />
grade=>'89'<br />
);<br />
Recall UPDATE syntax:<br />
update students set name='Boris', major='MATH', grade='89'<br />
function escape_string($str) {<br />
return "'" . mysql_real_escape_string($str) . "'";<br />
}<br />
Any Problems<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
function add_record(&$HTML) {<br />
$users_arr=array();<br />
$keys='name,major,grade';<br />
foreach( explode(',',$keys) as $index => $key ) {<br />
$users_arr[$key]=$HTML[$key];<br />
}<br />
$HTML= array (<br />
'name'=>'Boris',<br />
'major'=>'Math',<br />
grade=>'89',<br />
phone=>'….',<br />
e‐mail=>'something'<br />
);<br />
$resu<strong>lt</strong> = @mysql_query('INSERT INTO table ' . prepare_insert_sql($users_arr));<br />
if ($resu<strong>lt</strong>) {<br />
$user_id=mysql_insert_id();<br />
@mysql_free_resu<strong>lt</strong>($resu<strong>lt</strong>);<br />
}<br />
…………<br />
}<br />
return $user_id;<br />
27
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Sometimes you have 100+ records that you need to show on more than 1 page<br />
mysql> select count(studentID) as total_records from students;<br />
+---------------+<br />
| total_records |<br />
+---------------+<br />
| 4 |<br />
+---------------+<br />
In PHP get SQL records for a specific page number $page with $max_list records per page:<br />
list($total_records) = mysql_fetch_row(@mysql_query('select count(studentID) as ……'));<br />
$total_pages = ceil($total_records / $max_list);<br />
$start = ($page‐1) * $max_list;<br />
$sql_query .= " LIMIT $start, $max_list";<br />
Note: this is faster than using MySQL SQL_CALC_FOUND_ROWS and FOUND_ROWS()<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
The MySQLi extension provides various benefits with respect to its predecessor.<br />
It supports all the latest features in MySQL server 4.1 or higher.<br />
Major features:<br />
• An object‐oriented interface<br />
• Procedural interface (all the function names begin with mysqli_ instead of mysql_)<br />
• Support for the full feature set of the MySQL c‐client library<br />
• Support for prepared statements<br />
• Support for mu<strong>lt</strong>iple statements<br />
• Support for transactions<br />
• Enhanced debugging support<br />
• Embedded server support<br />
Advantages:<br />
• Maintainable<br />
• Similar Syntax<br />
• New Interface<br />
• Advanced Options<br />
• Speed<br />
• Security<br />
http://www.<strong>php</strong>.net/manual/en/book.mysqli.<strong>php</strong><br />
28
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
MySQLi: Dual Procedural and Object‐Oriented interface<br />
connect_errno) {<br />
<strong>echo</strong> "Failed to connect to MySQL: " . $mysqli‐>connect_error;<br />
exit;<br />
}<br />
If ( $resu<strong>lt</strong> = $mysqli‐>query("SELECT name, major from students where studentID='10147'") ) {<br />
$row = $resu<strong>lt</strong>‐>fetch_assoc();<br />
<strong>echo</strong> $row['name'];<br />
$resu<strong>lt</strong>‐>close();<br />
}<br />
><br />
http://<strong>php</strong>.net/manual/en/mysqli.quickstart.dual‐interface.<strong>php</strong><br />
// close database connection<br />
mysqli_close($mysqli);<br />
// close database connection<br />
$mysqli‐>close();<br />
else {<br />
<strong>echo</strong> mysqli_error();<br />
}<br />
else {<br />
<strong>echo</strong> mysqli‐>error;<br />
}<br />
MySQLi: Prepared Statements<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Using this new feature, available in MySQLi, it is possible to create queries that are:<br />
• More secure<br />
• Have better performance<br />
• More convenient to write<br />
Two types of Prepared Statements:<br />
• Bound Parameter<br />
• Bound Resu<strong>lt</strong><br />
The '' placeholders can be used in most places that could have literal data.<br />
A query could be transformed from:<br />
SELECT name, major FROM students WHERE studentID = '10147';<br />
to:<br />
SELECT name, major FROM students WHERE studentID = ;<br />
http://www.<strong>php</strong>.net/manual/en/mysqli.quickstart.prepared‐statements.<strong>php</strong><br />
No quotes around ''<br />
29
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Bound Parameter Prepared Statements<br />
• A Query template is created and sent to the MySQL server<br />
• MySQL server validates it, stores it and returns a special handle for future use<br />
• When a query needs to be executed, data to fill in the template is sent to the server<br />
• A complete query is formed and then executed<br />
Advantages<br />
• The body of the query is sent only once, later only data to fill in are sent<br />
• Most of the work required to validate and parse the query only needs to be done a single<br />
time, instead of each time the query is executed.<br />
• The data for the query does not need to be passed through a function like<br />
mysql_real_escape_string()<br />
to ensure that no SQL injection attacks occur. Instead, the sent data is handled safely by<br />
server when it is combined with the prepared statement.<br />
http://www.<strong>php</strong>.net/manual/en/mysqli.quickstart.prepared‐statements.<strong>php</strong><br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Example 1:<br />
$stmt = $mysqli‐>stmt_init(); // create a prepared statement<br />
if( $stmt = $mysqli‐>prepare("INSERT INTO students VALUES ('', , , )") ){<br />
$name ='Boris';<br />
$major ='MATH'; Parameters to be passed by reference<br />
$grade = 89;<br />
$stmt‐>bind_param('ssi', $name, $major, $grade);<br />
StudentID name major grade<br />
10147 Boris MATH 89<br />
}<br />
/* execute prepared statement */<br />
$stmt‐>execute();<br />
<strong>echo</strong> $stmt‐>affected_rows. " row inserted.\n";<br />
/* a<strong>lt</strong>ernative output */<br />
printf("%d row inserted.\n", $stmt‐>affected_rows);<br />
/* close statement and connection */<br />
$stmt‐>close();<br />
BIND Type<br />
i<br />
d<br />
b<br />
s<br />
COLUMN Type<br />
All INT types<br />
DOUBLE and FLOAT<br />
BLOBs<br />
All other types<br />
http://www.<strong>php</strong>.net/manual/en/mysqli.quickstart.prepared‐statements.<strong>php</strong><br />
http://www.<strong>php</strong>.net/manual/en/mysqli‐stmt.bind‐param.<strong>php</strong><br />
30
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Example 2:<br />
$stmt = $mysqli‐>stmt_init();<br />
if( $stmt = $mysqli‐>prepare("SELECT name, grade FROM students where studentID =") ){<br />
$IDs= array('10147', '10148');<br />
$stmt‐>bind_param('i', $studentID);<br />
}<br />
foreach($IDs as $studentID) {<br />
/* execute prepared statement */<br />
$stmt‐>execute();<br />
$resu<strong>lt</strong>= $stmt‐>get_resu<strong>lt</strong>();<br />
/* fetch values: */<br />
while ($row = $resu<strong>lt</strong>‐>fetch_assoc()) {<br />
printf ("Name: %s , Grade: %d ', $row['name'], $row['grade']);<br />
}<br />
}<br />
/* close statement and connection */<br />
Can we simplify this<br />
$stmt‐>close();<br />
http://www.<strong>php</strong>.net/manual/en/mysqli.quickstart.prepared‐statements.<strong>php</strong><br />
http://www.<strong>php</strong>.net/manual/en/mysqli‐stmt.bind‐param.<strong>php</strong><br />
StudentID name major Grade<br />
10147 Boris MATH 89<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Bound Resu<strong>lt</strong> Prepared Statements<br />
• Allow the value of variables in a PHP script to be tied to the value of fields of data in a<br />
query resu<strong>lt</strong> set.<br />
• Create a query<br />
• Prepare the query<br />
• Ask the MySQL server to execute the query<br />
• Bind PHP variables to columns in the query resu<strong>lt</strong><br />
• Request that a new row of data be loaded into the bound variables.<br />
It is possible to use bound parameters and bound resu<strong>lt</strong>s together in a single prepared statement.<br />
http://www.<strong>php</strong>.net/manual/en/mysqli.quickstart.prepared‐statements.<strong>php</strong><br />
31
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Example:<br />
$stmt = $mysqli‐>stmt_init();<br />
if( $stmt = $mysqli‐>prepare("SELECT name, grade from students limit 5") ){<br />
/* execute prepared statement */<br />
$stmt‐>execute();<br />
StudentID name major grade<br />
10147 Boris MATH 89<br />
/* bind variables to prepared statement */<br />
$stmt‐>bind_resu<strong>lt</strong>($name, $grade);<br />
/* fetch values: */<br />
while ($stmt‐>fetch()) {<br />
printf ("Name: %s , Grade: %d ', $name, $grade);<br />
}<br />
}<br />
/* close statement and connection */<br />
$stmt‐>close();<br />
http://www.<strong>php</strong>.net/manual/en/mysqli.quickstart.prepared‐statements.<strong>php</strong><br />
http://www.<strong>php</strong>.net/manual/en/mysqli‐stmt.bind‐param.<strong>php</strong><br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Using Bound Parameters and Bound Resu<strong>lt</strong>s together:<br />
$stmt = $mysqli‐>stmt_init(); // create a prepared statement<br />
if( $stmt = $mysqli‐>prepare("SELECT name, grade FROM students where major =") ){<br />
$major ='MATH';<br />
$stmt‐>bind_param('s', $major);<br />
$stmt‐>execute();<br />
/* bind variables to prepared statement */<br />
$stmt‐>bind_resu<strong>lt</strong>($name, $grade);<br />
/* fetch values: */<br />
while ($stmt‐>fetch()) {<br />
printf ("Name: %s , Grade: %d ', $name, $grade);<br />
}<br />
StudentID name major grade<br />
10147 Boris MATH 89<br />
}<br />
/* close statement and connection */<br />
$stmt‐>close();<br />
http://www.<strong>php</strong>.net/manual/en/book.mysqli.<strong>php</strong><br />
32
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Persistent connections are links that do not close when the execution of your script ends.<br />
When a persistent connection is requested, PHP checks if there's already an identical persistent<br />
connection (that remained open from earlier) ‐ and if it exists, it uses it.<br />
To use in PHP: mysql_pconnect(…) , mysqli_connect("p:example.com", ….)<br />
In reality, persistent connections are evil !<br />
1) they can be left in unpredictable states by clients. For example, a table lock might be activated before<br />
a client terminates unexpectedly. A new client process reusing this persistent connection will get the<br />
connection "as is".<br />
2) In PHP is used as a 'CGI' wrapper, an instance of the PHP interpreter is created and destroyed for every<br />
PHP page. Because it is destroyed after every request, any resources that it acquires (such as a link to<br />
an SQL database server) are closed when it is destroyed. Hence, persistent connections don't persist.<br />
3) In mu<strong>lt</strong>i‐process environment if the same client makes a second request to the server, it may be<br />
served by a different child process than the first time.<br />
4) If you have 20 different child processes that ran a script that made a persistent connection to your<br />
MySQL server, you'd be keeping active 20 different connections<br />
http://www.<strong>php</strong>.net/manual/en/features.persistent‐connections.<strong>php</strong><br />
When do we need<br />
mysql_close() <br />
Good part:<br />
Can reduce overhead when you create a link to remote MySQL server.<br />
They cause the PHP child process to simply connect only once for its entire lifespan, instead of every<br />
time it processes a page that requires connecting to the MySQL server.<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Normalization was first proposed by Codd as an integral part of the relational model.<br />
It encompasses a set of best practices designed to eliminate the duplication of data,<br />
which in turn prevents data manipulation anomalies and loss of data integrity.<br />
The most common form of normalization applied to databases are called the<br />
normal forms.<br />
Example: What's wrong with this database<br />
Title Author1 Author2 ISBN Subject Pages Publisher<br />
Database<br />
System<br />
Concepts<br />
Abraham<br />
Silberschatz<br />
Henry F.<br />
Korth<br />
0072958863<br />
MySQL,<br />
Computers<br />
1168 McGraw-Hill<br />
Operating<br />
System<br />
Concepts<br />
Abraham<br />
Silberschatz<br />
Henry F.<br />
Korth<br />
0471694665 Computers 944 McGraw-Hill<br />
33
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Database normalization is also the process in which a database structure is free<br />
from any uncertainties like update, insertion, and deletion incidences.<br />
In order to normalize a database it must be designed in the third normal form. In<br />
the third normal form, all data will be secured, and only certain areas of the table<br />
are subjected to any change.<br />
There are three major problems encountered in database normalization and they<br />
are: the update anomaly, the insertion anomaly, and the deletion anomaly.<br />
Normalization is criticized because it increases complexity and processing overhead<br />
required to join mu<strong>lt</strong>iple tables representing what are conceptually a single item.<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Title Author1 Author2 ISBN Subject Pages Publisher<br />
Database<br />
System<br />
Concepts<br />
Abraham<br />
Silberschatz<br />
Henry F.<br />
Korth<br />
0072958863<br />
MySQL,<br />
Computers<br />
1168 McGraw-Hill<br />
This table is not very efficient with storage.<br />
This design does not protect data integrity.<br />
Third, this table does not scale well.<br />
Operating<br />
System<br />
Concepts<br />
Abraham<br />
Silberschatz<br />
Henry F.<br />
Korth<br />
0471694665 Computers 944 McGraw-Hill<br />
• we have more than one author field,<br />
• subject field contains more than one piece of information.<br />
With more than one value in a single field, it would be very difficu<strong>lt</strong> to search for all books<br />
on a given subject.<br />
First Normal Form (1NF) sets the very basic rules for an organized database:<br />
Eliminate duplicative columns from the same table.<br />
Create separate tables for each group of related data.<br />
Identify each row with a unique column or set of columns (the primary key).<br />
34
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
What about this table<br />
Book Table<br />
Title Author ISBN Subject Pages Publisher<br />
Database System<br />
Concepts<br />
Abraham<br />
Silberschatz<br />
0072958863 MySQL 1168 McGraw-Hill<br />
Database System<br />
Concepts<br />
Operating System<br />
Concepts<br />
Henry F. Korth 0072958863 Computers 1168 McGraw-Hill<br />
Henry F. Korth 0471694665 Computers 944 McGraw-Hill<br />
Operating System<br />
Concepts<br />
Abraham<br />
Silberschatz<br />
0471694665 Computers 944 McGraw-Hill<br />
We now have two rows for a single book.<br />
We need to separate the data into separate tables:<br />
• Author table<br />
• Subject table<br />
Problems<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Title Author ISBN Subject Pages Publisher<br />
Database System<br />
Concepts<br />
Database System<br />
Concepts<br />
Operating System<br />
Concepts<br />
Operating System<br />
Concepts<br />
Abraham<br />
Silberschatz<br />
0072958863 MySQL 1168 McGraw-Hill<br />
Henry F. Korth 0072958863 Computers 1168 McGraw-Hill<br />
Henry F. Korth 0471694665 Computers 944 McGraw-Hill<br />
Abraham<br />
Silberschatz<br />
0471694665 Computers 944 McGraw-Hill<br />
Book Table<br />
Subject Table<br />
Subject_ID Subject<br />
1 MySQL<br />
2 Computers<br />
Author Table<br />
Author_ID Last Name First Name<br />
1 Silberschatz Abraham<br />
2 Korth Henry<br />
ISBN Title Pages Publisher<br />
0072958863<br />
0471694665<br />
What did we achieve<br />
Database System<br />
Concepts<br />
Operating System<br />
Concepts<br />
1168 McGraw-Hill<br />
944 McGraw-Hill<br />
35
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Book Table<br />
ISBN Title Pages Publisher<br />
0072958863<br />
0471694665<br />
Database System<br />
Concepts<br />
Operating System<br />
Concepts<br />
1168 McGraw-Hill<br />
944 McGraw-Hill<br />
Subject Table<br />
Subject_ID Subject<br />
1 MySQL<br />
2 Computers<br />
Author Table<br />
Author_ID Last Name First Name<br />
1 Silberschatz Abraham<br />
2 Korth Henry<br />
Each table has a primary key, used for joining tables together when querying the data.<br />
A primary key value must be unique with in the table (no two books can have the<br />
same ISBN number), and a primary key is also an index, which speeds up data retrieval<br />
based on the primary key.<br />
How to define relationships between the tables<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Subject Table<br />
Author Table<br />
Subject_ID Subject<br />
Author_ID Last Name First Name<br />
1 MySQL<br />
1 Silberschatz Abraham<br />
2 Computers<br />
Book Table<br />
2 Korth Henry<br />
ISBN Title Pages Publisher<br />
0072958863 Database System Concepts 1168 McGraw-Hill<br />
0471694665 Operating System Concepts 944 McGraw-Hill<br />
Book_Author Table<br />
Book_Subject Table<br />
ISBN<br />
Subject_ID<br />
ISBN<br />
Author_ID<br />
0072958863 1<br />
0072958863 1<br />
0072958863 2<br />
0072958863 2<br />
0471694665 2<br />
0471694665 1<br />
0471694665 2<br />
Through Primary keys define relationships between the tables.<br />
36
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Subject Table<br />
Author Table<br />
Subject_ID Subject<br />
Author_ID Last Name First Name<br />
1 MySQL<br />
1 Silberschatz Abraham<br />
2 Computers<br />
2 Korth Henry<br />
Book Table<br />
ISBN Title Pages Publisher<br />
0072958863 Database System Concepts 1168 McGraw-Hill<br />
Book_Subject Table<br />
ISBN<br />
Subject_ID<br />
0072958863 1<br />
0072958863 2<br />
0471694665 2<br />
0471694665 Operating System Concepts 944 McGraw-Hill<br />
Book_Author Table<br />
ISBN<br />
Author_ID<br />
0072958863 1<br />
0072958863 2<br />
0471694665 1<br />
0471694665 2<br />
Here we have a one‐to‐many relationship between the Book table and the Publisher.<br />
A book has only one publisher, and a publisher will publish many books.<br />
When we have a one‐to‐many relationship, we place a foreign key in the Book Table, pointing to the<br />
primary key of the Publisher Table.<br />
Second Normal Form (2NF) requires that database doesn't have any data in a table with a<br />
composite key that does not relate to all portions of the composite key.<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
First Normal Form deals with redundancy of data across a horizontal row.<br />
Second Normal Form (or 2NF) deals with redundancy of data in vertical columns.<br />
The normal forms are progressive, so to achieve Second Normal Form, the tables<br />
must already be in First Normal Form.<br />
Requirements for Second Normal Form (2NF):<br />
• Meet all the requirements of the First Normal Form.<br />
• Remove subsets of data that apply to mu<strong>lt</strong>iple rows of a table and place them in separate tables.<br />
• Create relationships between these new tables and their predecessors through the use of foreign keys.<br />
37
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Subject Table<br />
Book_Subject Table<br />
ISBN Title Pages Publisher<br />
0072958863 Database System Concepts 1168 McGraw-Hill<br />
0471694665 Operating System Concepts 944 McGraw-Hill<br />
Can't have 'McGraw‐Hill' as a key<br />
Author Table<br />
Book_Author Table<br />
Book Table<br />
ISBN Title Pages Publisher_ID<br />
0072958863<br />
0471694665<br />
Database System<br />
Concepts<br />
Operating System<br />
Concepts<br />
1168 1<br />
944 1<br />
Publisher Table<br />
Publisher_ID Publisher Name<br />
1 McGraw‐Hill<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Third Normal Form goes one step further:<br />
• Meet all the requirements of the second normal form.<br />
• Remove columns that are not dependent upon the primary key.<br />
• All of the non‐primary key attributes are mutually independent<br />
Publisher Table<br />
Publisher_ID Name Address1 City State Zip<br />
1<br />
Sams<br />
Publishing<br />
800 East 96th<br />
Street<br />
Indianapolis Indiana 46240<br />
Publisher_ID Name Address Zip<br />
1 Sams Publishing 800 East 96th Street 46240<br />
Zip City State<br />
Problem<br />
46240 Indianapolis Indiana<br />
38
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Transitive relation:<br />
In mathematics, a binary relation R over asetX is transitive if whenever an<br />
element a is related to an element b, and b is in turn related to an<br />
element c, then a is also related to c.<br />
Example: A> B and B>C then A>C<br />
Transitive dependency:<br />
A functional dependency which holds by virtue of transitivity. Conditions:<br />
1. A B<br />
2. Not the case that B A<br />
3. B C<br />
Then A C<br />
3NF excludes certain types<br />
of transitive dependencies<br />
Example:<br />
1. {Book} {Author}<br />
2. {Author} does NOT {Book}<br />
3. {Author} {AuthorNationality}<br />
( here means 'knowing')<br />
{Book} {AuthorNationality}<br />
IF we know the book, we know Author's Nationality<br />
Both 'Author' and 'AuthorNationality' are non‐key attributes<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
No transitive<br />
dependency<br />
between nonkey<br />
attributes<br />
All determinants<br />
are candidate<br />
keys - Single<br />
mu<strong>lt</strong>ivalued<br />
dependency<br />
First Normal Form (1NF)<br />
Second Normal Form (2NF)<br />
Third Normal Form (3NF)<br />
Boyce‐Codd Normal Form (BCNF)<br />
Fourth Normal Form (4NF)<br />
Fifth Normal Form (5NF)<br />
Boyce-<br />
Codd<br />
and<br />
Higher<br />
Functional<br />
dependency<br />
of nonkey<br />
attributes on<br />
the primary<br />
key - Atomic<br />
values only<br />
Full<br />
Functional<br />
dependeny<br />
of nonkey<br />
attributes<br />
on the<br />
primary key<br />
39
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
A fully normalized database schema can fail to provide adequate system<br />
response time due to excessive table join operations.<br />
http://www.siue.edu/~dbock/cmis564/denormal.htm<br />
1. Perform a detailed view analysis in order to identify situations where an excessive<br />
number of table joins appears to be required to produce a specific end‐user view.<br />
Any view requiring more than three joins should be considered as a candidate for<br />
denormalization.<br />
2. Reduce the number of foreign keys in order to reduce index maintenance during<br />
insertions and deletions. Reducing foreign keys is closely related to reducing the<br />
number of relational tables.<br />
3. The ease of data maintenance provided by normalized table structures must also be<br />
provided by the denormalized schema. Thus, a satisfactory approach would not require<br />
excessive programming code (triggers) to maintain data integrity and consistency.<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Hillyer Mike, MySQL AB. An Introduction to Database Normalization,<br />
http://babanski.com/files/MySQL‐intro‐to‐database‐normalization.pdf<br />
Microsoft. Description of the database normalization basics,<br />
http://support.microsoft.com/kb/283878<br />
Wikipedia. Database Normalization.<br />
http://en.wikipedia.org/wiki/Database_normalization.html<br />
40
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
mysql> select * from demo_people;<br />
+------------+--------------+------+<br />
| name | phone | pid |<br />
+------------+--------------+------+<br />
| Mr Brown | 01225 708225 | 1 |<br />
| Ms Smith | 01225 899360 | 2 |<br />
| Mr Pullen | 01380 724040 | 3 |<br />
+------------+--------------+------+<br />
mysql> select * from demo_property;<br />
+------+------+----------------------+<br />
| spid | pid | selling |<br />
+------+------+----------------------+<br />
| 1 | 1 | Old House Farm |<br />
| 2 | 3 | The Willows |<br />
| 3 | 3 | Tall Trees |<br />
| 4 | 3 | The Melksham Florist |<br />
| 5 | 4 | Dun Roamin |<br />
+------+------+----------------------+<br />
Cross‐Join: select * from TABLE1, TABLE2<br />
We end up with all the possible combinations<br />
Person number 1 is selling<br />
property number 1 – Old House Farm<br />
Person number 2 doesn't sell anything<br />
Person number 3 is selling:<br />
property number 2 – The Willows<br />
property number 3 – Tall Trees<br />
property number 4 – The Melksham Florist<br />
Person number 4 is selling<br />
property number 5 – Dun Roamin.<br />
pid = person ID<br />
spid = selling property ID<br />
Worst join ever!<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Cross‐Join: select * from TABLE1, TABLE2<br />
We end up with all the possible combinations<br />
Worst join ever!<br />
mysql> select * from demo_people,demo_property;<br />
+-----+--------------+-----------+------+------+----------------------+<br />
| pid | phone | name | spid | pid | selling |<br />
+-----+--------------+-----------+------+------+----------------------+<br />
| 1 | 01225 708225 | Mr Brown | 1 | 1 | Old House Farm |<br />
| 2 | 01225 899360 | Ms Smith | 1 | 1 | Old House Farm |<br />
| 3 | 01380 724040 | Mr Pullen | 1 | 1 | Old House Farm |<br />
| 1 | 01225 708225 | Mr Brown | 2 | 3 | The Willows |<br />
| 2 | 01225 899360 | Ms Smith | 2 | 3 | The Willows |<br />
| 3 | 01380 724040 | Mr Pullen | 2 | 3 | The Willows |<br />
| 1 | 01225 708225 | Mr Brown | 3 | 3 | Tall Trees |<br />
| 2 | 01225 899360 | Ms Smith | 3 | 3 | Tall Trees |<br />
| 3 | 01380 724040 | Mr Pullen | 3 | 3 | Tall Trees |<br />
| 1 | 01225 708225 | Mr Brown | 4 | 3 | The Melksham Florist |<br />
| 2 | 01225 899360 | Ms Smith | 4 | 3 | The Melksham Florist |<br />
| 3 | 01380 724040 | Mr Pullen | 4 | 3 | The Melksham Florist |<br />
| 1 | 01225 708225 | Mr Brown | 5 | 4 | Dun Roamin |<br />
| 2 | 01225 899360 | Ms Smith | 5 | 4 | Dun Roamin |<br />
| 3 | 01380 724040 | Mr Pullen | 5 | 4 | Dun Roamin |<br />
+-----+--------------+-----------+------+------+----------------------+<br />
Cross joins are also called Cartesian products<br />
41
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
JOIN / INNER JOIN / CROSS JOIN (all are syntactic equivalents) :<br />
We get all records that match in the appropriate way in the two tables.<br />
Records in both incoming tables that do not match are not reported:<br />
mysql> select name, phone, selling from demo_people<br />
join demo_property on demo_people.pid = demo_property.pid;<br />
+-----------+--------------+----------------------+<br />
| name | phone | selling |<br />
+-----------+--------------+----------------------+<br />
| Mr Brown | 01225 708225 | Old House Farm |<br />
| Mr Pullen | 01380 724040 | The Willows |<br />
| Mr Pullen | 01380 724040 | Tall Trees |<br />
| Mr Pullen | 01380 724040 | The Melksham Florist |<br />
+-----------+--------------+----------------------+<br />
on demo_people.pid = demo_property.pid<br />
can be replaced with<br />
using (demo_people.pid)<br />
Record pid=2 is not reported (No properties):<br />
| Ms Smith | 01225 899360 | 2 |<br />
Note: we don't have OUTER JOIN !!!<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
LEFT JOIN / LEFT OUTER JOIN:<br />
We get all records that match in the same way and IN ADDITION<br />
we get an extra record for each unmatched record in the left table of the join<br />
(Example: we want to ensure that every PERSON gets a mention).<br />
mysql> select name, phone, selling from demo_people<br />
left join demo_property on demo_people.pid = demo_property.pid;<br />
+------------+--------------+----------------------+<br />
| name | phone | selling |<br />
+------------+--------------+----------------------+<br />
| Mr Brown | 01225 708225 | Old House Farm |<br />
| Ms Smith | 01225 899360 | NULL |<br />
| Mr Pullen | 01380 724040 | The Willows |<br />
| Mr Pullen | 01380 724040 | Tall Trees |<br />
| Mr Pullen | 01380 724040 | The Melksham Florist |<br />
+------------+--------------+----------------------+<br />
Note: we don't have LEFT INNER JOIN !!!<br />
42
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
RIGHT JOIN / RIGHT OUTER JOIN:<br />
We get all records that match in the same way and IN ADDITION<br />
we get an extra record for each unmatched record in the right table of the join<br />
(Example: we want to ensure that every PROPERTY gets a mention).<br />
mysql> select name, phone, selling from demo_people<br />
right join demo_property on demo_people.pid = demo_property.pid;<br />
+-----------+--------------+----------------------+<br />
| name | phone | selling |<br />
+-----------+--------------+----------------------+<br />
| Mr Brown | 01225 708225 | Old House Farm |<br />
| Mr Pullen | 01380 724040 | The Willows |<br />
| Mr Pullen | 01380 724040 | Tall Trees |<br />
| Mr Pullen | 01380 724040 | The Melksham Florist |<br />
| NULL | NULL | Dun Roamin |<br />
+-----------+--------------+----------------------+<br />
Note: we don't have RIGHT INNER JOIN !!!<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
MyISAM storage engine does not support foreign keys. You need to use InnoDB engine.<br />
• employee: a table of company employees where each member is assigned a unique ID<br />
• borrowed: a table of borrowed books. Every record will reference a borrower’s employee ID.<br />
CREATE TABLE employee (<br />
id smallint(5) unsigned NOT NULL,<br />
firstName varchar(30),<br />
lastName varchar(30),<br />
PRIMARY KEY (id),<br />
KEY idx_lastName (lastName)<br />
) ENGINE=InnoDB;<br />
We want to add Foreign Key Constraint called 'FK_borrowed'<br />
http://dev.mysql.com/doc/refman/5.5/en/innodb‐foreign‐key‐constraints.html<br />
CREATE TABLE borrowed (<br />
ref int(10) unsigned NOT NULL auto_increment,<br />
employeeid smallint(5) unsigned NOT NULL,<br />
book varchar(50),<br />
PRIMARY KEY (ref)<br />
) ENGINE=InnoDB;<br />
ALTER TABLE borrowed<br />
ADD CONSTRAINT FK_borrowed FOREIGN KEY (employeeid) REFERENCES employee(id)<br />
ON UPDATE CASCADE<br />
ON DELETE RESTRICT<br />
The FOREIGN KEY clause is specified in the child table.<br />
CASCADE: Delete or update the row from the parent table, and automatically delete or update the matching rows in the child table.<br />
RESTRICT: Rejects the delete or update operation for the parent table (defau<strong>lt</strong> if not set otherwise).<br />
43
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
Remember that parent table (employees) must be added/populated with data first:<br />
employee<br />
borrowed<br />
id firstName lastName<br />
ref employeeid book<br />
1 John Smith<br />
1 1 Simply SQL<br />
2 Laura Jones<br />
2 1 U<strong>lt</strong>imate HTML Reference<br />
3 1 U<strong>lt</strong>imate CSS Reference<br />
3 Jane Green<br />
4 2 Art of JavaScript<br />
SELECT book FROM borrowed<br />
JOIN employee ON employee.id=borrowed.employeeid<br />
WHERE employee.lastname='Smith';<br />
UPDATE employee SET id=22 WHERE id=2;<br />
No need to update 'borrowed' table directly!!<br />
What about this<br />
DELETE FROM employee WHERE id=1;<br />
Won't work with RESTRICT; deletes records from borrowed with CASCADE<br />
Resu<strong>lt</strong>:<br />
Simply SQL<br />
U<strong>lt</strong>imate HTML Reference<br />
U<strong>lt</strong>imate CSS Reference<br />
borrowed<br />
ref employeeid book<br />
1 1 Simply SQL<br />
2 1 U<strong>lt</strong>imate HTML Reference<br />
3 1 U<strong>lt</strong>imate CSS Reference<br />
4 22 Art of JavaScript<br />
CS3336A, <strong>Alex</strong> <strong>Babanski</strong><br />
MySQL 5.5 Reference Manual<br />
http://dev.mysql.com/doc/refman/5.5/en/index.html<br />
44