Chapter 14
Chapter 14
Chapter 14
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
In this chapter you will learn . . .
• The role that databases play in web development
• What is GraphQL
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Databases and Web Development
In this book, the relational DBMS used will be either SQLite or MySQL ( or
MariaDB) There are many other open-source and proprietary relational DBMS
alternates to MySQL, such as PostgreSQL, Oracle Database, IBM DB2, and
Microsoft SQL Server.
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
The Role of Databases in Web Development
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Managing Databases
Running the SQLite lab exercises for PHP and Node, you don't actually have
to install anything, since it is a file-based, in-memory database.
To run the PHP exercises in this chapter's lab, you will need access to
MySQL. If you have installed XAMPP to run your PHP, MySQL is already
installed.
To run the Node exercises in this chapter, you will either need to install
MongoDB or make use of a cloud service such as MongoDB Atlas.
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Managing Databases (Tools)
The tools available to you range from the original command-line approach,
through to the modern workbench, where an easy-to-use toolset supports the
most common operations.
• Command-Line Interface
• phpMyAdmin
• MySQL Workbench
• SQLite Tools
• MongoDB Tools
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
SQL
A table is the principal unit of storage in a database. It is a two-dimensional
container for data that consists of records (rows); each record has the same
number of columns. These columns are called fields, which contain the actual
data. Each table will have a primary key—a field (or sometimes combination
of fields) that is used to uniquely identify each record in a table.
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Table Design
Data types that are akin to those in a statically typed programming language
and contribute to data integrity. (BIT,BLOB,CHAR(n),
DATE,FLOAT,INT,VARCHAR(n))
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Foreign Key
Foreign key relates a
field in one table to a
primary key in another
table
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Table relationships
Most often, two related
tables will be in a one-to-
many relationship.
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Composite Key
• Note that in this example, the two foreign keys in the intermediate table are
combined to create a composite key. Alternatively, the intermediate table
could contain a separate primary key field.
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
SELECT Statement
The SELECT statement is
used to retrieve data from
the database. The term
query is sometimes used
as a synonym for running
a SELECT statement
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Join
Retrieving data from
multiple tables is more
complex and requires the
use of a join.
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
UPDATE and DELETE Statements
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Transactions
A transaction refers to a sequence of steps that are treated as a single unit,
and provide a way to gracefully handle errors and keep your data properly
consistent when errors do occur.
Local transaction support in the DBMS can handle the problem of an error
with START TRANSACTION, COMMIT, and ROLLBACK commands.
/* By starting the transaction, all database modifications within will only be permanently saved in the database if they all work */
START TRANSACTION
INSERT INTO orders . . .
INSERT INTO orderDetails . . .
UPDATE inventory . . .
/* if we have made it here everything has worked so commit changes */
COMMIT
LISTING 14.2 SQL commands for transaction processing
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Distributed Transactions
Transactions involving multiple hosts,
several of which we may have no control
over; are typically called distributed
transactions.
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Data Definition Statements
All of the SQL examples that you will use in this book are examples of the
data manipulation language features of SQL, that is, SELECT, UPDATE,
INSERT, and DELETE. There is also a Data Definition Language (DDL) in
SQL, which is used for creating tables, modifying the structure of a table,
deleting tables, and creating and deleting databases.
Most tools such as the phpMyAdmin, offer interfaces that allow you to
manipulate table indirectly through a GUI.
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Database Indexes and Efficiency
Consider the worst-case scenario for searching where we compare a query
against every single record. If there are n elements, we say it takes O(n) time
to do a search (we would say “Order of n”).
It is possible to achieve O(1) search speed—that is, one operation to find the
result—with a hash table data structure.
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Database Index
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Working with SQL in PHP
With PDO, the basic database
connection algorithm is:
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Connecting to a Database
With MySQL databases, you supply:
• the host or URL of the database // modify these variables for your installation
server, the $connectionString =
"mysql:host=localhost;dbname=bookcrm";
• database name, and // you may need to add this if db has UTF data
• the database user name and $connectionString .= ";charset=utf8mb4;";
password. $user = "testuser";
$pass = "mypassword";
With SQLite databases, you only need to $pdo = new PDO($connectionString,
supply the path to the file: $user, $pass);
LISTING 14.4 Connecting to a database with PDO
$pdo = new PDO('sqlite:./movies.db'); (object-oriented)
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Storing Connection Details
A common solution is to store connection details in defined constants within a file
named config.inc.php.
require_once('protected/config.inc.php’);
$pdo = new PDO(DBCONNSTRING,DBUSER,DBPASS);
<?php
define('DBHOST', 'localhost');
define('DBNAME', 'bookcrm');
define('DBUSER', 'testuser');
define('DBPASS', 'mypassword');
define('DBCONNSTRING',"mysql:host=". DBHOST. ";dbname=". DBNAME);
?>
LISTING 14.2 Defining connection details via constants in a separate file (config.inc.php)
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Handling Connection Errors
Unfortunately not every database connection always works. The approach in PDO for
handling connection errors uses try...catch exception- handling blocks.
try {
$pdo = new PDO(DBCONNSTRING,DBUSER,DBPASS);
...
}
catch (PDOException $e) {
die( $e->getMessage() );
}
LISTING 14.7 Handling connection errors with PDO
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Executing the Query
If the connection to the database is successfully created, then you are ready
to construct and execute the query.
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Processing the Query Results
If you are running a SELECT query, then you will want to do something with
the retrieved result set, such as displaying it, or performing calculations on it,
or searching for something in it.
$sql = "SELECT * FROM Paintings ORDER BY Title";
$result = $pdo->query($sql);
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Fetching from a result set
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Fetching into an Object
Given the following simple $sql = "SELECT * FROM Books";
class we can have PHP $result = $pdo->query($sql);
populate an object of type // fetch a record into an object of type Book
Book while ( $b = $result->fetchObject('Book') ) {
// the property names match the table field names
class Book { echo 'ID: '. $b->ID . '<br/>’;
echo 'Title: '. $b->Title . '<br/>’;
public $ID;
echo 'Year: '. $b->CopyrightYear . '<br/>’;
public $Title; echo 'Description: '. $b->Description . '<br/>’;
public $CopyrightYear; echo '<hr>';
public $Description; }
LISTING 14.13 Populating an object from a result set (PDO)
}
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Freeing Resources and Closing Connection
When you are finished retrieving and displaying your requested data, you
should release the memory used by any result sets and then close the
connection so that the database system can allocate it to another process.
try {
$pdo = new PDO(DBCONNSTRING,DBUSER,DBPASS);
...
// closes connection and frees the resources used by the PDO object
$pdo = null;
}
LISTING 14.15 Closing the connection
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Working with Parameters
We can use the same
page design to display
different data records
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Sanitizing User Data
The last example is vulnerable to SQL injection attack (Chapter 16)
In MySQL, user inputs can be partly sanitized using the quote() method.
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Prepared Statements
// retrieve parameter value from query string
A prepared statement $id = $_GET['id’];
is actually a way to /* method 1 – notice the ? parameter */
improve performance $sql = "SELECT Title, CopyrightYear FROM Books WHERE ID = ?";
for queries that need to $statement = $pdo->prepare($sql);
$statement->bindValue(1, $id); // bind to the 1st ? parameter
be executed multiple $statement->execute();
times.
/* method 2 */
$sql = "SELECT Title, CopyrightYear FROM Books WHERE ID = :id";
$statement = $pdo->prepare($sql);
$statement->bindValue(':id', $id);
$statement->execute();
LISTING 14.17 Using a prepared statement
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Named Parameters
/* technique named parameters */
$sql = "INSERT INTO books (ISBN10, Title, CopyrightYear, ImprintId,
A named parameter
ProductionStatusId, TrimSize, Description) VALUES (:isbn,
assigns labels in prepared :title,:year,:imprint,:status,:size,:desc) ";
SQL statements which are $statement = $pdo->prepare($sql);
then explicitly bound to $statement->bindValue(':isbn', $_POST['isbn']);
variables in PHP, reducing $statement->bindValue(':title', $_POST['title']);
opportunities for error. $statement->bindValue(':year', $_POST['year']);
$statement->bindValue(':imprint', $_POST['imprint']);
$statement->bindValue(':status', $_POST['status']);
It is also possible to pass $statement->bindValue(':size', $_POST['size']);
$statement->bindValue(':desc', $_POST['desc']);
in parameter values within $statement->execute();
an array to the execute()
method and cut out the LISTING 14.18 Using names parameters (part b)
calls to bindValue()
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Using Transactions
$pdo = new PDO($connString,$user,$pass);
// turn on exceptions so that exception is thrown if error occurs
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
...
try {
// begin a transaction
$pdo->beginTransaction();
$pdo->exec("INSERT INTO Categories (CategoryName) VALUES ('Philosophy')");
$pdo->exec("INSERT INTO Categories (CategoryName) VALUES ('Art')");
// if we arrive here, it means that no exception was thrown
// which means no query has failed, so we can commit the transaction
$pdo->commit();
} catch (Exception $e) {
// we must rollback the transaction since an error occurred
// with insert
$pdo->rollback();
}
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Designing Data Access
Database details such as connection strings and table and field names are
examples of externalities. These details tend to change over the life of a web
application.
Initially, the database for our website might be a SQLite database on our
development machine; later it might change to a MySQL database on a data
server, and even later, to a relational cloud service. Ideally, with each change
in our database infrastructure, we would have to change very little in our code
base.
One simple step might be to extract all PDO code into separate functions or
classes and use those instead.
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Designing Data Access (ii)
class DatabaseHelper { $statement = null;
public static function createConnection($values=array()) { If (count($parameters) > 0) {
$connString = $values[0]; // Use a prepared statement if parameters
$user = $values[1]; $statement = $pdo->prepare($sql);
$password = $values[2]; $executedOk = $statement->execute($parameters);
$pdo = new PDO($connString,$user,$password); if (! $executedOk) {
$pdo->setAttribute(PDO::ATTR_ERRMODE, throw new PDOException;
PDO::ERRMODE_EXCEPTION); }
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, } else {
PDO::FETCH_ASSOC); // Execute a normal query
return $pdo; $statement = $pdo->query($sql);
} if (!$statement) {
public static function runQuery($pdo, $sql, $parameters=array()) throw new PDOException;
{ }
// Ensure parameters are in an array }
if (!is_array($parameters)) { return $statement;
$parameters = array($parameters); }
} } //end class
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Designing Data Access (iii)
try {
$conn = DatabaseHelper::createConnectionInfo(array(DBCONNECTION, DBUSER, DBPASS));
$sql = "SELECT * FROM Paintings ";
$paintings = DatabaseHelper::runQuery($conn, $sql, null);
foreach ($paintings as $p) {
echo $p["Title"];
}
$sql = "SELECT * FROM Artists WHERE Nationality=?";
$artists = DatabaseHelper::runQuery($conn, $sql, Array("France"));
}
Illustrates two example uses of this class. While an improvement, we still have a
database dependency in this code with the SQL statements and field names.
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
A table gateway
class PaintingDB {
private static $baseSQL = "SELECT * FROM Paintings ";
public function __construct($connection) { public function getAllForArtist($artistID) {
$this->pdo = $connection; $sql = self::$baseSQL . " WHERE Paintings.ArtistID=?";
} $statement = DatabaseHelper::runQuery($this->pdo, $sql,
public function getAll() { Array($artistID));
$sql = self::$baseSQL; return $statement->fetchAll();
$statement = DatabaseHelper::runQuery($this->pdo, }
$sql, null); public function getAllForGallery($galleryID) {
return $statement->fetchAll(); $sql = self::$baseSQL . " WHERE Paintings.GalleryID=?";
} $statement = DatabaseHelper::runQuery($this->pdo, $sql,
public function findById($id) { Array($galleryID));
$sql = self::$baseSQL . " WHERE PaintingID=?"; return $statement->fetchAll();
$statement = DatabaseHelper::runQuery($this->pdo, $sql, }
Array($id)); }
return $statement->fetch();
}
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
NoSQL Databases
NoSQL (which stands for Not-only-SQL) is category of database software that
describes a style of database that doesn’t use the relational table model of
normal SQL databases.
NoSQL databases rely on a different set of ideas for data modeling that put
fast retrieval ahead of other considerations like consistency.
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Why (and Why Not) Choose NoSQL?
NoSQL systems handle huge datasets better than relational systems.
NoSQL databases aren’t the best answer for all scenarios. SQL databases
use schemas for a very good reason: they ensure data consistency and data
integrity.
The data in most NoSQL database systems is identified by a unique key. The
key-value organization often results in faster retrieval of data in comparison to
a relational database
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Key-Value Stores
Key-value stores alone are quite
straightforward in that every value,
whether an integer, string, or other data
structure, has an associated key (i.e.,
they are analogous to PHP associative
arrays)
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Document Store
Document Stores (also called document-oriented databases) associate keys
with values, but unlike key-value stores, they call that value a document.
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Relational data versus document store data
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Column Stores
In traditional relational database
systems, the data in tables is
stored in a row-wise manner. This
means that the fundamental unit of
data retrieved is a row.
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Working with MongoDB in Node
MongoDB MongoDB is an open-source, NoSQL, document-oriented
database. It can be used with PHP, it is much more commonly used with Node
You simply package your data as a JSON object, give it to MongoDB, and it
stores this object or document as a binary JavaScript object (BSON).
The ability to run on multiple servers means MongoDB can handle large
datasets
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Comparing relational databases to the
MongoDB data model
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Comparing a MongoDB query to an SQL query
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Working with the MongoDB Shell
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Accessing MongoDB Data in Node.js
const mongoose = require('mongoose');
// define a schema that maps to the structure in MongoDB
const bookSchema = new mongoose.Schema({
id: Number,
isbn10: String,
isbn13: String,
title: String,
require('dotenv').config(); …
console.log(process.env.MONGO_URL); },
const mongoose = require('mongoose'); category: {
mongoose.connect(process.env.MONGO_URL, main: String,
{useNewUrlParser: true, useUnifiedTopology: true}); secondary: String
const db = mongoose.connection; }
db.on('error', console.error.bind(console, });
'connection error:')); // now create model using this schema that maps to books
db.once('open', () => { collection in database
console.log('connected to mongo'); module.exports = mongoose.model('Book',
}); bookSchema,'books');
LISTING 14.23 Connecting to MongoDB using Mongoose LISTING 14.24 Creating a Mongoose model
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Web service using MongoDB
// get our data model app.get('/api/books/:isbn', (req,resp) => {
const Book = require('./models/Book.js’); // use mongoose to retrieve all books from Mongo
Book.find({isbn10: req.params.isbn},
app.get('/api/books', (req,resp) => { function(err, data) {
// use mongoose to retrieve all books if (err) {
Book.find({}, function(err, data) { resp.json({ message: 'Book not found' });
if (err) { } else {
resp.json({ message: resp.json(data);
'Unable to connect to books' }); }
} else { });
// return JSON retrieved by Mongo as response });
resp.json(data);
}
});
});
LISTING 14.25 Web service using MongoDB data and Mongoose ORM
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Key Terms
aggregate functions data duplication inner join one-to-one single-master
relationship replication
binary tree database join
normalization ORM (Object- SQL
clickstream key-value stores
Relational
distributed SQL script
column store local transactions
transactions Mapping)
table
commodity servers many-to-many
document stores phpMyAdmin
table gateway
composite key relationship
failover clustering prepared statement
transaction
connection multiple-master
fields primary key
two-phase commit
connection string replication
foreign key query
database MySQL
GraphQL record
data integrity named parameter
graph store result set
Data Definition NoSQL
hash table sanitization
Language
one-to-many
index sharding
(DDL) relationship
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved
Copyright
Copyright © 2021, 2018, 2015 Pearson Education, Inc. All Rights Reserved