navigate site menu

Start learning with our library of video tutorials taught by experts. Get started

PostgreSQL 9 with PHP Essential Training
Mark Todd

PostgreSQL 9 with PHP Essential Training

with Bill Weinman

 


In this course, author Bill Weinman shows how to architect PostgreSQL databases and integrate them into web applications using PHP. The course covers the basics of creating tables, storing data with data types, and working with expressions, operators, and strings. The course also explores the differences between the PDO and pgsql interfaces and demonstrates managing a database in PHP.
Topics include:
  • Installing PostgreSQL
  • Understanding database architecture
  • Inserting, updating, and deleting data in a table
  • Creating a database library
  • Indexing ID fields
  • Storing numbers, text, and Boolean values
  • Reading data
  • Using casts to force type
  • Using mathematical functions
  • Concatenating strings
  • Working with date and time functions and operators
  • Defining CRUD
  • Using PHP to insert, read, update, and delete rows in a database

show more

author
Bill Weinman
subject
Developer, Web, Databases, Web Development
software
PostgreSQL 9
level
Beginner
duration
4h 45m
released
Nov 10, 2011

Share this course

Ready to join? get started


Keep up with news, tips, and latest courses.

submit Course details submit clicked more info

Please wait...

Search the closed captioning text for this course by entering the keyword you’d like to search, or browse the closed captioning text by selecting the chapter name below and choosing the video title you’d like to review.



Introduction
Welcome
00:04Hi! I'm Bill Weinman, and welcome to PostgreSQL 9 with PHP Essential Training!
00:09In this course, we'll explore PostgreSQL 9, a full-featured, open-source,
00:15object-relational database management system.
00:17I'll explain the major features of PostgreSQL and its usage in a PHP environment,
00:22focusing on real-world examples to aid you in implementing this powerful
00:26database engine in your applications.
00:29I'll show you the details of its SQL usage, functions, data types,
00:33expressions, and operators.
00:35This course is a great introduction to PostgreSQL 9, but some programming and
00:40database experience will really help you get the most out of these technologies.
00:44It's really exciting to be able to use a full-featured enterprise-class database
00:48management system that still maintains its free and open-source roots.
00:52So let's dig in with PostgreSQL 9 with PHP Essential Training.
Collapse this transcript
Using the exercise files
00:00If you have access to the exercise files for this course, you can use them to
00:03follow along with the lessons as I present them.
00:06Because this course uses PHP, you will need a web server installed on your
00:10development machine, and for many of the exercises you will need to copy the
00:14exercise folders to the document root directory of your web server.
00:17Here in the Exercise Files folders, you will find a folder for each of the
00:21chapters in this course.
00:24For many of the chapters you will find an examples.sql file.
00:29This file contains snippets of SQL to help you follow along with the examples in the movies.
00:35The rest of the folders contain supporting files, for example, applications
00:39and other purposes.
00:40They will be explained as we use them.
00:43Many of these files are available for non-Premium members of the lynda.com
00:46Online Training Library.
00:48The chapter folders are available for Premium members.
00:51If you do not have access to the chapter folders, you can easily follow along
00:55and create files of your own.
Collapse this transcript
Prerequisites
00:00PostgreSQL is typically pronounced as post-gres.
00:03Some say PostgreSQL, but many consider that unwieldy and simply say post-gres.
00:10Like most SQL databases, Postgres does its best to conform to ANSI SQL standard--
00:16in this case, the latest version, SQL 2008--
00:19but will break the standard where necessary for capability or
00:22compatibility reasons.
00:24In reality, there are no fully compliant SQL database systems, because the SQL
00:29standard does not describe a complete database management system.
00:33Additionally, most mature database systems pre-date the standard and maintain
00:38some non-compliant syntax in order to preserve compatibility with legacy code.
00:43Postgres, dating back to the Ingres project in the early 1980s, with its SQL
00:48support beginning in the early 1990s, has a great deal of legacy to support.
00:53Postgres has all the features you would expect from a major DBMS, including
00:57triggers, views, transactions, save points, foreign keys, full-text search,
01:02replication, concurrency, object inheritance, storage procedures, a rich set of
01:07data types, multiple indexing systems, and many, many more.
01:11For this course, we will cover the essential features necessary to use this
01:15powerful system for simple common projects.
01:18Postgres is suitable for many purposes, from a small web site project to a major
01:23corporate-distributed database system.
01:26It supports very large data stores with excellent performance, comparable to
01:30current offerings from major vendors like Oracle or Microsoft.
01:35In order to get the most out of this course, you should have some programming
01:38experience and some knowledge of SQL.
01:41If you need to learn the basics of SQL, please see my course SQL Essential
01:46Training here on the lynda.com Online Training Library.
01:49You'll need the have Postgres 9.0 or greater installed on your system.
01:54There are movies showing how to install Postgres on Mac, Windows, and Linux in this course.
02:00Postgres comes with a database administration program called pgAdmin3.
02:06You may use the SQL Query Module in pgAdmin to follow along with all the
02:10exercises in this course.
02:13In order to edit source code, you will need a good text editor.
02:16A text editor is different from a word processor.
02:19A word processor adds extra information to text files that will make them not
02:23work for source code.
02:24Do not use a word processor.
02:26For a text editor, I recommend BBEdit or TextWrangler on a Mac, or Notepad++ on a PC.
02:33Do not use the Notepad program that comes with Windows, as it is not
02:37sufficient for this purpose.
02:39In order to demonstrate the PHP features in this course, I'm using XAMPP,
02:43X-A-M-P-P, a quick and simple package installer for Apache and PHP that runs on
02:50all modern operating systems.
02:52Along with XAMPP, I'm using a program called SID, which I developed for
02:56demonstrating and testing SQL for my SQL-related courses here on lynda.com.
03:01You do not need to use SID in order to follow along with the exercises in this course;
03:06all the exercises will work fine using pgAdmin3.
03:09I find SID easy to use, and I think you will too, but it's not necessary.
03:14There are movies demonstrating how to install XAMPP and SID in this chapter.
Collapse this transcript
Installing PostgreSQL on a Mac
00:00Installing Postgres on a Mac involves a few steps.
00:03There is a little configuring to do.
00:04You need to create a Postgres user, and you need to install the software.
00:07So let's get started.
00:09If you're running OS X Lion Server version, Postgres is already installed.
00:14We will be concentrating on the non-server version of OS X 10.7 Lion.
00:20The first thing you need to do is to create the Postgres user.
00:23So we are going to go into System Preferences, and we are going to go into
00:27Users, and we are going to create a user.
00:29So I will click on the little lock down here, type in my password, and now I am
00:34going to create a user.
00:36Now the purpose for this is that Postgres actually requires its own user to run the server.
00:41It's a security thing, because Postgres is typically involved in a
00:45server environment.
00:46For our purposes, we are not installing it in a server.
00:48We are not going to be sharing this server with other users, but we are going to
00:53follow the procedures for installing the software anyway.
00:56We'll install it as a Standard user.
00:58If you install it as a Sharing Only user, it's not going to work, because the
01:02standard Postgres installation actually requires a home directory. And of course
01:07you don't want to install it as an Administrator,
01:10so we are just going to install it as a Standard user.
01:13The Full Name will be PostgreSQL.
01:17And the Account name is just going to be Postgres, like this--
01:21eight letters: p-o-s-t-g-r-e-s.
01:24It's really important that you install it exactly with this name, because
01:28otherwise the installer will not work.
01:30So I am going to give it a password.
01:32You'll want to remember what this password is--you're going to need it later.
01:36And you'll probably want to install a longer one than that.
01:39That's just traditional for use here in the recording booth at lynda.com. And I
01:44am going to click on Create User.
01:46I am also just going to be pedantic here and change the picture.
01:50You will notice in our Exercise Files, under assets, there is little image here of
01:56the Postgres elephant.
01:57I am going to use that.
02:01That way when I look in the list I'll immediately see that this is the Postgres user.
02:05And that's all we need to do.
02:06I am going to click to lock the changes and close the System Preferences.
02:12Now we are going to go and download the installer, and you'll notice this is the
02:15page where you download.
02:16The URL is www.postgresql.org/download/ macosx. And click on this Download for Mac
02:26OS X and you will get this page here, which you will notice is an
02:30enterprisedb.com, because they do the packaging for the installers for Postgres.
02:36And we are going to download it from this link right here at the top that says
02:39Mac OS X. This is version 9.1.1-1.
02:42Of course, by the time you do this, it will probably be a later version.
02:45If you're going to be following along with this installation, you want it to be
02:48in the 9.0 or 9.1 tree.
02:51Now I've already downloaded it. I have it here on my desktop.
02:55So I am going to double-click on that. And you will notice that the first time I
02:59run the installer, it does something interesting. So here we go.
03:03I am going to double-click on the installer, and it warns me that downloaded it
03:07from the Internet, and I type in my password.
03:12Instead of actually installing the software, it gives me this message.
03:16What it's done is it's set a file in the etc folder to configure shared memory,
03:22because Postgres requires a certain amount of shared memory and OS X comes with
03:27less shared memory than that, installed by default.
03:30This will not affect the performance of your machine for any purpose other than Postgres,
03:36so it's okay.
03:37You go ahead and you click OK here.
03:40If you ever want to remove this, you will simply go to the etc folder. I will show you the file.
03:44I am going to click OK, and we are going to go ahead and we are going to go to the etc folder.
03:47So I am going to click on Go.
03:49This is in the Finder menu.
03:51Go to Folder and type in "/etc" and select Go, and then all the way down at the
03:57bottom here you see this sysctl.conf.
03:59We will go ahead and open that in our editor.
04:03I will select BBEdit here. And you will notice that the etc sysctl.conf
04:10has these lines in it.
04:12This is just about setting up shared memory.
04:14It's not going to have any effect on the rest of your system at all.
04:17So we will go ahead and we will close this.
04:19Now in order for this to take effect, in order to be able to actually install
04:23the software, we need to reboot the machine.
04:26I know it's very rare for a Mac to have to reboot in order to install something,
04:29but this has actually changed the system configuration, and it's just necessary.
04:32There is no other way to do it.
04:34So now I am going to go ahead and reboot the machine, and I will back in a moment.
04:39So we've rebooted the Mac, and now I am going to go and open up this installer
04:44again. And you will notice this time when I double-click on it, it will open.
04:50So now I will click on Next.
04:54I am going to go ahead and keep the defaults here.
04:56So that's the directory where it will be installed, and you will want to make a
05:01note of that--and I will show you where to find it in a moment.
05:04We'll go ahead and leave that default as well.
05:06That's where the data will be installed.
05:08Now I am going to type in the password.
05:09Remember, we created the Postgres user.
05:11Now I am going to type in the password that I entered with that user.
05:15So you'll need to remember what that password was.
05:17If you don't remember what the password was then you'll need to go right now
05:20back to system settings, delete the user, and create it again, and remember
05:24what the password is.
05:25So I am going to go ahead and type it in, and retype it for confirmation, and I am
05:31going to click on Next.
05:32Now the default port for Postgres is 5432.
05:36If this number is different here, if the default does not say 5432, you'll
05:42need to quit and find out what's using the port and remove it and then come
05:47back and install again, because we're actually going to count on that port
05:52number being 5432 when we install PHP; the default PHP drivers look for
05:57Postgres on that default port.
05:59So I am going to go ahead and say Next, and I am going to accept the Default
06:03locale and say Next again.
06:07Now it's installing a bazillion things that are all part of the Postgres package.
06:12Now that's installed.
06:14I am going to uncheck this Stack Builder.
06:16If you want to run it and you want to look at the other things you can download
06:20and install, go ahead and look at it.
06:22There's nothing there that we need for this course though.
06:23And I am going to say Finish.
06:26Now Postgres is installed, and it's running.
06:29So I am going to unmount this installer disk here, and you'll notice that
06:33it's not down in the tray.
06:34So I am going to come into Finder, and I'm going to go to applications, and we are
06:40going to find here the Postgres 9.1 folder, and in the folder you will notice
06:47there is this pgAdmin III app.
06:50Now there is a little bit of an issue with this, and that issue is the icon.
06:55The problem with this icon is that it's mostly transparent,
06:58so when I put it down here in my tray you will notice that you can hardly see it.
07:02It looks like a ghost, and that may be okay for you.
07:06For my purposes I found it really hard to work with,
07:09so I came up with a workaround, and this is what it is.
07:11I am just going to right-click on it and go to Get Info, and you will notice
07:15that there is the icon.
07:16When I select that, I'm actually able to paste another image in there.
07:20So I am going to come back up here at the Exercise Files, and under assets I've
07:23got the official Postgres logo here.
07:26When I double-click on that it comes up in the preview app, and I just press
07:31Command+A and a Command+C and that puts it into my copy buffer, and I come over
07:36here and Command+V to paste it.
07:39I have to type in my password, and it updates the icon there.
07:43So now when I go back to Applications, you'll notice that it's updated here, and I
07:52put it in my tray and it's updated in my tray.
07:55Unfortunately, when you run this, it actually goes off and runs another program.
08:00So when I press Command+Tab you'll see it's got the ghost logo there again.
08:04There's a way to fix that as well, and I am just going to show you how to do
08:08that, because maybe it annoys you as much as it annoys me--
08:11maybe it doesn't. I am going to go to Folder, and I am going to type in
08:16/library and scroll down to PostgreSQL 9.1 and pgAdmin III app, and just do the same thing.
08:25Get Info, select it, press Command+V, because it's still in my copy buffer, and
08:32that updates it. And that's the actual application that gets called by the other one.
08:38So now when I click on this it brings up the actual application and when I click
08:44Command+Tab, I've got a real icon there.
08:46Although it matters to me, it may not matter to you.
08:50So Postgres is installed.
08:51This is pgAdmin III, which is the application used to administer Postgres.
08:57It's actually written by a third party.
08:58There is a command-line client that comes with Postgres, and we're just not going
09:02to be using that because, well, we've got this, and it works so much better.
09:07So I am going to double-click on this server, which is our local server, and that
09:12connects it. And again, it wants that password for the Postgres user,
09:16so I am going to type that in.
09:17If I want to, I can click Store password so I don't have to type it in anymore,
09:21and it will give me a little warning about it.
09:24We will say Do not show that again.
09:27Now every time I start this, I can just double-click on the server and it will
09:30connect to the server.
09:31First thing we are going to do here is we are going to create a Login Role, and
09:36I am going to show you the best way to do this.
09:38The easy way to do it is just click on Login Roles and click on this New button
09:42and create a role, and you can certainly do that and that will work.
09:46But when you're using Postgres in a production environment, you're going to want
09:49to have several different users, and some of these users are going to have
09:52similar sets of privileges and are going to use common objects.
09:56One of the advantages of the Postgres database management system is that it's
10:00object oriented and objects can inherit properties from other objects.
10:04We are going to go ahead and create a Group Role, and then we are going to
10:07create a Login Role that actually inherits the permissions from the Group Role,
10:11so you can see how that works.
10:12So I am going to select Group Roles, and this icon here will create a new one of
10:17whatever you have selected down here.
10:18So if I have Databases selected, it'll create a new database.
10:21If I have Group Roles selected, it'll create a new Group Role.
10:25So we are going to go ahead and create a Group Role, and we are just going to call it web.
10:28It's going to have just the default privileges and no Role membership, and it's
10:34just going to be called web.
10:35You will notice that because it's a Group Role it does not have a place for a password.
10:40So you don't need to enter password.
10:41All you really need to do is enter that name. And now we are going to go and
10:44create a Login Role that will inherit from that Group Role.
10:47So I can select Login Roles, press the New button, and under Role membership,
10:52I am going to select web and press the little right arrow, and that'll make
10:56this new role a member of web. And then I am going to give it a name, and the
11:00name will be sid, which is the name of the application we are going to be using it with.
11:06SID will simply inherit its permissions from web. And under Definition we are
11:12going to put in a password for sid.
11:14Again, you'll need to remember this password. And I am going to say OK, and it
11:22creates that Login Role. And you'll notice there are two.
11:24There is Postgres, which is our system one and there's sid.
11:28Never use Postgres for applications. Bad idea.
11:32Now under Databases we are going to create a few databases.
11:35We are going to create one called test, and its owner will be web, and that means
11:41that sid can use it. That's pretty cool, huh?
11:43I am going to create another one called album, and these are going to be some of the
11:49databases we are going to be using for the examples.
11:53And one more, and this one is called world.
12:01Now that we have these databases, we are going to go and populate them with
12:03a little bit of data.
12:04We are almost done here.
12:06Under test you'll notice down here you get the SQL that was used for
12:10creating these objects.
12:12I am going to select test and click on this SQL button, and we are simply going
12:17to open an SQL file.
12:19So I am going to click on this Open icon there and navigate to my Exercise Files,
12:24and in my Exercise Files, under SQL, you notice I have the test database,
12:31so I am going to get the test-pg.sql file.
12:35I am going to open that up, and in here you see there's all of the databases
12:41and views and things that we are going to use in the test database.
12:45So I go ahead and run it, and that's this little green right arrow there.
12:48And that's been run.
12:50So I'll close this, and I am going to do the same thing for album.
12:53We will open up the album SQL file, and we'll run it and that created the tables
13:01and such for album, and we will do the same thing for world.
13:05And world is a little bit bigger so it takes just a moment longer, and
13:11Run, query is running. There it is.
13:14Now it's done.
13:16Now you will notice, if we just go ahead and open a query window again for world
13:21and we type in select*from view_tables--
13:26view_tables is a view that we actually created in that SQL file and I click Run--
13:32there we have some results.
13:33We have three tables--
13:35city, country, countrylanguage-- and they're all owned by web.
13:39I do not want to save that.
13:43So in fact, at this point you can actually run most of the exercises in the course.
13:48In another movie in this chapter we will be installing a test environment that
13:51includes a web server and PHP, and you will certainly need to do that if you want
13:55to be learning about how to use Postgres with PHP.
13:59If you're just interested in learning to use the database and you don't care
14:01about the sid application, which is just a convenient way of running the SQL
14:06examples in the course, then you can simply use the SQL Query application from right here.
14:12You can select the test database, you can press the SQL button, and you can type
14:16in your queries here, press Go, and see your results down here.
14:21If you're interested in SQL or if you'd simply like to run the sid application,
14:25which is a more convenient way of doing exactly the same thing,
14:28then go ahead and watch the other movie and install the XAMPP package, which
14:31includes Apache and PHP, and we'll also install the sid application with that.
14:37But for now, Postgres is installed and the pgAdmin III application is installed,
14:42which allows you to administer and use the Postgres database on your Mac.
Collapse this transcript
Installing PostgreSQL on a PC
00:00In this movie, I'll be installing Postgres 9.1 on this machine running Windows 7.
00:06I've downloaded Postgres already from this web site, but here's how you do it.
00:10You go to www.postgresql.org/download, and you'll notice a link down here for Windows.
00:17You click on that and you'll click on Download the one click installer.
00:24Now this will take you to another web site run by EnterpriseDB.
00:27These are the folks that package up the one-click installers for Postgres.
00:33And you'll select the appropriate one of these Windows versions.
00:36I have selected the Widows x86-64, and that's right here on my Desktop, and I'm
00:42going to install it from there.
00:45Now before you install Postgres, it's really important that you turn off any
00:50antivirus software that might be running.
00:53I have actually experienced installing Postgres with antivirus software running
00:58and having that installation not work.
01:02So you need to turn off your antivirus software before you run this installation.
01:07Also, you need to run the installer in administrator mode, and that means that
01:11you right-click on it and you select Run as administrator.
01:16And then the rest of it is actually pretty easy.
01:18The installer comes up.
01:20Now this takes a while.
01:21You might see some dialog boxes about Visual C and stuff like that.
01:26Just be patient and at some point the installer will start up. And there it is.
01:33So I'll click on Next, and I'm going to just accept the defaults here, and I
01:38suggest that you do that as well. So it's going to install it in Program Files. Click Next.
01:43It's going to install its data in a subdirectory of its installation directory,
01:47and I'm going to click Next.
01:49And now it's asking for a password for what it calls the database superuser,
01:53which is called Postgres, with one s, and a service account, also called Postgres
01:59with one s. And if these already exist in Windows then the password has to be
02:03the same as what you installed them with, or in most cases those accounts will
02:08not already exist in your Windows if this is you're first time installing
02:11Postgres, in which case you choose a password and the account will be created.
02:14So I'm just going to choose a password here.
02:18Now you'll need to make a note of the password that you choose here because
02:21we're going to need it later.
02:23So make a note of that and then press Next.
02:26Now it's asking for the port number and it will suggest a port number.
02:29And again, this is really important:
02:31this port number must be 5432.
02:34If there's a different port number showing in this dialog box, that means that
02:38you probably already have Postgres installed on your machine and you'll need to
02:42either use that installation, or you will need to uninstall it, or you'll need
02:46to figure out how it's installed and use it.
02:49So this must say 5432.
02:52If it says something different, some of the components in our installation
02:55will not work properly.
02:57Of course, it's possible to install it on different ports, and it's complicated
03:00to do so. And for our purposes, we just need to get it installed so we can
03:03start learning about it.
03:05So if this says something besides 5432, you need to stop the installation and
03:09figure out what's going on and deal with that.
03:11So I'm going to press Next.
03:13I'm going to accept the Default locale. Press Next.
03:17And now when I press Next, the installation will begin and thousands of things
03:22will spin by on the screen as the software gets installed. All right!
03:27Now Postgres is installed.
03:29You'll notice this little check box here for Launch Stack Builder at exit.
03:33I'm going to uncheck that. Stack Builder is not something that we need for this course.
03:38So I'll click Finish, and now Postgres is installed and running.
03:43So I'm going to click on the Start menu here and click on All Programs and
03:47PostgreSQL 9.1, and you'll notice something here called pgAdmin III.
03:53That is the Postgres administration console that comes with the one-click installer.
03:57This is actually built by the folks over at EnterpriseDB and given away for free,
04:02so I'm going to right-click on that and click Pin to Start menu and then come up
04:08here to the Start menu and click on pgAdmin III and run it.
04:13I am going to go ahead and make this take up a little bit more of the screen
04:17here so that we can use it properly.
04:19And you will notice here in the left- hand pane there is a server with an X on it
04:24that says Postgres 9.1 on localhost 5432.
04:25And that's our server that we just installed, and the fact that that's there
04:31means that it's running.
04:32So I'm just going to double-click on it and it goes ahead and connects, and
04:36you'll notice that it's asking me for the password for the user Postgres on the server.
04:41And we made a note of that password, so I'm going to type in that password here.
04:45I'm going to click Store password.
04:47This is because this is not a production server; this is a test server and a
04:51test server needs to be convenient.
04:53Obviously, for a production server you probably don't want to store the
04:56password or you'll want to follow whatever security procedures you have in place.
05:00So I'm going to go ahead and click Store password, and you may get a warning
05:04about saving the passwords, and you can either click the Don't want me again or
05:08deal with that however you like.
05:09So we have the running server here, and we need to create a user, and we need to
05:14create some test databases.
05:17So we'll go ahead and do that.
05:18Now I want to show you a feature here that we don't really need for our test
05:22purposes, but it's something that you should know about, and it's called Group Roles.
05:26So users in Postgres are called roles, and so we could just create a role that
05:30we're going to use with very few permissions and have all of our databases owned
05:34by the role and that would work just fine.
05:37But because Postgres is an object- oriented database and objects can inherit
05:41other objects, I want to show you how you can create a Group Role and have your
05:46other roles inherit that role.
05:48This is really useful in a production environment, and so you should know how to do this.
05:52So we'll start up by creating a Group Role. So I select Group Roles here on the
05:56left and I press this really convenient "create a new one of these" button.
06:00When I have Group Roles selected, it will create a new Group Role.
06:04If I have something else selected, like Databases and I press that button, it
06:07will create a new database.
06:09So this is kind of a cool thing, and again, it has to do with Postgres'
06:14object-oriented nature that allows it to do this.
06:17So I select Group Roles and I press this new one of these and I just name the role web.
06:23And if I click through all of these different tabs here, you don't need a
06:27password, because this is not a login role.
06:30Privileges, it's just going to have the minimum amount of privileges.
06:33Role membership, there aren't any. Variables, SQL.
06:36This is actually the SQL that will be executed to create this role.
06:41So I just press OK and now we have this Group Role called web.
06:45Now when I create a login role--and again, I'll press the handy-dandy "create
06:49one of these" buttons.
06:51I'm going to name this one sid, because that's the name of our application that
06:53we're going to be running.
06:54Under Definition, I'm going to give it a password.
06:57Now the password that I'm using I'm just going to tell you because the PHP
07:01script called SID and also the PHP script called CRUD already use this password.
07:05And if you use the same password, then you don't need to change it.
07:08Of course, feel free to use whatever password you want to, but this one is
07:11foo.bar, and I'll type it again, f-o-o-.-b-a-r.
07:17And under Role membership, you'll notice there is this Group Role here, so I'm
07:22going to select that and press this right arrow button, and that will make this
07:26sid a member of web.
07:28And that means the databases and other objects that are owned by web can be used
07:33by sid, because sid inherits web. Pretty cool, huh?
07:37The SQL to do this looks like this. And when I press OK, it will actually
07:42execute that SQL, and it will create this role called sid, which inherits web.
07:48Now when we create databases, we can have them owned by web and sid can use them,
07:52so let's go ahead and do that.
07:53I'm going to create a database called test, and its owner will be web.
07:59And you'll notice the SQL looks like that for creating the database. And I'm just
08:03going to press OK. And this takes a moment.
08:07And I'm going to do this a couple more times.
08:09I'm going to create one called album, and it's also owned by web. And I'm going to
08:17create one called world, and that is also owned by web.
08:22Now we're going to go ahead and populate these databases.
08:27I've already copied the exercise files to the Desktop, and you'll need that for
08:32populating these databases.
08:33So I'm going to click on test, and I'm going to click on this button that says
08:37SQL for executing SQL queries.
08:41And we're going to open a file and in the Exercise Files off of my Desktop, so
08:46under Desktop and Exercise Files, there is a folder called SQL.
08:51And in that SQL folder, you'll see these three SQL files. So I'm going to select
08:56the test one and say Open,
08:58and that opens up this SQL file where it defines these tables and populates them.
09:03So I'm just going to press this green Execute query button here and that
09:08populates that database.
09:11I'll close this, and we'll do the same thing under album, run the SQL query, open
09:18the file, click on album-pg.sql, and click Execute.
09:26And we're going to do the same thing one more time for world: SQL, open file,
09:31world-pg.sql, and click on the Execute query button.
09:37This one takes just a moment longer.
09:40So now we've created these three test databases.
09:43They're owned by web.
09:44We have our login role called sid that inherits the permissions for web.
09:47And we have these populated databases.
09:51So for example, if I were to click on test here and open the SQL query
09:56application, I can type a query.
09:58I can say select * from sale;
10:04and press the Execute button, and we get the data from the sale table.
10:09Now in fact, you can actually follow along with most of the exercises in this
10:14course using this SQL query application.
10:18Unless you're actually here to learn also about how to use Postgres from PHP, or
10:24if you just like to run the slick little sid application that I've written in
10:29PHP, you don't need to install the XAMPP web server.
10:32You don't need to install PHP.
10:34You can stop right here and go on to the rest of the course and actually learn
10:40how to use Postgres from here.
10:43On the other hand, if you want to learn about using Postgres from PHP, or if you
10:47want to run the sid application, or if you just want your screens to look the
10:50same as mine as we proceed through the course, then you'll want to go ahead and
10:54install the XAMPP package later in this chapter.
10:56So I'm going to close this and say no, I don't want to save those changes,
11:02and there we have it.
11:04In this movie, we've installed Postgres on a Windows 7 machine.
11:08If you're also learning how to use Postgres with PHP or just want to follow
11:11along with the exercises in this course, we'll be installing XAMPP in
11:15another movie.
Collapse this transcript
Installing PostgreSQL on Ubuntu Linux
00:00In this movie, we're going to install Postgres on a Linux desktop system.
00:06Here I'm using Ubuntu 11.04. This is the April 2001 version of Ubuntu.
00:12Ubuntu is released twice a year,
00:14so your version will probably be later, since I am recording this in October and
00:18they will probably release a new version soon.
00:21If you are using a different distribution of Linux, the process should be
00:26roughly the same, but of course each distribution kind of does their own thing,
00:30so you may need to adjust.
00:31I'll be installing Postgres 9.1. The version released with Ubuntu 11.04 is
00:39Postgres 8.4, which is a couple of years old, but either way, it's probably best
00:44to just download it and install it from the web site than to install it from
00:49Ubuntu's repository.
00:50So we will start by bringing up our web browser, and here I'm using Firefox.
00:55I am going to go to the Postgres homepage, which is at Postgresql.org. And I will
01:03click on Downloads, and I'll click on Linux, and I'll click on Graphical
01:09Installer, and then I'll click on Download packages from EnterpriseDB.
01:14Now the Graphical Installers are maintained by this other company called
01:18EnterpriseDB, and you'll notice there is a place to download for all these
01:22different operating systems. We are going to download the Linux x86-64.
01:27That's the 64-bit Linux version. And you see this is version 9.1.1-1.
01:32Again, your version will probably be later, unless you're watching this soon
01:35after this course is released.
01:37Now I've already downloaded it, so I am going to go ahead and close this, and
01:42here's the installer there on my desktop.
01:44Now this installer needs to be run as root, so I am going to bring up my
01:48terminal here and I am going to change directories to my desktop.
01:52So that's cd Desktop. And if I type ls -l, you will see that here is the installer.
02:00Just expand my window a little bit here.
02:04So here is the installer Postgresql-blah, blah, blah.bin.
02:09And you'll notice that it's owned by me and that its permissions are as for a
02:13document; it's not executable.
02:15There is no Xs there.
02:16So the first thing I need to do is I need to change those permissions.
02:19So I am going to use chmod. And I am going to give it executable permissions,
02:25so I am going to type 755 and the name of the file.
02:28So I type the first few letters and press Tab, because I am using Bash and it
02:32has got command completion. And press Return and we have now changed those
02:37permissions, but let's say ls -l one more time.
02:40You see it comes up in green, and it's got Xs now in the permissions, which
02:44means that it is executable.
02:45Now I need to run this as root,
02:48so I am going to use the sudo command to get superuser permissions.
02:52So I say sudo ./ and type the first few letters of the installer and press Tab,
02:59and this will execute the installer as if I were root with the superuser permission.
03:04So I'll press Enter.
03:05It asks me for my password, and it runs the installer.
03:10So, welcome to the PostgreSQL setup wizard and I press the Next button. And I am
03:17going to leave this installing in the default directory, which is in the opt
03:20tree, which is a great place for this.
03:22Press Next and the data directory will be right off of that PostgreSQL 9.1
03:28directory, so that's fine.
03:29I am going to press Next again. And now it's asking me for a password for
03:33the database superuser.
03:35This is not the root superuser on the machine.
03:38This is a new user called Postgres, eight letters--
03:41you can see here, Postgres--
03:43that will be created by the installer, and the purpose of that user is to
03:49own the Postgres server process and to be the default user for the Postgres database.
03:55So you are going to remember this password--that's the point.
03:58You are going to type in a password here and you need to write it down and remember it
04:01because we are going to need it later.
04:02So I am going to type in a password here.
04:04You probably want to use a longer one, but here in the recording booth this is
04:09the password we tend to use because we tend to share it.
04:12And I press Next here. And now it is asking me for the port number for the server.
04:17You will notice it says 5432.
04:19If it does not say 5432 then you probably have another instance of Postgres
04:25already running on your machine, and you want to cancel this installation and
04:29find out about that other installation and see if you can use that.
04:32But the default port number for Postgres is 5432, and so that's what should
04:37be the default in this box, and if it's not, you need to care of that,
04:40because other parts of what we are going to be installing and using depend
04:44upon that being 5432.
04:46So I am going to go ahead and press Next.
04:48We will accept the Default locale, press Next, and I will press Next one more
04:52time and it will go ahead and install.
04:55This takes just a couple of minutes. And now the server should be running.
05:00I am going to go ahead and uncheck this stack builder.
05:03This is not something you really need.
05:05If you want to run it, it's okay; it won't hurt anything.
05:07You can install some additional tools. But it's not necessary for the purpose of this course.
05:11So I am going to press Finish, and the Postgres server is now installed and running.
05:16So if I come up here at the Applications menu and go into Other, you will notice
05:20there's a number of applications here.
05:22One of them is called pgAdminIII. And I am just going to drag that up there to
05:26my launch bar, and I am going to click on the little Postgres elephant there
05:32and run this admin.
05:34I'll make this a little bit more full-screen for our purposes here, and you'll
05:40notice that it has found the Postgres server that we installed, running on
05:44localhost at port 5432.
05:47So when I double-click on that, it'll ask me for the password for the user
05:51that it created called Postgres. And so you'll want to remember that password, type it in there.
05:56I am going to click on Store password, which saves that password so I don't
06:00need to type it in again.
06:01You may or may not want to do that.
06:03If you don't, that's okay;
06:04you will just need to type the password every time you connect to the server, and
06:08that's fine. And certainly in a production environment
06:10you would never save this password.
06:12But for our purposes, just for demonstration and for experimentation, it's
06:18probably perfectly okay, on your desktop machine, to store that password.
06:22So I am going to say OK and get this lovely warning. I'll say Don't
06:26show me that again, and say OK, and now I am connected to that server.
06:31So the server is running, and the pgAdmin application is running just fine.
06:35Now I am going to create a couple of users here.
06:38Now, it would be perfectly acceptable to just create a login user called SID or
06:43web or something like that, and that would be fine.
06:46But I want to show you another feature, because Postgres is an
06:49object-oriented database.
06:50It allows users to inherit from other users.
06:53So this is actually pretty cool, and it's something that you might use in
06:56production in the future.
06:57So we will go ahead and do it now, so that you know how.
07:00I am going to create a Group Role, and this Group Role is going to be called web,
07:04and then I am going to create a login role called SID that will inherit the
07:08Group Role. And that will allow me to have databases that are owned by web that
07:13are used by different users, and it makes it really easy to do that.
07:17So I am going to create this Group Role.
07:19I select Group Roles and I click this cool button here, which is basically the
07:23"create a new object of that" button.
07:26So if I were to select Databases, it would create a new database. See, it
07:30says New Database.
07:31Click on Group Roles and press this button,
07:33it says Create a New Group Role.
07:35So I am going to create a New Group Role and I am going to call it web, and
07:38under Definition, I am not going to put in a password, because it's not a login role at all.
07:43Under Privileges, I am just going to leave it blank like it is.
07:46Role membership none, Variables none, SQL, this is the SQL that would create
07:51this if you were to type it into the command line client.
07:54But for our purposes, really all we need is that Role name web, and I am just
08:00going to say OK. And now I am going to create a Login Role that inherits that.
08:04So I select Login Roles, I click on the New button.
08:07It says New Login Role.
08:08I am going to call this one sid, because that's the name of the program that we
08:11are going to be using it with.
08:12And under Definition, I am going to give it a password.
08:14I am going to type the password.
08:16I am going to tell you what it is, because this is the default password in my
08:20scripts, and it just makes it convenient, since all we are doing is using this
08:24for demonstration purposes.
08:25This is probably okay, so it is foo.bar. And if you use that password, it
08:32will make things a little bit easier; otherwise, just remember what password you put in--
08:36you are going to need it later.
08:37And again, you will notice under Role Privileges, we are just going to
08:42inherit from the parent.
08:44Under Role membership, we are going to give it a parent.
08:46I am going to select web and press this right arrow, and that makes a Member of
08:50web, so it will actually inherit the role web.
08:54And then under Variables, nothing. Under SQL, this is the SQL that you would use
08:58if you are going to create this role in the command line client.
09:02But we're just going to click OK at this point.
09:04It doesn't need any more privileges but to inherit from web. And now we have a
09:08Login Role called sid that inherits from the Group Role called web--
09:13See, it says GRANT web To sid--and there is also a Login Role called
09:17Postgres--that's our superuser.
09:18We are not going to actually use that one for anything.
09:21And then we come over here to Databases and create some databases that are going
09:24to be owned by web, but sid can use them because sid inherits web.
09:28See, that's pretty cool!
09:29So I'll click on this new button and create a new database and this one will be
09:33called test, and its owner will be web.
09:37And again, I don't need any of this other stuff--this is the SQL that will be
09:40used to create the database--and I just press OK.
09:44And I'll do another one, and this one will be called album, and it's also owned by web.
09:50And one more. This one is called world, and it's also owned by web.
09:57Now let's populate those databases.
09:59So I am going to select the database called test, and I am going to come up here
10:02and I am going to press the SQL button, and this brings up this nice little
10:07query application. And I am going to open a file with some queries in it.
10:12So on my desktop I've got the ExerciseFiles, and inside the ExerciseFiles for
10:16this course you'll see a folder called SQL. And I'm just going to select
10:20the one that says test-pg.sql, and that is the SQL for creating the tables in our test database.
10:29So it has got all this cool SQL in it right there.
10:32So I just open that up and press Run, which is this green button right there, and
10:38you will notice that it creates the tables and it works just fine.
10:41So I close that and I select the album database and I do the same thing again:
10:46press the SQL button, open a file, Desktop/ExerciseFiles/SQL/album-pg.sql,
10:55and I select Run and close this. And one more time for the world database:
11:01SQL, open a file, Desktop/ ExerciseFiles/SQL>world-pg.sql, open and run.
11:13This one takes a little bit longer, and now it's done, so I'll close that.
11:18So now we have created these three databases that are owned by web, which means
11:22that they can be used by sid.
11:24And now you have Postgres installed.
11:26You have databases created.
11:28You have databases populated with data.
11:30For example, if I were to select the test database here and open the SQL query
11:35application and just type in a simple query, "select*from view_tables;"
11:44and press the Go button right here, see, we get a result.
11:48We have three table names--
11:51customer, item, sale--and the owner name is web for all three of those.
11:56So in fact, you could do all of the exercises in this course that don't have
12:00anything to do with PHP, which is most of the course, right here from this query
12:05application, and you wouldn't need to install the Apache web server.
12:08You wouldn't need to install PHP.
12:10You would need to install the SID and CRUD applications. And you could really
12:14actually do most of course from right here.
12:17Now I am going to go ahead and install those other things, because this course
12:21is also about how to use Postgres from PHP and I just like the sid application
12:27for demonstrating the SQL.
12:29So follow along with me if you want those things.
12:31If you really want to follow along with everything in this course then do
12:34follow along. That's fine.
12:36But I just want to let you know that you can do most of this course from right
12:39here without actually installing the rest of these things.
12:43So I am going to close this and no, I am not going to save my changes to that.
12:47And we are done with pgAdmin for now, so I am going to close that. Now we are
12:51going to go ahead and install Apache and PHP, and we are going to do that from
12:55the Ubuntu Software Center.
12:57So here in the Ubuntu Software Center, I am going to search for PHP5, so in
13:01the search box I type "php5," and you see it's a server-side HTML embedded meta package.
13:08So this is a package that installs all the things that are necessary to run PHP,
13:12including the Apache web server.
13:14So I am going to just click on Install here, type in my password, and you notice
13:20a little progress bar slowly moving across that little space right there.
13:25That's installed now, and that installs and starts up the Apache server with PHP.
13:31And now here in the search box, I am just going to search "php5_pg.sql," and that
13:38is the Postgres drivers for PHP5.
13:40So I will select that and install that, and now PHP and its drivers for
13:47Postgres and the Apache web server were all installed.
13:50So I am going to close the Ubuntu Software Center, and now back here in our
13:54command line, I am just going to type "clear" here, so that we can get a clear screen.
13:59Now I need to do a couple of things so that we can actually use the Apache web
14:03server without having to become root all the time.
14:06So I am going to create a symbolic link from the root of the web server file
14:10system to my home directory.
14:12So I just type "cd" by itself and that will change to my home directory, and I'm
14:17going to create a symbolic link to the Apache web server document root.
14:23So the way this works is like this.
14:24I type "ln -s" for symbolic links, "/var /www." That's the document root of the
14:33Apache web server as it was just installed.
14:36And I put in a dot or a period to refer to my current home directory and press Return.
14:42Now I have a symbolic link to that document root, but that document root is
14:47owned by the root user,
14:48so I can't really use it yet.
14:49So I am going to change directories into that document root, cd www, and I am
14:56going to change the permissions.
14:58So first thing I am going to do is I am going to change the group ownership of
15:03the directory to admin, because my user is a superuser on my desktop machine. I
15:08am part of the admin group.
15:09So I say sudo, because I have to do, this is a superuser, because the directory
15:13is owned by root, and chgrp to change the group ownership of the folder.
15:19Type the word admin, which is the superuser group on this machine, and I know
15:25that my user is part of that group, and a dot refer to the current directory. Press Enter.
15:31It asks for my password.
15:33Now this may be actually different on your machine, and I'm just going to have to
15:37assume that if you are using Linux that you have a little bit of understanding
15:40of how permissions work on your machine, because different distributions of
15:44Linux are going to do this in a different way.
15:46I know that this is working on this version of Ubuntu--and it will probably work
15:50on future versions of Ubuntu as well.
15:52Now I am going to change the permissions of that same directory by saying sudo
15:56chmod, so it changes the permissions-- mod is the mode or the permissions--and
16:02775 and a dot. So that will make it so that the group ownership also has
16:10read/write permissions to this directory, and I need that, because I am in the
16:14group and I am not the owner.
16:16And finally, there is a file in this directory called index.html.
16:19If I say ls -l, you will see that the index.html is owned by root, and that's
16:25not going to work, because I am not root.
16:26So I need to do one more change of ownership.
16:29I am just going to say sudo, chown-- that changes the ownership of the file--
16:34billw--that's my user;
16:36you are going to use your own user--and index.html.
16:40Now when I ls -l, you will see that that file is owned by me.
16:45And so I can edit if I need to.
16:47So now we need to restart the Apache web server, and the reason we need to
16:52restart the Apache web server is because after starting the web server, we
16:56installed the Postgres drivers.
16:57So that's really the reason.
16:59It's not these permission changes;
17:00we wouldn't need to restart the server for those.
17:02But because we installed a driver after we installed and started the web server,
17:06we need to restart the web server.
17:07So sudo and then /etc--
17:12that's the et cetera directory--/init.d-- that's where the initialization startup
17:19scripts go--/Apache.
17:21And I am just going to type the first few letters and press the Tab key, so I
17:25get Apache2 and then the word restart, and that will restart the web server, and
17:30you will see it says restarting web server Apache2.
17:33This error message about the server's fully qualified domain name, that just
17:36means we are not running a name server, and that's fine. It's working okay.
17:40You will notice that it says okay over there on the right-hand side of the window.
17:44So we have now restarted the web server with our drivers, we have the
17:48permissions that we want in the document root directory for the web server, and
17:52now we are ready to go ahead and install our applications.
17:55So I am going to close this terminal window.
17:58I am going to type "exit."
17:58Now I am going to open up my exercise files, which are here on the Desktop.
18:04I've copied those on the desktop earlier. And I am going to create another
18:08window here by pressing Ctrl+N--N like in new--and that creates another window
18:14where I can get to my www.
18:16So you can see I am in my home directory, and there is the symbolic link for the
18:20www directory--that's the document root for the Apache web server.
18:24I am going to double-click on that.
18:26There is my index.html file, and I am going to come over here to my ExerciseFiles.
18:30I am going to select CRUD, and hold down the Ctrl key and select sid, so
18:35those two are selected.
18:36Now I am going to press Ctrl+C to copy.
18:39See, at the bottom it says, "The 2 selected items will be copied if you select the Paste command."
18:44So I come over here into the www folder and I press Ctrl+V, like Victor, for
18:50paste, and it copies those two folders over.
18:53Now if you entered a different password than I did, you'll need to go and edit
18:57the passwords in these two applications.
18:59So first, we will open the CRUD directory, and we will edit crud.php file.
19:04I am right-clicking on it. I am going to say open with text editor, and that opens the GNU text editor
19:10g-edit. And I'm just going to scroll down here, and you see where PGSQLPASS foo.bar,
19:18so that's my default password that I use.
19:20So when you get these exercise files, that will be the password that's in them.
19:23And if you set that password for the sid user, you see, here is the sid user,
19:28then you will be able to open those databases that this application needs.
19:33So change that if you need to and save and close and do the same thing in the sid directory.
19:40So I click on www, and I double-click on sid, I open sid.php, and we will scroll
19:47down, and there is the same thing.
19:50There is the user, sid, and the password, foo.bar.
19:54So change that if you need to, save it and close it, and now we're ready to test
19:59these applications in our browser.
20:00So I am going to open the browser here.
20:02Now we've installed a web server on our local machine.
20:05That web server has PHP support.
20:07Now, we've installed the drivers for PostgreSQL server
20:12that's also installed and running on our local machine, so all this is
20:15running on our localhost.
20:16So I type in localhost, and if I just press Enter here, you'll see I get the It works.
20:22That means that the web server is running.
20:23That's that default index.html file in the www directory.
20:28And now if after localhost/ I type in CRUD, all caps--
20:34that stands for Create, Read, Update, Delete, those are the four basic functions
20:38of any database application--
20:41and I press / and CRUD again in lowercase .php, and I am going to press my
20:46Enter key, and there is our CRUD application.
20:49You see it's accessing the database, because it has got data up here.
20:52You will notice at the bottom it says "PostgreSQL Server version 9.1.1."
20:56That means it is connecting successfully to the server and getting that version number.
21:01So PHP is working, Postgres is working, the web server is working. And now we
21:06come up here and we just edit our URL, and instead of CRUD, we put in SID, all in
21:11caps/sid in lowercase .php, and I am pressing the Enter key. And now we are
21:17running the SQL Interactive Demonstrator.
21:20You see it's connecting the database fine.
21:22There is our databases that we populated.
21:25So for example, if I select the test database and I say
21:28select*from view_tables;--
21:35that's a special view that is defined in that database to just list the tables
21:40that are defined in the database--
21:42and I press the Go button, there you have it.
21:44Those are the three tables:
21:45customer, items, sale, owned by web.
21:48This is exactly the same query that we put into the pgAdminIII query application,
21:55and you see we are getting exactly the same result.
21:57So now, if you followed along this far, you have installed the Postgres server,
22:02you've installed the Apache web server with PHP,
22:05you have installed the Postgres drivers for PHP, and you have installed the SID
22:09and CRUD applications successfully.
22:12This is everything you need to follow along with all of the exercises in
22:15this course.
Collapse this transcript
Installing XAMPP and SID on a Mac
00:00In order to run PHP on your Mac, you're going to need a web server, and you're
00:05going to need the PHP system.
00:07The easiest way to do this is to install XAMPP on your Mac.
00:11There is another course in the lynda.com online library that teaches you how to
00:16install XAMPP on your Mac, and we're just going to go ahead and do it here
00:19anyway, because we're also going to be installing a few things on top of it, and
00:23this just makes it easy.
00:24So if you already have XAMPP, just follow along until the point where we're
00:28installing SID and CRUD, and then follow those instructions. Or you can do the
00:32entire installation, along with this movie.
00:35This is the Apache Friends web site, and you'll notice this is at
00:38www.apachefriends.org/en/xampp-macosx.html.
00:47XAMPP is spelled X-A-M-P-P, and I pronounce it ZAMPP because I just can't think
00:52of any other way to say it.
00:54So this is the page where you would download that from and if you scroll
00:57down here a little bit, you can see this is the link. And I have already
01:01downloaded this, and I have it here on my desktop, and I am just going to
01:05double-click on that.
01:08Installing XAMPP is very simple.
01:10You simply take this XAMPP directory and drag it over to the Applications
01:14directory and you watch it copy thousands and thousands of files.
01:18Now that's done and I eject that, and I am going to bring up the
01:24Applications folder.
01:29You see, down here at the bottom, there is XAMPP, and there is the XAMPP
01:33Control.app, which I am going to drag down to my dock, and then I am going to run that
01:39when I say Open. Notice it brings up this little Getting Started window.
01:44I am going to uncheck that and close that.
01:47And all I have to do here is start Apache; I don't need MySQL and I don't need
01:51FTP. So I am just going to click Start. For Apache, it's going to ask me for my
01:55password, and then I get a green light.
01:57If you don't get that green light for some reason, one thing I would check is
02:01I'd go into System Preferences, and I'd go into Sharing, and I'd make sure that Web
02:05Sharing is not checked.
02:07If Web Sharing is checked then you won't be able to run Apache and this green
02:11light will now come up.
02:12So when the green light is up, Apache is running and I can close that, and I can
02:17bring up my Firefox here and I can type in localhost, and we get this Splash
02:24screen for XAMPP. And if you click on English, then you won't get the Splash
02:28screen again in the future, and you have all these things.
02:31You can check your status.
02:32You can check all of these different things.
02:34You don't need MySQL; all you really need here is PHP and as long as PHP says
02:39Activated, then you're fine.
02:40So I am going to go ahead and close Firefox.
02:42I am pressing Command+Q. And now we're going to install the SID and CRUD applications.
02:48Again, this is very easy to do.
02:50I am going to click on htdocs here, and I am going to open up my ExerciseFiles,
02:55and I am simply going to drag over and copy.
02:57I am going to hold down the Option key while I drag it, so that I get the little
03:01plus sign that means it's copying.
03:03I am going to copy that over.
03:05Type in my password.
03:06I am going to do the same thing for the CRUD folder.
03:08So I am copying over the SID folder and the CRUD folder.
03:13So now before we can bring up the SID application and test it, we need to edit it.
03:18So I am going to open this with BBEdit, which is the editor that I am running on
03:21the Mac--whatever text editor you're running.
03:24And remember, you'll need a text editor that is not a word processor
03:27that's a plain text editor.
03:29I recommend BBEdit or TextWrangler, which is its little brother.
03:33But whatever text editor you're running, you'll want to open sid.php with that,
03:37and you're going to need to edit this password right here.
03:40This is the password that you entered for the SID user in Postgres, and so that's
03:45just the password that I entered in mine. And you'll want to type whatever
03:49password it is that you entered in your version right there on Line 27, and then
03:54you'll save it, and you'll do the same in the CRUD application.
03:59So we'll come up here to CRUD and open crud.php with your text editor and come
04:05down here on Line 22 and enter the password you entered for your SID user when
04:11you set up your Postgres. And I will close that and close the editor.
04:16Now, when I bring up Firefox, I am going to type in "localhost/SID/sid.php" and there it is.
04:27You'll notice down here you have SID Version 2.3.7, which is correct, and we have
04:33Postgres Version 9.1.1, which is the version of Postgres that I am running.
04:37Yours may be a little bit later.
04:39So that means we're connecting successfully to the database and we're running PHP okay.
04:44You'll notice the databases here.
04:45We have three databases installed--
04:47test, album, and world--and those are the databases that we installed earlier.
04:51If you get an error message that says something about the password, then you
04:54didn't get the password the same in the sid.php file as when you set up your SID
05:00user in pgAdminIII. And if you get something about not being able to connect to
05:05the database then that means that Postgres is not installed properly.
05:08If Postgres is installed properly, it's going to be running all the time. And it
05:12doesn't take up much resources when you're not connecting to it, but if it's not
05:16running, then it's not installed properly.
05:18So I am going to go ahead in here and select the test database.
05:21I am just going to type in here in the SQL field.
05:24I am just going to type in SELECT * FROM view_databases;
05:34and press Go, and we should get this result--
05:37test, album, and world--says 3 rows returned and elapsed time. Your milliseconds
05:42will be different than mine.
05:44And let's just change it here and say view_tables, and I've still got the
05:50semicolon in there, and I say Go, and I get a list of the tables in the test database:
05:55customer, item, and sale.
05:57Go ahead and select the album database, leave that SQL the same, and press GO.
06:01You get the tables and the album database, album and track. And do the same for
06:05the world database and press Go:
06:08city, country, and country language.
06:10Now, let's go ahead and also test the CRUD application.
06:13So I am going to change this URL here to localhost/CRUD, which stands for Create,
06:19Read, Update, and Delete--four basic functions of any database application--and I
06:24am going to type /crud.php.
06:28Here's our CRUD application, and if it does this, then that means it's working.
06:33We have the CRUD version down here, the PHP version, and there is data coming
06:36from the album database.
06:38So installing XAMPP and SID and CRUD on your Mac is actually a pretty easy thing to do.
06:44Just download it, drag it over to applications, enter the passwords in those two
06:48files, and you're off and running.
06:50And so this is all the things that we need to have installed on the Mac in order
06:53to follow along with the exercises in this course.
06:56Before we finish, there is one more thing we need to do.
06:59We need to make the exercise files available to the web server.
07:03We do that by making a copy of the Exercise Files folder and pasting that into
07:07the web server's document root.
07:08So we'll start by opening a new Finder window, and we'll navigate to Applications
07:15and XAMPP and the htdocs folder within XAMPP, and then I am simply going to take
07:22this ExerciseFiles folder.
07:23I could Option+Drag, or I am just going to right-click on it and select Copy, and
07:30then right-click inside the htdocs folder and select Paste.
07:35Type in my password, and this will make a copy of the exercise files that's
07:40inside of the document root for the web server.
07:44Now, when I bring up the browser, I will type in localhost/ExerciseFiles like that.
07:53It brings up these exercise files in the browser, and that allows me to run the
07:59PHP programs that are in the exercise files.
08:01So I am just going to take this and put that on the toolbar so I can select
08:06that whenever I want.
08:07I am going to do the same thing with SID because we're going to use that quite a bit.
08:10There is SID and drag that into the toolbar. And so now whenever I need my
08:17exercise files, it's there;
08:18whenever I need SID, it's there. And that makes this nice and easy and convenient.
08:23So now we have successfully installed XAMPP, set up the web server, and now we
08:27can use this set of for exercises in the rest of this course.
Collapse this transcript
Installing XAMPP and SID on a PC
00:00PHP is a technology that typically runs in a web server,
00:03so in order to work with PHP, you will need a web server.
00:07Now you can do this using a web server on the Internet somewhere, but it's
00:11really much more convenient to use a web server installed on your local
00:14development machine.
00:16For the purposes of this course, I'll be using a package called XAMPP
00:22to provide a PHP development environment that includes an Apache web
00:25server running PHP.
00:27I've already installed Postgres on this machine--
00:30this machine is running Windows 7--
00:32but unfortunately, the latest versions of XAMPP have some incompatibilities with Postgres,
00:38so we must use XAMPP version 1.7.3 for our Postgres compatibility.
00:43So I provided a copy of XAMPP 1.7.3 here on my web site, and you'll find this at pgsql.bw.org.
00:55And right here you can download the win32.
00:58That's the Windows version of XAMPP.
01:00There is no 64-bit version of XAMPP.
01:02This is the win32 version of XAMPP that I'm using in this course, version 1.7.3.
01:09I've already downloaded this, and I've saved it here on the Desktop, and there it
01:13is, so I'm going to close the browser.
01:14Now there's one more thing we need to do before we install XAMPP:
01:17we need to make sure the User Account Control is disabled.
01:21Like most server software, XAMPP will not run properly with Windows User
01:25Account Control enabled.
01:27So we'll come down here to the Start menu, and I'm going to open up the Control
01:30panel, and I'm just going to, in the Search up here, type in uac, and there it
01:35is, Change User Account Control Settings.
01:39So I'll click on that, and you'll notice that it says here "Never Notify."
01:43That means that it's turned off. And of course Windows is complaining that
01:47this is not recommended. That's okay.
01:49It's a development machine, it's behind a firewall, and it should be okay to run it this way.
01:55If you turn on User Account Control later, it will create problems with XAMPP,
02:00so you need to keep this turned off while you're running XAMPP.
02:04So in this machine, it's already turned off.
02:07If in your machine it's not turned off, you're going to change this and when you
02:11click OK, it will ask you to reboot, and you'll have to reboot your computer
02:14before you go ahead and install XAMPP.
02:15So I'm just going to say OK, I'm going to close this, and now we can install XAMPP.
02:21I'm going to right-click on this so that I can run the installer as an administrator.
02:26It's also very important before you run this installer that you disable your
02:31virus scanner on your machine.
02:33You can enable it again once it's installed, but you need to disable it for the
02:37purposes of the installation.
02:39So I'm going to go ahead and run this as an administrator.
02:41I'm going to accept the default destination here, which is the root drive on C:\--
02:46it's actually important that it gets installed there--and click Install, and now
02:52it installs a bunch of files.
02:54Now, XAMPP is a development environment.
02:56It's not meant to be a production environment.
02:59Do not install XAMPP on a production server.
03:02It's got all of its security stuff turned off.
03:04It's really just meant to be run on a local development machine that's behind a
03:09firewall and is not accessible on the Internet.
03:13So here at the end of the installation process, it's running a setup script in a
03:17command window, and we're just going to accept the defaults here.
03:20Yes to adding Start menu. So I'm pressing the Return key actually and accepting
03:25default here for the shortcuts.
03:28And I'm accepting the default for the paths, and this is actually really
03:32important--XAMPP doesn't work well if you change the paths.
03:35This is another one that's also important.
03:37It's for the same reasons.
03:39You just accept the default, which is a No here.
03:41I'm pressing the Return key again. And moving some things around and it's done.
03:46I'm going to press the Return key, and the time zone, you can change this later
03:51in php.ini and my.ini.
03:54So I'm just pressing the Return key, and here I'm going to type the letter X and
03:58press Return, and XAMPP is now installed.
04:02So you'll notice a shortcut on the Desktop here for the XAMPP control panel, and
04:07I'm going to double-click on that, and that's how we start the servers.
04:11Now I'm not really interested in any of these other ones except the Apache server.
04:15But before I press Start for the Apache server, I'm just going to leave that alone there--
04:20if you've jumped ahead and pressed Start, you can just press Stop;
04:22that's fine--because we need to edit something in the PHP configuration file in
04:28order for it to work with Postgres.
04:30So I'm going to go ahead here and open an Explorer window, and I'm going to go to Local C:
04:35disk and open the xampp directory, which is off the root of the local C: Disk.
04:41And in here I'm going to double-click on php folder, and I'm going to scroll
04:45down until I find a file called php.ini, and I'm going to open this with my text editor.
04:51Now I've got Notepad++ here installed on this machine.
04:55It's really important that you don't use a word Processor, and also that you
04:58don't use the Notepad file that comes with Windows, which is notorious for
05:02changing line endings.
05:04And then those line endings get changed
05:06you don't see it on the screen, but it really messes with stuff, and it
05:10makes things not work.
05:11So that's why I've got this Notepad++.
05:14You can search for Notepad++ in Google or wherever you do your searching and
05:19simply install it for your machine.
05:21It's a pretty good full-featured text editor for the kinds of purposes that we have here.
05:26And I've opened this file before apparently, so it wasn't at the beginning, but
05:30I'm just going to bring it up to the beginning so I can show you.
05:32And I press Ctrl+F, like Find, and I search for pgsql.
05:37I'm going to press Enter, and I'm just going to close this Search box because
05:43it has now found it.
05:44Now you'll see a line here that says extension=php_pdo_pgsql.dll. And there's
05:52a semicolon at the beginning of that line, and that makes it commented out, as we say.
05:57So I simply remove that semicolon, and now that line is active.
06:01And then a few lines down you'll see another one here that just says php_pgsql,
06:08and that one also I'm going to uncomment.
06:11I'm going to remove that semicolon, and those are the two lines that we need to change here.
06:17So those lines are now uncommented, and I'm going to click Save.
06:21First, I'm going to close the file, or I'm going to press the little x there to close the file.
06:25And then I'm going to close Notepad++ and close this Explorer window, and now we
06:31can start PHP and this will all run fine.
06:34So I'm going to start the Apache web server, which provides PHP, and you see the
06:39little green Running comes up.
06:41That's exactly what we want.
06:42I can close this control panel now, and I can bring up my browser, so I'm going
06:47to bring up Mozilla Firefox.
06:49Now if I just type in localhost, it will connect to the Apache web server and
06:55make sure that that's running,
06:57so I'm just going to do that. And we get this screen that says XAMPP, and it's
07:00got a bunch of languages here.
07:01If we click on English, we get the little XAMPP Status page, and you can click on
07:06Status, which is right under Welcome here, and it takes just a moment while it
07:10checks what's running and what's not running.
07:12And you see that PHP is active, and that's the thing that we are the
07:16most concerned with.
07:18PHP is working, and so that's all we need there.
07:21So now I'm just going to close Firefox, and we're going to go ahead and
07:24install SID and CRUD.
07:27So I'm going to open up the ExerciseFiles here off of my Desktop.
07:29These are the exercise files that come with this course.
07:32And in here you'll notice two folders: one called SID and one called CRUD.
07:36We're going to need those, but first I need to open another Explorer window for
07:40the destination of where we're going to copy them.
07:42So I'm going to press Ctrl+N for a new Explorer window and just kind of move it
07:48over here to the side on the screen, and I'm going to come back down here to
07:51local disk, the xampp directory, and under xampp, you'll find htdocs.
07:57This is what's called the document root directory for the Apache web server.
08:02So I double-click on that. It's got just a few files in it, but what I want to
08:06do is I want to copy these SID and CRUD folders.
08:09So I'm going to select the CRUD folder, and I'm going to hold down the Ctrl key
08:13while I select the SID folder, and that will select these two.
08:16I'm just going to press Ctrl+C to copy and then come over and select the htdocs
08:22folder and press Ctrl+V to paste, and it copies over those two folders.
08:29Now here's where you have to pay attention to that password that you entered for
08:34the SID role in Postgres.
08:36When we installed Postgres, we installed a user, or a role, called SID, and we
08:43gave it a password,
08:44so you'll need that password right now.
08:46So I'm going to open the SID folder, and I'm going to open the sid.php in my editor.
08:52So I right-click on it and select Edit with Notepad++.
08:57And right down here at line 27 you see it says PGSQLPASS, and it says foo.bar for that password.
09:06And that's where you'll put it in the password for your sid user.
09:09So on the line above it, it says sid is the user, and even though it says PGSQLUSER,
09:15it's actually called a role in Postgres.
09:17So that's the sid role, and the password is foo.bar.
09:21If you didn't change the password, if you used the same password that I used in
09:24the installation of Postgres, then you probably don't even need to edit this
09:28file, but I just want to show you how to do it so you know how.
09:31So I'm going to close this, and then we're going to go and do the same thing
09:36in the CRUD directory.
09:39Right-click on crud.php.
09:41There it is, on line 21 and 22. The user is sid, and the password is foo.bar.
09:48So once these two files are edited, we can close this, we can close this, and we
09:53can bring up our web browser again. And this time we're going to type in
09:57localhost/CRUD/ and that's all caps, and then lowercase crud.php.
10:07CRUD stands for Create Read Update Delete.
10:10These are the four basic functions of any database application, and this is
10:14just an application written in PHP that demonstrates these four functions in Postgres.
10:19So I press Return and it brings up the CRUD application, and you can see it's
10:24reading data from the database. Everything is working fine.
10:27So we're going to do the same for SID.
10:29So I'm just going to select that part of the URL, I'm going to type in SID
10:34in all caps, and then sid.php, and it brings up the SID application.
10:40This is the SQL interactive demonstrator.
10:42This is what we'll be using to learn about the particular SQL syntax for Postgres.
10:49You'll notice down here it says Postgres server version 9.1.1, so it's
10:53successfully connecting to the server.
10:56And we have these three test databases listed here, so I'm just going to
11:01select one of them.
11:02I'm going to select test. I'm going to type in here some SQL, SELECT * FROM sale;
11:11and Go, and that's the same result that we got in the Postgres SQL Query application.
11:18So we can see it's successfully connecting to the database, and it's successfully
11:22sending queries and getting results from the database.
11:26So this means that we have successfully installed XAMPP.
11:30We've successfully installed the Postgres drivers for PHP.
11:35We've successfully installed the application programs from the exercise files
11:40SID and CRUD, and all of this is working well with the Postgres server that we
11:45installed in a different movie in this chapter.
11:48So now we can use these tools as we go ahead and run the exercises in the
11:53rest of this course.
11:55Before we finish, there is one more thing we need to do.
11:58We need to make the exercise files available to the web server, and we'll do that
12:02by making a copy of the Exercise Files folder and pasting that into the web
12:06server's document root.
12:08So we'll start by bringing up an Explorer window here. And I'm going to
12:12select the local disk C:, double-click on the xampp directory there and
12:17double-click on htdocs--
12:19that's the document root right there--and you see that it's got the SID and CRUD folders.
12:23And I'm going to come over here and I'm going to just make a copy of
12:26this ExerciseFiles.
12:27I could Ctrl+Drag it, or I can just right-click on it and select Copy, and then
12:34right-click on the Explorer window here in the web server document root and
12:39select Paste, and that makes a copy of that ExerciseFiles folder.
12:45Now I'll just bring up my web server. And when I type in localhost/ExerciseFiles
12:54and make sure that I capitalize it write--this is case sensitive here--and there
12:58we see that I've got those exercise files right there.
13:01So I'm just going to drag this onto my bookmark bar and I'm also going to
13:06put SID there as well.
13:08So I've got SID there, localhost/SID/sid.php, and I'm going to put that also on
13:14my bookmark bar, so I can get back to SID when I want, and I can get back to the
13:18exercise files when I want, and that makes this all really easy.
13:22So now we have successfully installed XAMPP, and we've set up the web server, and
13:29now we can use this setup for the exercises in the rest of the course.
Collapse this transcript
1. Quick Start
Getting the most out of the Quick Start
00:00This chapter is for those of you who are familiar with another relational
00:02database management system and who know enough PHP and SQL to get your job done
00:07and are looking to get up and running with Postgres as quickly as possible.
00:11For the purposes of this quick start, an experienced developer is someone who has
00:15experience using PHP or another similar C-like scripting language, and
00:20experience with SQL and another SQL-based database management system.
00:26The examples in this chapter use a PHP sandbox script as a template.
00:30Before you continue, it's important that you update the password in this file to
00:34match the password you entered when you created the sid user in the pgAdmin.
00:39You see here on line 14 I have foo.bar.
00:42This is where you'll need to put the password for your sid user exactly as you
00:46entered it in pgAdmin.
00:48Let's take a look at here.
00:49This is in PHP, and we're just going to start at the bottom for our purposes
00:53right now. And down here at the bottom you see there is a function for displaying
00:57errors, there is a function for displaying error messages, there is a function
01:01for just displaying a message, and there's a function for displaying content.
01:05These functions, combined with some CSS, make your screen look like this.
01:11Then going back up to the top, you see we have some variables are defined.
01:16We bring in the bwPgSQL.php library-- and that gets described in some detail later
01:22on in the course--and we'll call an init function, the main function where the
01:26work is done and a page function to display the pages.
01:30The init function defines some global variables, initializes an array for the
01:35display variables, and connects to the database, creates a table, populates that
01:41table, and it does all of this within a try block so that it can handle
01:45exceptions for errors.
01:49Then the main function displays some messages, starts a timer, which is then
01:54displayed at the bottom, and has another try block for whatever database
02:00operations we're demonstrating in this particular exercise.
02:04So this is where the bulk of the work is done here in the main function.
02:08Then finally this page function brings in a header, a body, and a footer PHP
02:13pages, and fills in the variables that display the actual content on the screen.
02:17So this is what it looks like in the browser.
02:20This is our start.php script, which is the same one when we're looking at here in the editor.
02:26And you see the little bit messages where it connects to the database,
02:30it populates the database with four rows in the table, and it displays the
02:34content there in the main function.
02:37The examples in this chapter also use a PHP library called bwPgSQL.
02:42It's basically a wrapper around the PHP functions that use Postgres and the
02:48Postgres driver--and this library is explained detail later in the course.
02:53It uses PHP's excellent PDO interface for talking to the database, and it
02:58provides direct SQL support, as well as simple CRUD functionality.
03:02Feel free to use this library as a starting place or to write your own
03:06library from scratch.
03:07The library provides a simple object-oriented interface that can be a real
03:12timesaver for you, with very little performance cost.
03:16It supports most common database operations.
03:18It uses placeholder arguments for SQL parameters.
03:22It has a CRUD interface--that's Create Read Update Delete--the basic four
03:26functions of a database application.
03:29The CRUD records are passed as convenient associative arrays.
03:33Rows are also returned as associative arrays.
03:36It does not provide support for prepared statements, although it does use
03:39prepared statements internally for performance.
03:42So again, this chapter is a quick start.
03:44If you have the necessary experience and knowledge, this should help you get up
03:48and running with Postgres quickly and easily.
Collapse this transcript
Creating a database
00:00As with most operations in Postgres, databases are created using SQL.
00:05While it's certainly possible to just open up the pgSQL command line interface
00:09and type "Create Database," this is not generally the best way to do it.
00:14Instead we're going to use the pgAdmin III application to create a database.
00:19So I'm just going to double-click here on the Postgres9.1 server and it'll go
00:25ahead and login to that, because we had saved the password here before.
00:28If you haven't saved the password, you might need to type your password.
00:30And I'm going to select the databases here, and we'll see that we've got these
00:34three databases that we've already created plus the Postgres database, which is
00:38required and will always be there.
00:40You should never delete that.
00:41It's used by the system.
00:43So now to create a database all I do is, with this database is selected here in
00:48the Object browser panel, I just click on this magic button up here, the
00:53"create a new object of the same type" button, and that will bring up the New Database dialog.
00:58So I'll just type in a name for the database--
01:01I'm going to call this one foo-- and I'll select an owner for it.
01:05We'll just select web for the owner.
01:07And you'll notice it's got a few tabs here.
01:09Under Definition, we have a place for encoding.
01:12UTF8 is of course a very common and useful encoding.
01:16See, there is a lot of other encodings available there.
01:18We're just going to leave it at UTF8.
01:20There is a place for a template, and you'll notice that there are a lot of names
01:24of databases in here.
01:26There is also this template1 and template0.
01:28So because of the object-oriented nature of Postgres, all databases inherit from
01:33one of the template databases.
01:36The template1 database is the default database.
01:38If I just leave it at the default and don't select a template, it'll use template1.
01:42And template1 is there--you can actually modify that.
01:45You can add things to it, like one common use for this is to modify it so that it
01:50includes a language for stored procedures. And you can also inherit from
01:55template0 if you like.
01:56template1 inherits from template0, and template0 is basically the one that you're
02:01never supposed to modify.
02:02This will always be the default.
02:04You should leave that one alone, in case you have modified template1 and you
02:08still want to be able to get the default database.
02:11So you can also use any of the other databases that you've created and use one of
02:16those as a template as well.
02:18But in this case we're going to just leave the default, and that's what you'll
02:20probably do most of the time.
02:22You can also select a tablespace if you create tablespaces.
02:25This allows you to store your data on different volumes in different
02:28places within your system.
02:30That might be valuable for a large data store or a large
02:33production installation.
02:35Of course, we're not going to use anything like that here.
02:37For our purposes, we are just really going to accept the defaults for
02:40most things, because all we're doing at this point is we're learning
02:43about the database,
02:44we're exploring the database;
02:46we're learning how Postgres works. So for Collation,
02:49you have a choice between C and POSIX, and there may be some other choices in your
02:54installation. Character type, likewise, and as long as the encoding as UTF8, you're
02:59probably just fine with the defaults.
03:01Connection Limit of -1 just means there's no limit.
03:05Under Variables there is a lot of different variables that you can set, and these
03:09are mostly be used for performance enhancement and setting certain defaults and
03:14options within the database.
03:16Again, those are the kinds of things you'd probably set in a template and then
03:20just inherit them for your production databases.
03:23Under Privileges you can set your privileges with some pretty good granularity,
03:27and you can have different privileges for different roles. And then in the SQL
03:31tab of course, we just tab the SQL that will be used to create the database with
03:35the options that you've selected throughout the rest of the tabs.
03:38In this case it's just very simple create database statement.
03:41So we go ahead and say OK, and that creates our database.
03:45So now we have this foo database there, and we can go ahead and use it.
03:49So I'm going to bring up the SQL Query Editor, and I'm just going to type in here
03:53CREATE TABLE foo (a TEXT, b TEXT);.
04:02And I'll go and run that.
04:03As you can see we get a message that says, "Query returned successfully."
04:06Of course, there is no result because there's no result from a CREATE TABLE,
04:10but it created a table. And now we can insert some data into it, and we'll see
04:15INSERT INTO foo VALUES. And I'll just put a couple of rows of values in here,
04:21('one', 'two'), ('three', 'four'); and I'll run that, and you'll see two rows affected.
04:35So that means we've inserted data into two rows of the table, and now I'll just
04:39say SELECT * FROM foo and run that and we get the result in our data output.
04:46So I'm going to go ahead and drop that table and execute that, and we can close
04:54this and say no we're not going to save our changes, and then we can go ahead
04:59and we can drop that table as well.
05:01I can select Delete/Drop from the context menu like that, or I can just click on
05:06this trashcan icon with the database selected and that will go ahead and
05:11drop the database foo.
05:12So you can see that pgAdmin makes it easy to create databases and to manage our
05:19permissions, and to even create tables and populate them.
05:22Once you have the database created, you can use it from whatever interface you
05:26have designed it for.
Collapse this transcript
Creating a table
00:00Creating a table in Postgres is easy;
00:02you just use the SQL CREATE statement to define the columns that you're using.
00:07So let's go ahead and create a table in a PHP script.
00:11We're going to start with this create- start.php file, and I'm just going to make
00:15a working copy of it here, and I'm going to name that create.php.
00:21That way if I need to revert back, it's easy to do. And I'm going to open
00:25that in my text editor.
00:27Before you continue, it's important that you update the password in this file to
00:31match the password you entered when you created the sid user in pgAdmin.
00:36You see here on line 14 I have foo.bar. This is where you'll need to put the
00:40password for your SID user exactly as you entered it in pgAdmin.
00:45Now this is based on the sandbox we're using for this quick start chapter, and
00:50the difference here is that my init function really doesn't have anything in it;
00:55instead, I'm going to be creating the table here in the main function.
00:59And inside this try block, so that I can catch exceptions,
01:03I'm going to go ahead and instantiate the database object. So I'll put out a
01:08message, creating the db object,
01:13and I'll use a variable called db = new bwPgSQL( PGUSER, PGPASS, DATABASE,
01:28TABLE_NAME)--and these are all constants that are defined up here at the top.
01:34There they are: PGPASS, PGUSER, DATABASE, TABLE_NAME. And I'm also going to
01:40set a variable for the TABLE_NAME, and that will allow us to use it in the strings below.
01:49Now we're going to create the table, and I'll put out a message that
01:52we're creating the table. And we'll use that db object, and we'll use the sql_do method.
02:04Keep in mind that the bwPgSQL library is explained in a lot of detail later on in the course.
02:11Now we're going to use Postgres special syntax for conditionally dropping a
02:16table if it already exists, which is DROP TABLE IF EXISTS.
02:21A lot of database systems have that same syntax, so it might look familiar. $tn,
02:26that's the table name there, and that's just a simple way of making sure that
02:32we're starting with a fresh table each time.
02:34Again, I'm going to do the sql_do, and this time I'm going to CREATE TABLE $tn.
02:42It looks like I used an h up here by accident, so I'm going to correct that.
02:47My command completion was not giving me the correct variable there, and so now
02:54I know why that was.
02:56Now I'm going to define the columns.
02:58The first column is id column, and it's going to use SERIAL PRIMARY KEY as its type,
03:07and that's a special type in Postgres that's basically an automatically
03:12incrementing integer.
03:14It's great for ID columns.
03:16And I use this because in the bwPgSQL library, for the CRUD functions, they
03:22depend on an id column having that property.
03:26So this actually makes that same library work great across different
03:30database technologies.
03:31I can use pretty much the same interface for Postgres, for MySQL, for SQLite.
03:38And then we'll have a couple of text columns: animal and sound--the sound
03:44that the animal makes.
03:48So that creates a table.
03:49It's got three columns: this automatically incrementing column called id and an
03:54animal column and a sound column that are both text columns.
03:57Now I'm going to go ahead and insert some records.
04:00And again, I'm going to use this sql_do("INSERT INTO $tn, animal and sound)--
04:15we'll use those columns--and VALUES. And we're going to use the placeholders
04:20here, SQL placeholders.
04:23And that part will remain the same for each row. And we'll have a cat.
04:28We'll make it purr, how's that?
04:32And now I'm just going to copy that, and all I have to change is the animal--this
04:38one would be a dog--and the sound, woof.
04:44And duck, and it will say quack, and a bear, and it will say grrr.
04:55Now I'll put out one little message here, and this one tell us how many rows
05:02there are in the table.
05:03It will use the count_recs method from the database library, and now we're going
05:19to drop the table just to put it back in its original state.
05:28See my command completion is working properly there now, and we'll put out a
05:32message that we've dropped the table.
05:34I'll put it in italics.
05:44You notice that my message function uses variadic variables just like printf in C.
05:50So there we have it.
05:52Just look over it; make sure there aren't any typos.
05:54We instantiate a new object from the database library,
05:58we assign this variable tn, TABLE_NAME, Create the table, DROP TABLE IF EXISTS.
06:04Here's the CREATE TABLE SQL, and that all looks right.
06:07We insert some records using SQL placeholders--
06:11that's a really valuable feature there-- and display a message, how many rows in
06:15the table, and then we drop the table and put out a message to that effect.
06:19So I'm going to go ahead and save this--
06:22I'm pressing Command+S to save the file-- and switch to the browser, and we'll go
06:28ahead and load it up and see if it works.
06:31So there's the create.php, and there it is.
06:34So here we're connecting to the database.
06:36We've got the database version.
06:38We created the db object, create the table.
06:40There are four rows in the table, and then we dropped the table, and that all
06:44happens in 28 milliseconds.
06:46So there you can see, creating a table in Postgres is just like in most SQL-based systems:
06:52it's simply a matter of defining your columns using SQL. And we'll cover in more
06:56detail on the various data types that Postgres supports later on in this course.
Collapse this transcript
Inserting data into a table
00:00Inserting data into a table is accomplished with the SQL insert statement.
00:04Let's see how this is done in a PHP script.
00:08We are going to make a working copy, starting with the start.php file, and I am
00:14going to name this "insert."
00:17Open it in the editor.
00:19Before you continue, it's important that you update the password in this file to
00:23match the password you entered when you created the sid user in pgAdmin.
00:28You see here on line 14 I have foo.bar.
00:31This is where you'll need to put a password for your sid user exactly as you
00:35entered it in pgAdmin.
00:38Now we see in the init function we are going ahead and creating the table, and
00:43then in the main function I have this little marker "database operations go here."
00:49And I am just going to replace these three lines, this foreach loop, with the
00:54database operations for this example.
00:57So we are going to start by inserting a row into the table.
01:01Now you will remember that this table has a SERIAL PRIMARY KEY and id column
01:07that's automatically incremented, and as we insert this row, we want to get a
01:13value back that's going to be that new ID, because we don't know what the id is going to be.
01:18So I am going to create a variable for that, and we are going to insert a horse.
01:21We need another animal, so we will call this the horse_id.
01:25And I am going to use the db->sql_query value. And we will put our SQL inside
01:35these quotes here, and we will say INSERT INTO $tn--
01:39that's our table name--and the columns animal and sound, and VALUES
01:50will get the SQL placeholders. And then it's going to say RETURNING id, and
01:59that is a syntax that is specific to Postgres.
02:02That allows an insert statement, which is normally not a query statement, not
02:07a statement that returns any value, to actually return the value of the next
02:12sequential id. And this is specifically, it matches up with the SERIAL PRIMARY KEY.
02:18So you use the returning clause, and you give it a column name. And I am just
02:24going to go to the next line here for our parameters, because remember, we need
02:28two parameters for these placeholders right there.
02:32So those parameters are going to be horse, and the horse has to make a sound, and
02:38of course a horse is going to sing the song for Mr.
02:41Eddie, "A horse is a horse, of course, of course," because that's the sound that horses make.
02:50We are going to put in a MESSAGE, and we are going to echo back the id number that we got.
02:59We are going to say Added id number %d, and that will be horse_id. And now we
03:10are also going to add another record, but this time we are going to use the CRUD syntax.
03:15So you can see both ways of doing this.
03:17One way uses the SQL, and the other ways is arguably easier. Let's add a bird.
03:21So we will give it a bird_id.
03:24So we will use db->insert, and we will give it an associative array. And the first
03:34named element will be animal, and we will call it bird. And then we will give it
03:40a sound, and its sound will tweet, because that's the sound that birds make.
03:48Tweeting is not just for Internet-crazed teenagers.
03:52Again, we are going to say Added id number, and this time it will be the
03:59bird_id. And now we'll spit out how many records there are in the table. And we
04:17will go ahead and we will retrieve the two rows based on their id number.
04:21We are going to do this in two different ways:
04:23we are going to do this once using SQL and once using the CRUD methods.
04:29So the SQL will use db->sql_query_ROW, and it will say SELECT * From $tn WHERE ID =
04:45and we will use the SQL placeholder question mark, and we will pass in the
04:49horse_id. And then we will go ahead and display it.
05:03Again, we are using those printf-like placeholders, because message uses format
05:09just like printf. And we will dereference the row array. What we got back from
05:14the SQL query row in $row is an associative array,
05:18so we de-reference it just like any associative array in PHP.
05:21Like that, $row'id;, $row'animal', and $rowsound.
05:38Now we are going to do exactly the same thing using the CRUD methods, and you
05:42will see how much easier it is.
05:43We just say row =$db->get_rec, and we pass in the bird_id.
05:52And that's as simple as that.
05:53So this line is basically the equivalent of that. And then I'll go ahead and I
06:01will just copy this message, because that's going to be exactly the same, and we
06:05should get the same results.
06:07So I am going to go ahead and save this.
06:08I am pressing Command+S here on my Mac. And we will look at it again and just
06:12make sure that there are any typos.
06:14We have the horse_id =, and there is our SQL INSERT INTO $tn, (animal, sound),
06:20VALUES (?, ?) RETURNING id.
06:22Of course, that returning clause, that's Postgres-specific SQL right there.
06:28We pass it the word horse and the sound that the horse makes, which is the horse,
06:33of course, singing the song. Added_id number %d. There's the horse_id. Then we do
06:39the same thing for the bird, except this time we used the CRUD methods, insert
06:43(array(animal, => 'bird', 'sound' => 'tweet'.
06:46And we have the right number of parentheses there. And we put out the message
06:51for the bird, and then how many rows there are in the table, and then we do our queries.
06:57So we get SELECT * From $ tn WHERE id = ?, $horse_id--
07:03that looks right--and the message for the horse, and then we do to get_rec, which
07:08is very simple, and the message for the bird.
07:11So we will go ahead and we will save that, pressing Command+S again, and we will
07:15go and load it up in the browser.
07:16There is insert, and there we have it.
07:21So here we have, there are four rows in the table to start, and that is actually
07:25up here before our database operations go here.
07:28So where the timer starts, it then says there are %d rows in the table.
07:32So that's always going to say 4, because so that's how many are inserted in
07:36the init down here: we have for animals.
07:39So it starts with, There are 4 rows in the table, and we Added id number 5, Added id number 6.
07:44So that's that returning clause in the insert statement--that's specific to Postgres.
07:51That's how you get your serial ID.
07:53Now there are six rows in the table, and here they are.
07:56We have the horse says "A horse is a horse, of course, of course,...," and
08:00the birds says "tweet."
08:02The horse of course was done with the SQL, and the bird was done with the
08:07simple CRUD method.
08:09We dropped the table and a lapse time, 29 milliseconds.
08:13So we can see the inserting data into a table with Postgres in PHP is as simple
08:17as using the SQL insert statement or using the CRUD facility from the library.
Collapse this transcript
Getting data from a table
00:00Retrieving data from your table with Postgres in PHP is simply a matter of
00:04using an SQL query.
00:06Let's take a look at how this is done in PHP.
00:09We're going to make a working copy of the start.php here, and we're going to
00:14name that retrieve, I before E. We'll go ahead and open that in the text editor.
00:23Before you continue, it's important that you update the password in this file to
00:26match the password you entered when you created the SID user in pgAdmin.
00:31You see here on line 14 I have foo.bar.
00:34This is where you'll need to put the password for your SID user exactly as you
00:38entered it in pgAdmin. And come down here to the "database operations go here."
00:45The first thing we're going to do is we're going to use the query row and get a
00:52row, which will be a associative array;
00:55$db->sql_query_row("SELECT * FROM $tn WHERE animal = and the SQL placeholder,
01:11which will get replaced with the string duck.
01:13So this will retrieve the row for the duck.
01:18If we look down here in our insert statements, that's probably row number 3.
01:22Then we'll go ahead and display it with the message call. And so that will be
01:32$row 'id', and I'm just going to cut and paste here for the rest of them.
01:36And because this is an associative array, we just de-reference it like this, like
01:40any associative array in PHP.
01:43We have animal and we have sound, and that is how we do that.
01:51We can also get a single value, and here we'll just use a message call.
01:57We'll say value result:
01:59%s for a string, and we'll just say $db ->sql_query_value("SELECT sound FROM $tn,
02:16our table name, WHERE animal =?
02:24And that question mark of course is the SQL placeholder, and we're going to
02:29give it the string dog.
02:30So that will give us the sound that a dog makes.
02:35Finally, oftentimes we're going to want to simply get a whole bunch of rows,
02:41and so here we can get all of them.
02:43We can say foreach get_recs as row. Actually, this is going to be exactly the
03:02same as this one, just indent it.
03:06Then for each row, it will go ahead and display that line.
03:10Now, you'll notice that we're calling this get_recs in the place of an iterator,
03:16in this iterative foreach, and that's because the library has been written as
03:20such that that conforms to the iterator pattern. And it will simply get each
03:25record one at a time, rather than filling up a whole array and taking up a whole
03:30lot of memory and a whole lot of processor and then spitting out all the
03:34records in a separate loop.
03:36So this is actually a very, very efficient way to do this.
03:40So looking at it again, we're querying a whole row here in the first one, and
03:44we're putting that in an associative array and displaying it one row at a time,
03:50and then we're getting a single value here, selecting sound.
03:54And then finally, we're iterating through the whole table using the CRUD method get_recs.
04:01So go ahead and save this.
04:02I'm pressing Command+S on the Mac here, and we'll bring up the browser and go to
04:08Chapter 1, and this is retrieve.php.
04:12So here we have the third one is duck, like we predicted that it would be, and
04:17the value result is woof, like we predicted that it would be, and then here is
04:21all four of the records with the CRUD iterator.
04:24So retrieving data with Postgres in PHP is simply a matter of constructing
04:30an SQL query just as you would in another environment or using the CRUD
04:35facility from the library.
Collapse this transcript
Updating data in a table
00:00Updating data in your table is simply a matter of writing the SQL and
00:03passing the data in.
00:06We'll start by making a working copy of start.php, and we'll take a look at how
00:10this is done in PHP.
00:12We'll call this one update.php, and we'll open that in the text editor.
00:17Before you continue, it's important that you update the password in this file to
00:21match the password you entered when you created the SID user in pgAdmin.
00:26You see here on line 14 I have foo.bar.
00:29This is where you'll need to put the password for your SID user exactly as you
00:33entered it in pgAdmin.
00:35And scrolling down here to the "database operations go here" section,
00:42we'll start by grabbing a row using SQL.
00:48So that will get us the row for the dog, and we'll go ahead and display it with
00:54the message function. And we'll break out those variables from the row, starting
01:10with the ID and the animal and the sound.
01:19Now once we know the ID, we can put that in a variable, and then we can update
01:32it. And we'll do that with SQL here.
01:43We'll use sql_do because in this case we don't have any return value.
01:51We'll use the SQL for updating, and this is just standard SQL right here.
01:56("UPDATE $tn SET sound =, and we'll use the placeholder there, and the dog will
02:05now say bow wow instead of woof.
02:09We also need a where clause, WHERE id =?,
02:14and we'll need a second parameter with the $id variable.
02:19Now, let's do this again with the CRUD methods.
02:22We'll start by assigning the row. We'll use get_rec.
02:30Since in this case we already know the ID, we can just use it there.
02:36We'll go ahead and display the values so far.
02:41In this case, we'll display the bow wow, and now we'll go ahead and update it
02:46with the update method instead of the SQL.
02:49So we'll call db->update, and we'll use the ID to indicate which row we're updating.
03:06And in the array, all we need to specify is the column that we're updating.
03:14We don't need to specify all of the columns.
03:19This time it will just say ruff.
03:22Now again, we'll just get the record and display it using that same code from a
03:27couple of lines above.
03:28We queried the row, we got the record for the animal dog, and we displayed it,
03:35and then we updated it using SQL--and this is very standard SQL;
03:39there's nothing unique here for Postgres-- and then we went ahead and we queried
03:44the record from the database, and we displayed it, and then we updated it again,
03:48this time with CRUD.
03:50This time we're using this update function, and then we use get_rec and display it again.
03:55So let's go ahead and save this, pressing Command+S and go ahead and run it in the browser.
04:06And there it is!
04:08The dog initially says woof, and then we update it and then he says bow wow, and
04:13then we updated with CRUD, and then he says ruff.
04:16Again, updating data in our table is very simple:
04:19simply use the SQL update statement and pass the data, or we can use the CURD
04:25facilities and an associative array.
Collapse this transcript
Deleting data from a table
00:00To delete rows from your table, you simply use the SQL delete statement, and
00:05we'll take a look at that in PHP, making a working copy here of start.php.
00:10I'm going to call this one delete.php. And of course when you're all done,
00:15you're welcome to delete it.
00:18Before you continue, it's important that you update the password in this file to
00:22match the password you entered when you created the SID user in pgAdmin.
00:27You see here on line 14 I have foo.bar.
00:30This is where you'll need to put the password for your SID user exactly as you
00:34entered it in pgAdmin.
00:36I'll start down here in the main function, where we have the "database
00:41operations go here."
00:43We'll just delete this foreach, and we'll go ahead and delete record 3.
00:50So I'll say $id = 3 and message( 'deleting id %d' $id. And then we'll use the
01:05sql_do("DELETE FROM $tn WHERE id =, and we'll use the SQL placeholder
01:16question mark there and type the variable name after it. And then we can say 'after delete:
01:26There are %d records in the table,' and then we'll call count_recs.
01:37Then we can also just go ahead and display all the records here. And then we can
01:48just do exactly the same thing again.
01:50I'm just going to copy and paste all of this.
01:52But instead of the sql_do, we're going to call the CRUD method, which is
01:58simply called delete.
02:00Of course, record 3 will already have been deleted, so we'll delete record 2 instead.
02:08So now in our first little block here, we're deleting using SQL, using a
02:13standard SQL delete statement. And we display a message that there are so many
02:19records left, and we display all the remaining rows in the table. And then we do
02:23the same thing again using the CRUD delete method. So let's see how this works.
02:27We'll go ahead and save this pressing Command+S, and we'll bring up the browser
02:33and go to Chapter 01 and delete.php.
02:38So it starts out with 4 rows in a table.
02:39We delete ID number 3. After delete,
02:42there are 3 records in the table, and this is them.
02:45We see that number 3 is missing. And then we delete id:
02:492 and after delete:
02:50there are 2 records in the table, and all that's left is 1 and 4.
02:54So in order to delete data from your table, you simply can use the SQL delete
02:59statement, or you may use the delete function from the CRUD facility in library.
Collapse this transcript
Creating a database library
00:00As you've seen in this chapter, a simple database wrapper library can be a
00:04very convenient thing.
00:05Let's take a closer look at the library we've been using in this chapter so you
00:09can see what's involved in creating your own.
00:11So down here in this lib folder in the Exercise Files, you'll notice a file
00:17called bwPgSQL.php, and that's the library that we've been using throughout this chapter.
00:23I am going to open that in the editor.
00:25I'm just going to say this at the outset: you are welcome to use this however you see fit.
00:31If you do redistribute it, if you do make any modifications to it, I just ask
00:35that you leave these comments up at the top here, so people will know where it came from.
00:41So it starts out by declaring the class bwPgSQL and some private variables that
00:46are used throughout the library, and then we have the constructor.
00:50You'll notice at the top of each function I have a little usage so that when I
00:54look at this I know how to use that particular function.
00:58So this is the constructor, and it gets passed a user, a password, a
01:02database, and a table_name.
01:03You'll notice that there is a default value for the table_name, so that
01:06parameter is actually optional; the other ones are not. Then I use PDO.
01:11Throughout this library I'm using PDO.
01:13PDO is PHP's portable object-oriented database library.
01:18I think it stands for Portable Database Objects. And it makes it really
01:23convenient to write these wrappers and then simply modify them for
01:27different databases.
01:28I've got pretty much the same code that I've written for MySQL and also for
01:32SQLite, and all of these wrappers work exactly the same, so I can simply unplug
01:36one and plug in another one, and everything continues to work.
01:41I have a lovely little note here about how PHP doesn't play nice with Unicode,
01:45and the truth is is that it's starting to get a little bit better.
01:48They've been working really hard on it. It seems like forever.
01:51But the code hasn't really propagated, and it's not really very consistent and done yet.
01:55So it still makes sense to set the client encoding to Latin-1.
02:00Unfortunately, Latin-1 is ugly any place except in the United States.
02:06So here I've got some setters and getters for the table_name, for the database
02:11handle, for statement handles.
02:14This allows a little bit of extra flexibility in the library.
02:17I rarely use any of those. And then the actual fun begins.
02:22The first method is sql_do, and you'll notice that it takes a variable number of
02:27arguments, and this allows us to use those cool SQL placeholders, the question
02:32marks for placeholders.
02:34It returns a count of the rows affected. And as you can see, this is really just
02:39a matter of calling prepare and execute from the PDO library.
02:47Then I simply have wrapper for the PDO's exec, which allows you to pass in a
02:52string with multiple lines of SQL.
02:55I recommend never using that, but it's there for completion.
03:00sql_query is pretty cool because it returns an iterable statement handle.
03:05This allows us to do cool things like using it in a foreach loop.
03:10query_all is another one of those "don't ever use this one."
03:14It basically calls fetchAll, and it fills up memory with every row in a table
03:19that matches the query.
03:21So it's very, very easy for you to crash your program with this.
03:24I recommend that you never use it.
03:25Again, it's just there to be complete.
03:28sql_query_row returns one row from a fetch; sql_query_value likewise returns one value.
03:38You'll notice that all of these methods will throw PDOExceptions in the case of errors.
03:43And way up at the top, in the constructor, I set the ERRMODE to ERRMODE_EXCEPTION,
03:50which means that any of the PDO calls themselves, like the Prepare, the Execute,
03:56any of those will throw PDOExceptions if there is a problem.
04:01Then we have the simple begin_ transaction and commit, for transaction handling,
04:07and now we have the CRUD stuff.
04:08The CRUD stuff is where this gets really fun.
04:11We actually construct SQL on the fly from the parameter.
04:16So the first one is get_rec.
04:17This one is really simple.
04:18Simply SELECT * FROM the table_name WHERE id = the id value that gets passed in.
04:25So that one is really simple.
04:27Likewise, get_recs sets up a statement handle and returns it so it's iterable,
04:32and this allows us again to use the cool foreach loops.
04:37Again, the SQL construction is pretty straightforward here.
04:40INSERT is where things start getting a little bit more interesting.
04:44You'll notice that to construct the query, I have to use joins from the
04:49associative array that gets passed in.
04:52I have that cool RETURNING. Just like in our SQL in the insert movie, we're
04:58using the Postgres extension returning to return the value.
05:02This makes this actually really much more elegant than it does in another
05:06library like MySQL where you have to make a separate function call.
05:11UPDATE likewise requires us to create the SQL on the fly, based on
05:18the associative array.
05:20I find this just to be really, really convenient.
05:22It allows me to bury all of this complexity in a library.
05:28It allows me to not have to worry about that kind of complexity in my code.
05:32I can just pass around associative arrays and everything just works.
05:36So I only had to figure this out once and then it's done.
05:41Now, DELETE is very simple.
05:43It's simply a delete statement in SQL.
05:46There is a pseudo-iterator called get_next.
05:48This comes in handy every once in a while, when you don't want to use a foreach
05:52loop, you want to be able to get the next record adhoc and different types
05:56of loops and in different types of places.
05:58Likewise count_recs;
05:59this is something that's a little bit unusual for Postgres. SELECT COUNT(*) in
06:04most databases is actually a very, very efficient thing to do, and it gets
06:09optimized out of the way very, very efficiently. Because of the construction of
06:14the Postgres databases--and they say that it has to do with the fact that it's
06:18object oriented--this is not actually that efficient in Postgres.
06:22Postgres does its writes asynchronously and its reads asynchronously.
06:26It doesn't actually keep track of how many records are in a database at a given
06:31time, or in a table at a given time, and so this is not as efficient as it is in
06:36some other databases.
06:38And last_insert_id, again, just to be complete, this is something that's very
06:43convenient in other databases like MySQL, and so I've implemented it here
06:48just to be complete.
06:51table_exists is a convenience function for finding out if a table exists before
06:55you go and create it, and in case for some reason you don't want to do a drop
06:59table if exists. And then there is a little thing for getting the version and
07:05the methods for the timer_ start and the timer_end.
07:09So a database wrapper like this can be a very convenient and useful tool.
07:13Feel free to use this library for your own projects, or to use it as a starting
07:17point to create your own.
Collapse this transcript
2. Creating a Database
Understanding databases and tables in PostgreSQL
00:00As a starting point, it's good to understand how a Postgres database works.
00:05In Postgres a database is a general container.
00:08It stores both data and metadata.
00:11It includes the tables related to the database, as well as metadata describing
00:16permissions and other attributes related to the database.
00:20An application communicates with a database driver that knows how to talk to
00:24the Postgres server.
00:26This allows the application to log in to the server with the appropriate
00:29credentials, and to send SQL statements and receive replies, including rows of
00:34data from the tables in the database.
00:37The driver then communicates with the server on behalf of the application,
00:41exchanging the credentials, statements, and data responses with the server.
00:46The database in turn contains tables, among other things.
00:50Those tables contain the rows and columns of data that make your application
00:54do that thing it does.
00:56So in order to create a database application, you must create the database,
01:00design and code the tables, using rows and columns of relevant data designed to
01:05interact and express the intention of the application.
01:09In this chapter, we'll look at how to create databases and tables in Postgres.
Collapse this transcript
Creating a database
00:00In order to create a database in Postgres, you will need to have sufficient
00:04permission, and while it's possible to assign sufficient permission to a normal
00:08user or, say, a user that's only logged in from a particular application, it's
00:14generally a bad idea.
00:15So you'll normally need to have superuser permission in order to create a
00:20database. And given that restriction, the easiest way to create a database is to
00:24launch the pgAdmin application, where you have superuser permission by default.
00:30So here's the pgAdmin application.
00:33I am going to double-click on our database here
00:35so we get logged in, and click on Databases.
00:39You can see here the databases that we've already created when you installed
00:42Postgres, and the Postgres database, which is the default database it's the
00:46administrative database--
00:48you need that in order for the system to work,
00:50so don't ever delete that one.
00:52Now let's go ahead and create a database. This is very easy.
00:55We simply select Databases in the object browser and press the magical "create
00:59one of these" button, and that pops up a new database dialog box.
01:04We can type in the name of the database.
01:05We will just call this foobar, and we will type in an owner.
01:09We will select web over here. And really at this point, ninety-nine times out of a hundred,
01:15you're just going to press OK, and it will create that database. But let's just
01:20take a quick tour through the different things that you can do.
01:23Under Definitions you can change the encoding.
01:25There are a lot of law encodings available.
01:27Of course UTF-8 is going to be perfect for most purposes.
01:31You can select a template. Because of the object-oriented nature of Postgres,
01:36databases inherit from other objects, and these templates are what they inherit
01:40from, for the most part.
01:42Some of these templates you will notice are other databases, and then there is
01:46template0 and template1.
01:47template1 is the default.
01:49template1 actually inherits from template0.
01:52In the default configuration of Postgres as it comes out of the box, so to speak,
01:56they're exactly the same.
01:58So you can modify template1 if you like, for whatever defaults you want to have
02:03like perhaps you want a particular language for stored procedures or something
02:07like that, or perhaps you want some defaults tables, you can modify template1
02:11and then by default, whenever you create a database, that database will follow that template.
02:16You'll never mollify template0; that's considered a bad thing to do.
02:21Or you can simply use one of your existing databases for a template.
02:24In our case we are just going to accept the default.
02:26Tablespace is about where your data is stored, and under most circumstances
02:31you're not going to modify that;
02:33all the data is going to be in place. But with very, very large databases with
02:37distributed storage you might want to change that, and you might want to create a tablespace.
02:41Coalition and Character type just have to do with the character sets, and really
02:47you're going to want to leave those alone almost always and simply change the
02:51encoding if you need to do that.
02:54Under variables there are a lot of variables that you can customize
02:58your database with.
03:00Most of these have to do with things like optimizations.
03:03You can change time zone on a database basis, things like that.
03:08For the most part, again, you're not going to use this, but if you need to, it's there.
03:12Postgres allows you to have a certain amount of granularity for your privileges.
03:16You can have some users that are allowed all privileges, some users that are
03:21allowed just to connect, some users that are allowed to create data. And under
03:26the SQL tab, this simply shows you the SQL that you would use if you were going
03:30to create this database,
03:31like, for instance, in the command line client or in a PHP script, if you have
03:36those kinds permissions.
03:38For our purposes, this is all just fine.
03:40We are just going to select OK, and we have created our database, and there it is.
03:44It says foobar.
03:46Once the database is created, I will typically create an SQL file with the table
03:50definitions and any initial data that I want to populate those tables with.
03:55In our Exercise Files of course, in the SQL folder we have a few examples of this.
04:01We did this when we installed Postgres and one of these, albums-pg.sql,
04:07let's take a look at that.
04:08Bring that up in my editor, and you can see what's in it.
04:11I set the role to web so that the tables as well as the database are owned by web.
04:17Otherwise, if the Postgres superuser is creating the tables, even though the
04:21database is owned by the web role, the tables might be owned by Postgres and
04:26then a web user wouldn't be able to modify them. So I set the role,
04:31I drop if they exist, and otherwise I create some views and these views,
04:37we will be using these throughout the course.
04:40These are views for viewing tables and viewing databases.
04:42These are views for viewing things from the system tables in the Postgres database.
04:49Then I create a couple of tables, and then I insert some rows of data.
04:54So it's a pretty simple script and yet it's really very useful to do things this way.
05:00So let's go ahead and see how we would import this data.
05:03I simply select the database and press the SQL button and I get the SQL editor,
05:08and then I can just open this file and it reads the file in, and just press this
05:15green Execute query button and those tables are now created.
05:20So I am going to go ahead and open a new window here, and you will notice this
05:23is a separate window. That other one is still there.
05:26I can close that. And I just type in a couple of queries.
05:30I can say SELECT * FROM view_tables, and that's my view that will show me what
05:35tables exist in this database. And there they are. I have two tables:
05:41one called album and one called track.
05:44So if I want to, I can select from album and I can see all the albums.
05:50There is the title of the album and the artist of the album.
05:54This is not a terribly convenient way to manipulate your database.
05:58That's why I wrote the sid application.
06:00Now you can see that we have a number of albums in our table. And track,
06:05these are the tracks on those albums, and the table is called track, singular,
06:10and press Go there.
06:12And there is the tracks that are in that table.
06:15So I am going to go ahead and close this, and now we have populated our database.
06:21We have given it a couple tables, we've given it some views, we've given it some
06:24rows of data, and now it's ready to use with our application.
06:28So for our purposes here, I am going to go ahead and drop this table.
06:31You'll want to know how to do this anyway. As you're experimenting, as
06:34you're originally designing your database, you're going to create and delete some databases.
06:39Deleting a database is called dropping it.
06:42So to drop this database, I simply select it here and press the trashcan icon
06:47and it says, "Are you sure you wish to drop database foobar?" and I say Yes.
06:53And that database is now dropped.
06:54So when I select Databases over here, we see we just have our original four databases.
06:59So, pgAdmin makes it very easy to create databases and to manage their
07:04permissions and their content, and the included SQL query editor is a convenient
07:09tool for defining and populating the tables in your database.
Collapse this transcript
Defining a table in SQL
00:00Creating a table in Postgres is accomplished with the SQL CREATE TABLE
00:04statement, and it looks like this.
00:07We're here in the SID application, and you'll notice I've got the test database
00:11selected. And I'm going to go ahead and create a table called foo,
00:14so I will type CREATE TABLE. And I am going to name that table foo. And I'm
00:21going to give it a column definition here.
00:23First column will be animal, and that's a text column, and the second column
00:28will be sound, and that is also a text column.
00:31There are a lot of different column types available in Postgres, and we will
00:35cover what those are and how they work in another chapter.
00:39So I'll go ahead and press the Go button now and lapse time 6 milliseconds, and
00:45that table is now created.
00:47If I try to create the table again, if I press Go again, you'll notice I'll
00:50get an error that that relation, as it calls it, already exists and so it
00:56cannot create that table.
00:58And if I take a look at the tables that are already defined in this database, by
01:02typing SELECT * FROM view_tables;--and this is a view that I've created that's
01:09in all of the databases in our example databases--and it will give me a list all
01:13of the tables that are available in this database.
01:17So you'll notice that we have three that are owned by web--
01:20customer, item, and sale--and those are the one that we populated the database
01:24with initially when we installed Postgres and created these databases,
01:28and then the one that we just created called foo, which is owned by sid--and sid
01:33is the user that we're logged in with in the SID program.
01:37So now we have created that table foo.
01:40We can put some data in it if we like.
01:42And over here in my text editor I've got open this 02-examples.sql from
01:47the Chapter02 folder in the exercise files, and down here I've got some
01:53INSERT statements here.
01:54I am just going to copy those and paste them in.
01:58And I will press Go.
02:01And you see that four queries were performed, four rows affected, which means that
02:04we actually inserted data into four rows in this table.
02:08And so now I can look at that data.
02:09I can type SELECT * from foo;
02:14and I see the rows of the table that we just inserted are returned down there.
02:19Now, as you noticed before--I am going to go ahead and take my CREATE TABLE
02:24statement again and paste that back in-- as we noticed before, if I try to create
02:29this table again and press Go, it gives me an error.
02:33And so if you have a script, like a PHP script for example that has some SQL in
02:38it, and you want to make sure that table is available,
02:40you would like for that script to be able to create the table. But if it just
02:44says CREATE TABLE like this then it will always give you an error.
02:48Instead what you can do is you can use this extension, which is a Postgres
02:52extension; you can say CREATE TABLE IF NOT EXISTS.
02:57And this will just create it if the table doesn't exist.
03:00If the table already exists, it won't create the table again, and it won't erase
03:04the data in your database.
03:05If I say Go, that table was left alone, and if I put in my SELECT statement
03:10again, our data is still OK.
03:16On the other hand, if you want to make sure that you are starting with a fresh
03:19table every time, you want to know if the table exists, and if the table does
03:24exist, you want to drop that table first and then go ahead and create it.
03:28So you can do this with the DROP TABLE IF EXISTS foo. So that's an extension to the drop table statement.
03:38Normally you'd just say DROP TABLE and it would go ahead and drop the table
03:42unconditionally, but if the table didn't exist, it would give you an error.
03:46So this allows you to conditionally drop the table.
03:49And I am just going to paste in my CREATE again, and I'm going to go ahead
03:53and put in our SELECT after this, and you can see that it will create an empty table.
03:59So three queries performed. We dropped the table, we created the table, and
04:03selected Not return any data, so that data is now lost because we dropped the
04:08table that had the data in it.
04:10So if I go ahead and just populate that again--I'll copy these lines for the
04:14SELECT--and so now what we have here is, we drop the table if it exists and
04:21we create a fresh table, and we insert four rows into it and then display those rows.
04:26So if I press Go, we have exactly four rows.
04:30Now, because I am dropping the table every time, it creates those rows fresh
04:35every time in a fresh table.
04:36So if I press Go again, we have the same four rows.
04:40If instead I don't do the DROP and I do a CREATE TABLE IF NOT EXISTS then it
04:48won't create the table if the table is already there.
04:51This is the way that you would do it in an application that just wants to add
04:55data to an existing table but create that table if it doesn't already exist.
04:59And so now when I press Go, we get four additional rows and we get
05:02four additional rows.
05:04So creating a table in Postgres is simply a matter of defining your columns
05:08using SQL and managing those tables using the conditional IF EXISTS, or IF NOT
05:13EXISTS for your CREATE TABLE and DROP TABLE statements.
05:16More detail on the various data types that Postgres supports will be found
05:20later in this course.
05:22Before we go here, we're going to go ahead and just drop our table, so that we
05:29leave this database in its original state for the rest of the exercises in
05:34this chapter.
Collapse this transcript
Creating a table in PHP
00:00Creating a table in PHP is simply a matter of using the Postgres interface to
00:04create the table using SQL.
00:07Let's take a look at an example of how to do that.
00:09Here is the Chapter 02 folder of the exercise files.
00:12You'll notice that this is the copy that's in the document root of the web server.
00:15You'll notice I've turned on the path bar at the bottom of this file window here
00:21so that you can see that this is under XAMPP and htdocs, and so this is where we
00:27put a copy of the exercise files that's accessible to the web server.
00:30So I'm going to make a working copy of start.php here, and I'm going to name
00:35this createtable.php, and I'm going to open that in my text editor.
00:42Before you continue, it's important that you update the password in this file to
00:46match the password you entered when you created the sid user in pgAdmin.
00:51You see here on line 14 I have foo.bar.
00:54This is where you'll need to put the password for your sid user exactly as you
00:58entered it in pgAdmin.
01:00This is a version of the sandbox frameworks that I've created for this course,
01:06Most of the examples of this are in the quick-start chapter, but all of the supporting
01:10files for this sandbox are in the free exercise files.
01:14So, if you have this course, you have those free exercise files.
01:18They don't require Premium membership to have access to them. And so this uses my bwPgSQL.
01:25It's a wrapper for the PHP PDO interface for Postgres, and the reason for that is
01:31really just to make it simple, so that we can focus on the SQL and on the
01:37features of the database and how this works, rather than all of the details of
01:41PHP's PDO interface. And if you want the details of the PDO interface, take a
01:46look at that library, which again is in the free exercise files with this
01:50course, and you can see how the PDO interface is used from within there.
01:54So the first thing we're going to do here is we're going to take the table name
01:58and put it in a variable, and you'll notice that that's defined actually up here
02:05in these constant definitions TABLE_NAME test.
02:08Then I'm going to issue a drop table if exists statement,
02:17so with the database handle sql_do, and that allows me to just execute some
02:24literal SQL, which is the way that we do most things with a database in PHP.
02:29I'll say DROP TABLE IF EXISTS $tn, which is the table name, and then we'll go
02:38ahead and create the table.
02:39We'll use sql_do again, and we say CREATE TABLE $tn. Then we put in our column
02:49definitions id, and use SERIAL PRIMARY KEY, which creates a automatically
02:56incrementing integer--
02:58we'll talk more about this in the chapter on data types--and the animal and
03:03sound, which are both text columns.
03:10So now the database is created.
03:12We're going to go ahead and populate it and search some rows.
03:16I'm a big fan of comments in my code. And that's going to look like this.
03:26INSERT INTO $tn (animal, sound) VALUES, and we'll use the SQL placeholders there
03:39so that we can just pass those values as parameters.
03:42So it will be a cat, and the sound makes is purr, and then I can just copy
03:48this and just change the animal: cat, dog, duck, bear.
04:00Dog says woof, and the duck says quack, and the bear says grrr.
04:06Now we'll just put out a message. And again, this message, this is a function
04:13here in my sandbox code.
04:15You'll see down below here, page, set variables, content, and there is message,
04:23error message, and error down at the bottom, and that just makes it convenient to
04:28display messages on screen.
04:30There are %d rows in the table, $dbt->Count_recs.
04:41And the message function, it works like printf;
04:43it uses a variety of arguments, so that you can do things like
04:47replaceable placeholders.
04:48Now we'll go ahead and display these rows that we just added with a foreach loop.
05:03So get_recs is a convenient function here in my database wrapper library that
05:08allows us to iterate through a table, row by row, and it deposits those rows in a
05:14PHP associative array.
05:15So we'll go ahead and display that associative array like this. And then we just name these.
05:24This will be animal, and this one here will be sound.
05:29So that should be all there is to it.
05:32Here we've created the table using this SQL CREATE TABLE.
05:36We drop table if it exists, so we make sure that we have a fresh table each time
05:40we run this, and then we insert some rows.
05:43We count the rows in the table and display them one by one.
05:47So I'm going to go ahead and save this.
05:48I'm pressing Command+S on my Mac.
05:50I'm going to bring up the browser and go to the exercise files and Chapter 02, and
05:56here is my createtable.php that I just created, and there it is, running.
06:01So that's as simple as that.
06:03I created the table.
06:04I populated it with four rows.
06:05I counted them, and there are the four rows of data. Then I drop it in the elapsed time.
06:12So creating a table in PHP is really as easy as creating the table directly with SQL.
06:17You may use this technique with whatever database interface or library you're using.
06:22I'm using this library that I created.
06:24Obviously, you can create your own, or you can use mine as a starting place to create yours.
06:29This library is described in a lot more detail later in the course. And then you
06:33can use that library--either the one you created yourself or use mine--for the
06:37rest of your application.
06:39It's really that simple.
Collapse this transcript
Creating indexes
00:00Indexes are a useful tool for improving performance when searching large stores of data.
00:04They also have a performance cost on inserting rows into those index tables, and
00:11they have a storage-space cost for the space of the index.
00:14So there are some trade-offs there.
00:16Indexes are created with the CREATE INDEX statement.
00:20So for example, going back to our example SQL here from Chapter 2, we have this
00:27table that we've been using, and let's say it has got some rows of data in it.
00:33If I wanted to create an index on the animal column, I would do this:
00:53CREATE INDEX, and then the name of the index, and ON, and the table name with
00:59the column in parenthesis. And I say Go and it creates an index.
01:04And now if I want to see my indexes, I can use the view that I created and say
01:09SELECT * FROM view_indexes.
01:15I see a list of indexes, and one of them is this idxAnimal that I just created
01:20that's owned by sid.
01:22If I want to drop that index, I can drop it with the DROP INDEX statement, and
01:33that drops the index. And now if I do that SELECT again, view_indexes, you see that
01:43that index is no longer there.
01:45Now, there is a couple of other ways to create indexes that are sort of specialized.
01:49Take a look at one of these right now.
01:53And this is the primary key.
01:55Now, PRIMARY KEY is technically a constraint, and it's typically implemented with
02:01an index, as it is here in Postgres.
02:04The PRIMARY KEY constraint says that this column is going to be unique and it's
02:10going to be non-null.
02:12So if I create a table with a PRIMARY KEY--and here I'll have to drop the table
02:17first--and I create a table with that PRIMARY KEY, now I will not be able to
02:27insert null values--and I'll also not be able to insert duplicate values.
02:32So if I go ahead and insert these rows into that table, I now have those four rows.
02:37If I go try to insert them again, I'm going to get errors: "duplicate key
02:42violates unique constraint" for the animal columns, and so those rows were not inserted.
02:49There's only one set of these rows in here now.
02:51SELECT * FROM foo and you'll see we've only got one set of four rows.
02:56I also will not be able to insert null values here.
03:01So if I try to insert a null value for animal, that also violates the constraint.
03:09And you'll notice, if we take a look at the view_indexes view, that it has created
03:20a primary key index for that table--it's called foo_pkey--and you notice we have
03:25it for some of these other tables as well.
03:28Now, if I drop the whole table, DROP TABLE foo, you'll notice that its indexes
03:34get dropped as well.
03:35So I'll go ahead and do that. And now the table is gone.
03:38SELECT * FROM view_tables. The table itself is gone you seem and view_indexes, and
03:48the index is gone as well.
03:50Finally, there is one other type of constraint here. Sometimes I don't want the primary key.
03:55In other words, I don't want it to restrict null values, but I do want it to
03:59restrict values to being unique--restrict duplicates.
04:03So I can go ahead and I can say CREATE TABLE foo with a unique constraint, and
04:09that also creates an index.
04:17And of course the reason that these indexes get created for these constraints is
04:22that a search has to be done for every insert.
04:25And this is one of the things that also makes it slower, is every time you insert
04:30a row into a table with a unique constraint the database actually has to search
04:34that index and find out whether or not that key already exists, and if it does,
04:41then throw the exception and disallow the insert. So that index actually gets
04:47searched for every insert.
04:49So let's go ahead and drop this table one more time.
04:53Make sure we get our database back to its original state for the following movies.
05:02Indexes can provide performance advantages.
05:04They also have performance costs associated with them. And they can be used for
05:08constraints, as with unique.
05:10In Postgres, indexes are created using standard SQL, either CREATE INDEX or by
05:16specifying one of the constraints that creates an index.
Collapse this transcript
Indexing ID fields
00:00Like most database systems, Postgres provides a simple and straightforward
00:04facility for creating automatically incrementing integers for ID columns.
00:09This facility is called Serial Primary Key.
00:12I am just going to paste some SQL in here, and you'll see that if we create a
00:17table with a field that has a type of Serial Primary Key that this can be
00:23nicely used for an id field.
00:26So let's go ahead and create this and watch what happens.
00:31Now the first thing we will notice about this is when we take a look at the
00:35index definition--go ahead and run that query--
00:44you see that we get a primary key index.
00:47And that's just we would expect if it were text primary key or any other kind of a primary key.
00:52So that's used for the constraint so all those values are unique and non-null.
00:57Now there is another behavior here that's unique for serial columns.
01:02Let's go ahead and insert some rows here, and you will notice that these inserts
01:08are only inserting two columns: animal and sound.
01:11They're not inserting any value at all in the ID column.
01:15So I will go ahead and insert those--
01:17you can see four rows affected--and we will SELECT * FROM foo, and you see that
01:25that first column, that id column, gets a serially incrementing value for each
01:31insert; each insert gives it a new value.
01:34In fact, if we insert another row--and I'm going to just add another keyword here.
01:51This is another special Postgres thing, RETURNING id.
01:56Now usually an insert statement is a non-select statement--
02:00in other words, it's a statement that does not return any value--but in
02:05Postgres there is an extension, this returning clause, which actually causes
02:09insert to return a value.
02:11So when I run this you will see we get a value down here in the results. id 5.
02:17So it's returned us a row with one column called id and a value of 5.
02:24So when I select all our values again, you'll see that
02:29that is actually the id column for that new row that I added, 5.
02:35So what serial does is it actually creates a separate sequence generator and it
02:40marks that sequence as owned by the column,
02:42so if the sequence is dropped, if the column is dropped, or if the table is dropped.
02:47So you can actually have a serial column that's not primary key, but it's most
02:52common to use it also as a primary key.
02:55So the common usage that you will see is this one here, where that Serial Primary
03:04Key is used for the id column.
03:07Okay, let's go ahead and drop our table, put our database back in its
03:13original state. And the Serial Primary Key feature in Postgres is simple to use and reliable.
03:20This is especially useful when creating relationships between several tables.
Collapse this transcript
3. Data Types
Understanding data types
00:00Postgres has a rich set of data types, and while you may never use most of them,
00:04it's a good idea to have an overview of what's available.
00:07Numeric types include three sizes of integers--2-byte, 4-byte, and 8-byte sizes--
00:14decimal or numeric for fixed precision applications, like money, and note that
00:19while Postgres has a money type, this is depreciated so you should avoid using it.
00:24You should use decimal or numeric instead.
00:26Decimal and numeric are the same thing.
00:29It has real and double types for a floating point precision, and it has serial
00:34types for automatically incrementing unique identifiers.
00:39Character types include the standard VARCHAR, or Character Variant for
00:44Variable Length Strings;
00:46CHAR for fixed length strings; and TEXT, which is actually equivalent to VARCHAR
00:52with no maximum length specified.
00:55It's useful to note that the fixed- length strings are actually less efficient in
01:02Postgres than the VARCHARs.
01:05The VARCHARs and the text are more efficient than the fixed-length character
01:10strings, although the fixed-length character strings can be more efficient with
01:14storage depending on the application.
01:16So it's important to look at your application and understand what you are looking
01:19for: efficiency and speed, or storage space. And I think most of the time you
01:24will pick the text type or the VARCHAR type.
01:27It's also worth noting that with VARCHAR you can specify a maximum length, and
01:32this may be important in some applications, because that constraint gets
01:36imposed by the database,
01:38although in most cases where you are running your database from an application
01:42it may actually be more efficient for you to implement that constraint in your
01:46host language than in the database.
01:48So again this is something to look at in terms of performance and convenience,
01:53but I think most of the time of you look at all these trade-offs you are going
01:56to select the text type for almost all text.
01:59Postgres also supports the standard date and time types:
02:02timestamp that stores both date and time,
02:05date for dates alone and time for time alone, and an interval type for a time intervals.
02:12Just a few other data types that are supported.
02:15There are binary types, and these are packed binary so you get one bit per binary value.
02:21It's extremely efficient in storage space. Boolean types,
02:25now this is different than binary types.
02:27Boolean types are for logical Booleans, and this is basically true or false, and
02:33these take up one byte of storage per Boolean value.
02:36So they're not efficient on storage, but they are convenient for use.
02:39And there is enumerated types for enumerations.
02:43So Postgres has a rich set of data types available, and while you may never use
02:48most of them, it's a good idea to have an overview of what's available.
Collapse this transcript
Storing numbers with INTEGER
00:00Integer types are useful wherever you need to store integer-numeric values.
00:04In fact, they are commonly used for fixed-precision storage, even where those
00:08values have a decimal part.
00:10Here we have a table definition with two columns with integer types.
00:16I want to go ahead and select Go, and that creates that table.
00:20Then come over here to my 03-examples.sql from the Chap03 in the exercise files.
00:27Down here at the bottom I have some inserts with various integer values.
00:35Now the basic integer type in Postgres is four bytes long, which means that this
00:41third set of values is the minimum and maximum size number that can be stored
00:46in a four-byte integer.
00:48These are signed integers.
00:50So minus this big number to plus that big number is as much as we can store.
00:55So this fourth one should generate an exception, because that's a number that's
01:00too big to store in a four-byte integer.
01:03So I created this table with a standard integer type, which is four bytes,
01:07so the first three inserts should be fine and the fourth one should create an error.
01:11So we will go ahead and select Go and sure enough, query number four: integer out of range.
01:16Now when I do a select, see, we have those three rows.
01:24So let's go ahead and drop this table and create another one. Go back in here,
01:34and we will go up to the top, and we are going to use SMALLINT.
01:37SMALLINT is a two-byte integer,
01:42so that should give us even fewer of those values. And let's go down to the
01:46bottom here and get all four these inserts, and we will just drop all these
01:49in here, and we will do all this at once. And we will do a select, and we will do a drop table.
01:56So now we have got all of it in there and we select Go and it creates the table,
02:01and it gives us these two errors: query number five and query number six.
02:04So that's these two rows and sure enough, it only stored the first two rows of data.
02:10So a two-byte integer allows this range here, from -32,000 to plus 32,000.
02:17So if we want to be able to handle all of these values, even up to this nine
02:21bazillion, or whatever it is, large, large number that is an eight-byte integer.
02:28Instead of SMALLINT we use BIGINT, and put that one over here too, and run this
02:35again, and now we have no errors, and we've got all of those values.
02:39So for most applications you'll probably just use the four-byte integer, and that's in
02:43most circumstances going to be the most efficient, because it's the natural word
02:47size on most modern computers today.
02:50But it's still good to know that we have these other ones.
02:52You can use SMALLINTs in places where storage is as at a premium and you want to
02:57make sure that you are using your space and your disk storage in the most
03:00efficient way, and the BIGINTs for those cases where you just have to store
03:04very, very large integer numbers.
Collapse this transcript
Storing decimal numbers with NUMERIC
00:00Postgres provides a numeric type for storing fixed-precision numbers.
00:05Here we have a table being created with two columns, and each of them is of the
00:09numeric type, and we are inserting the same values that we have been using for
00:13all of the fixed-precision and integer numbers throughout this chapter.
00:17And we go ahead and select them from the table so we can see what they look like
00:21and then drop the table. So we'll go ahead and press Go and you see that all of these
00:25values were successfully inserted into the table and are all being read and
00:29displaying properly.
00:30Now the point of numeric is actually to provide fixed precision.
00:35So if I were to say, for example, 12, 2--and we will do the same thing over
00:41for this other one--
00:42what this does is is it provides space for twelve digits of precision, with the
00:49decimal place two positions from the right.
00:52So in other words, it will be ten digits of decimal place and two digits.
00:57So this bottom number obviously is going to be too long.
00:59Go ahead and select Go and sure enough, we see that "A field with precision 12,
01:05scale 2 must round to an absolute value less than 10 to the 10th," in other
01:11words, 10 digits of precision to the left of the decimal point.
01:15And so that last row did not get inserted.
01:18If instead, we just change this 12 to 64 and do the same thing over here and
01:26press Go, then we see that we get all of the values.
01:29So there is an important distinction to be made here, precision versus resolution.
01:35Precision means how many significant digits are guaranteed to be accurate?
01:39Resolution means how big of a number can you store?
01:43Numeric and integer fields are high precision and low resolution.
01:49Real, floating point, double precision, those are the high-resolution data
01:53types, but they have low precision and so we will be looking at those in
01:57the next movie.
Collapse this transcript
Storing floating-point numbers with REAL
00:00Postgres provides two sizes of floating- point storage: REAL and DOUBLE PRECISION.
00:05So here we have a table with a REAL type and a DOUBLE PRECISION type, and we're
00:10inserting these same values we've been using throughout this chapter.
00:13So let's go ahead and take a look at the results.
00:16There we see we're successfully storing all four rows of numbers, and if you
00:21look at these last couple of rows, you'll see that the way they're being
00:24displayed is with not necessarily all of the significant digits, but with the
00:30scientific notation e, +, and the number of positions to the right where the
00:34decimal point would move.
00:36So what this means is that floating-point numbers are stored with a larger
00:42scale, that is, a larger magnitude, but a lower amount of precision.
00:47In other words, there are only so many significant digits where they're
00:50guaranteed to be accurate.
00:52So let's take look at another example that will illuminate this effect.
00:57I'm going to create this table all over again.
01:04And in this case, we're going to use two numeric columns and two real, or
01:10floating-point, columns.
01:11We're using NUMERIC so that we can have fixed precision, and we're using
01:16floating point so that we can have greater magnitude but with less precision.
01:20And then we're putting four values into it, exactly the same for the numeric
01:24and the floating-point.
01:25So we'll go ahead and select Go and we get the results that we expect.
01:29These decimal numbers, these numeric numbers, have ten significant digits of
01:34precision and two places for the decimal point.
01:38And so they're displayed here 0.10, 0.20, exactly as we would expect, and the
01:44floating-point numbers are simply displayed as 0.1 and 0.2.
01:49Now the truth is that these values are not all that they seem.
01:59If instead of just selecting all of the columns, if instead we add these two
02:04numbers up and see if they equal to 3, in other words, da is 0.10, db is 0.20,
02:11da+db should be 0.30.
02:13So I'm testing it here.
02:15This is a Boolean test, and we should get a 1 if it's true or a blank cell if it's not true.
02:22So if I say Go here, we get 1. da+db is equal to 0.30.
02:30Now here's the fun part.
02:32We do the same thing using the floating-point columns.
02:36fa, fb, these are the ones that are defined as real.
02:40We would also still expect this test, fa+fb equals 0.3 to be true, right? Well, it's not.
02:48You notice we get a blank column there on the right, and that means that it's not true.
02:53So what is it, if it's not 0.3?
03:00What this here does is this takes that addition, fa+fb, and it formats it with a
03:05whole lot of significant digits and in engineering notation, or scientific
03:12notation, with the E at the end.
03:13And so that's what this to_char does is it formats it so that you can see it
03:18with a lot of precision and see what that number actually is.
03:21And when I select Go, you see that it's 3 to the -01, but only to one, two,
03:27three, four, five, six significant digits, and then it starts a straying, and it
03:32becomes a little bit less accurate.
03:33If we make these DOUBLE PRECISION, it will be better, but it's still not going to be 100% accurate.
03:44You see now we get a lot more 0s, but we've still got some problems down here.
03:48We're using larger floating-point numbers so we get more resolution, but we're
03:53not really getting accuracy. Because when it comes down to things like money, if
03:57you are adding and subtracting large columns of money day in and day out, say
04:02for a bank, and you're introducing these miniscule errors, if you've got
04:08billions of transactions going on, you're going to be off by millions of
04:12dollars this way or that way.
04:13This is the point, is you cannot use floating-point storage for money.
04:19You must use NUMERIC for money, because when we do this with the NUMERICs, we get true.
04:31That da+db is 0.30. Guaranteed. Always.
04:38Now it's worth pointing out that earlier versions of Postgres have a
04:42specific money type,
04:43and that has been depreciated, and instead you're supposed to use the NUMERIC type.
04:47And the NUMERIC type is exactly designed for applications where you need
04:52precision as opposed to magnitude or resolution.
04:55You use the REAL or DOUBLE PRECISION type where you need magnitude or resolution
05:01and you're willing to sacrifice a little bit of precision for that.
05:04And that's great for engineering applications where you can take that
05:07variance into consideration.
05:10But for applications where you're going to be adding and subtracting many,
05:14many, many, many rows of numbers over long periods of time and expecting to get accurate results,
05:20you need to use precision instead of resolution,
05:23and so you should use the NUMERIC types for those kinds of applications,
05:26especially in accounting and banking.
Collapse this transcript
Storing text
00:00Postgres supports both fixed and variable storage for strings.
00:04Here we are creating a table, and that table has three columns, and they are all
00:07specified as the text type. And we're inserting into each column of a row a thirty-six-character-long string.
00:16And so when I press Go here, you see that that succeeds, and it works exactly as
00:21we expect, and we get the whole thirty-six-character string in each of these columns.
00:27Now let's go ahead and edit this table definition. We'll make this one here VARCHAR(16).
00:34That's not going to give us enough room for that string.
00:37We'll see what happens. And we'll make this one here a CHAR(16). And now when I go
00:44ahead and execute, you see that we get an error.
00:47So we are getting an error on the VARCHAR(16) because that string is
00:53thirty-six characters long.
00:54So I am going to go ahead and take off the 16, which makes VARCHAR exactly like
00:58text and we'll go ahead and press Go again. And now we see we are getting an
01:03exception for it being too long for the character, which is fixed at 16.
01:08So this just isn't going to work.
01:10We'll put his 16 back in, and we are just going to change out this INSERT. And I
01:15am going to over to my little cut and paste area here that you'll find in your
01:19Exercise Files in Chapter 3, under the file name 03-examples.sql. And I am going
01:26to get these twelve-character strings instead, which just happens to be my name, and
01:30I'll go ahead and paste that in there, and select Go, and now everything is
01:34working exactly like we expect.
01:37So what we see here is that we can constrain the size of our strings to either a
01:43variable storage space, where in this case this twelve-character string is being
01:49stored and it's taking up twelve characters plus a length byte--
01:52it's actually probably an integer. And so it's being a little bit efficient
01:57in storage space. And this one here is twelve characters and that's actually
02:01getting padded with nulls, and so it's always going to take up sixteen characters' worth of storage.
02:07The thing to know about this is how Postgres works with these different types.
02:12The text type, which is the equivalent of VARCHAR without a link specification,
02:18is the most efficient type in terms of processing speed, because the storage
02:23engine is actually optimized for that.
02:26So the text type is the most efficient.
02:28The VARCHAR is effective for providing a constraintm, and it's just a little bit
02:33less efficient in terms of processing speed.
02:36And the fix size C-H-A-R, CHAR, with a constraint is the least efficient, and
02:44actually what it does is it makes sure that the storage is always exactly the same size.
02:49So you're always going to be storing sixteen characters' worth of string, even if your
02:53actual data a smaller size than that.
02:56And it still gives you constraints.;
02:57it still gives you the exception processing if you try to store more than that in there.
03:02So that's what you need to understand about the character types.
03:05You have text for free-form storage, VARCHAR for storage with constraints, and
03:11CHAR for specific fixed-length storage of text and string data.
Collapse this transcript
Storing Boolean values
00:00Postgres provides a dedicated Boolean type.
00:03It's is not really very efficient for storage--it uses an entire byte for each
00:07value--but it's good to know how it works so that you can use it in other non-storage contexts.
00:12So here's a table with two columns, both of the Boolean type, and you'll notice
00:16the one of them spells out the word BOOLEAN and one of them is using the
00:19abbreviated BOOL. And both of these are acceptable and they both work. And then I
00:26have inserted some various values.
00:27You will notice that you can use true and false as keywords.
00:31You can use 1 and 0 as string values.
00:35You can use true or the letter t, also strings; false, the letter f; yes, the
00:41letter y; no, the letter n; and these will correspond to Boolean values.
00:46So go ahead and select Go, and you see here are our values.
00:50So we get a one for true and we get a blank for false. And so in the first
00:56column we have the keywords TRUE and FALSE, so we get a 1 and a blank.
01:01In the second row we have the '1' and '0' in quote marks for strings, and we
01:06get a 1 and a blank.
01:08In the third row we have 'true' and 't' so they are both 1, and then we have
01:13'false' and 'f' and they both blank.
01:14We have 'yes' and 'y' and they are both true, and we have 'no' and 'n' and they are both blank.
01:21And so these are the Boolean values, and this is how they get returned.
01:25Now like I said, you are not really necessarily going to use these for storage.
01:29But you can and it works and if storage space is not an issue for you, it's
01:34certainly effective.
01:35But really the value of this is just understanding,
01:39when you do something like this, you have a value returned from a SELECT
01:48statement or from some query that is being evaluated as a Boolean value.
01:56The result there is blank, and that means that it's false.
01:58On the other hand, if its b equals b, then you will get a 1.
02:03And so it's good to understand how the BOOLEAN type works, even if you're not
02:07using it in a storage context.
Collapse this transcript
Storing dates and times
00:00Postgres provides a simple set of time and date types for storing and working
00:05with time, dates, and intervals.
00:08The most common of these is probably the timestamp type, which stores both a
00:13date and time, with or without time zone.
00:15So here we've created a table with two columns:
00:18a is the regular timestamp and b is a timestamp with the time zone. And we're
00:24inserting into it some values. And it's useful to note that these were all 3 PM
00:30in two different time zones.
00:32The first row is 3 PM as 15:25 in Eastern Daylight Time, or 3:25 PM spelled out
00:41that way in Eastern Daylight Time; and the second row is 3:25 PM as 15:25 UTC,
00:49UTC being the international designation for Greenwich Mean Time, or spelled out as 3:25 PM.
00:57And as Postgres works, there are a lot of different ways that you can specify a
01:01time string and it will interpret most of them really, really well.
01:06So here I've just used two of them with the 24-hour time and the 12-hour time
01:11with a AM or PM designation.
01:14So we'll go ahead and run this, and it's interesting what happens.
01:17The a column has no time zone associated with it, and the b column is storing
01:22with time zone. And it's using the default time zone that was installed when we
01:28installed Postgres on this machine, which is set for Los Angeles, California. And
01:33as I'm recording this, that is Pacific Daylight Time, which is seven hours early
01:39from UTC, and so it gets this -7 here with the time zone.
01:44So you'll notice in the A column it says 15:25 for both of them. Even though we
01:49specified one as Eastern Daylight Time, we specified one as UTC, it ignored the
01:54time zone and it simply stored the time and date--
01:58October 7th, 2011 at 3:25 in the afternoon.
02:03In the B column it stored it with the time zone, but it's displaying it in my
02:07local time zone, so it's actually done the conversion for me.
02:11Eastern Time zone is three hours ahead of me, so 15:25. There would be 12:25 here
02:17on the West Coast. And it's seven hours from UTC so 15:25-7 would be 8:25, and
02:24that's exactly what's being displayed here.
02:27So that's how a timestamp works, and timestamp is really, really useful. I use it a lot.
02:31I'll use it for logging events.
02:34I'll use it just by routine.
02:35I will stick it in lot of tables just so I have a record of when rows
02:39were created or updated.
02:41It's really, really convenient to use.
02:44There are some other data types associated with date and time.
02:47You can do the time by itself, so I'm going to go ahead here and just paste that
02:52in. And we'll use exactly the same inserts, but just with time columns, and it
02:57will discard the date part and just use the time part.
03:02So without the time zone it's just storing 15:25 for both of these rows, and with
03:07the time zone it's actually storing it with the time zone and displaying with
03:12the time zone and not doing the conversion for us.
03:14So -4 is EDT and +0 is UTC. And likewise there is a date type, and you'll notice
03:24that the date type does not have time zone available for it.
03:29There is no "with time zone" clause available for the date type, and that makes
03:33sense, because of course a date does not have a time zone--it's not a time.
03:38So when I execute this query with the date type, it just stores the dates, and it
03:42ignores the time altogether.
03:45And our final type here is the interval type. And of course, these aren't
03:52intervals, so if I run this, I'll just get errors, because I can't store absolute
03:56times into intervals.
03:58We have some examples of intervals here, and I'll just pop those in.
04:04We have 1 day, 1 week, 1 month and 1 year, and when I go ahead and run that, I
04:11get 1 day, seven days for one week, 1 month, and 1 year for those.
04:16And also, if you like, you can do something like this.
04:22You can use the AGE function to find the difference between two dates, and that
04:27should be 1 day. Or you can simply store a string like this, 2 days.
04:33So we have 1 day because we have the difference between two dates, and we have 2 days.
04:38So that's a quick overview of the date and time types available for Postgres.
04:42Of course, you can store these values, or you can use these values simply in
04:47queries.
Collapse this transcript
4. Storing and Reading Data
Storing and deleting data with INSERT, UPDATE, and DELETE
00:00Storing and deleting data in Postgres is pretty much like it is in other SQL
00:04relational databases.
00:06Let's take a look at the basics.
00:07Here we're creating a table with three columns,
00:11a, b, and c, and we're inserting values a, b, and c into five rows.
00:15We select those rows and then drop the table, and there is our results,
00:20we have the headings a, b, and c and the five rows of a, b, and c. So that very
00:26simply is how you store data in a table.
00:29You create the table with the appropriate column types and you insert those
00:33types of data into the respective columns in each row, row by row, using
00:39the INSERT statement.
00:40Of course that's not the only way to get data into a table,
00:44you can also do something like this.
00:46Let me go ahead and write in here.
00:50Before we drop that table, I'm going to create a table b with columns d, e,
00:54and f and we're going to INSERT INTO b FROM a, and so that's how we do that
01:01using what's called a subselect to select everything from a and insert it right into b.
01:06Then we'll go ahead and SELECT * FROM b, so you can see that, and then
01:12we'll drop them both.
01:18So there is table b and it has got columns d, e, and f, and you'll notice it has
01:22exactly the same data from a.
01:25But wait, there's more.
01:27We can also do something like this.
01:28INSERT INTO b (f, e, d) SELECT * FROM a. So we're turning the order around.
01:38Instead of d, e, f, it's f, e, d, and yet we're selecting * FROM a, so that's
01:43going to be a, b, c, and so we'll have five more rows with everything reversed.
01:49I'll go ahead and run that.
01:51And when we scroll down here, you'll see the first five rows are a, b, c and
01:56the second five rows are c, b, a. In fact, we can do this even more
02:01convolutedly if we want to.
02:05If we reverse the order of both f, e, d and c, a, b, you'll find that it will
02:11come out in the right order.
02:13And so we'll go again, and now the first five rows in our second table are a, b,
02:17c, the second five rows are c, b, a, and the third five rows are b, a, c,
02:23because we did it in this order c, a, b from a.
02:28So as you can see, there is number of different ways you can insert data into a
02:32table, including copying that data from another table with subselects.
02:37Now let's take a look at how you update data that's already in a table.
02:41We'll go ahead and we'll copy this UPDATE example from our examples file in
02:46Chapter 04, Command+C to copy it, and then going back to the browser and select
02:51all of this and paste it in, and we'll take a look at how this works.
02:55First, we're creating a table t with the SERIAL PRIMARY KEY for the id and a
03:02quote and byline for TEXT.
03:03And so we're just going to be inserting the quote and the byline, and we've
03:07got Aye Carumba!
03:08from Bart Simpson and a few other interesting quotes, and then we're going
03:12to select from that.
03:14And why don't I go ahead and take out these other lines for now, and we'll just
03:18run this much of it so we can see that that works.
03:20And there we have four different rows in this table with quotes and bylines.
03:26Now, if we want to change one, we can do it like this.
03:31We update the table, UPDATE t SET quote = and change it WHERE id=4.
03:38So for the fourth row instead of saying "I'll be back" The Terminator says "Hasta
03:43la vista, baby." and we select Go.
03:47And you see, we have the first query.
03:50It's I'll be back, and the second query it's Hasta la vista, baby.
03:53So we updated that row and you notice we have this WHERE clause.
03:57If we did not have that WHERE clause, well, why don't I go ahead and take it
04:01out, and you can see what happens.
04:03It will change all of the quotes in the entire table.
04:07And if I take out the WHERE clause in the SELECT here, then you'll be able to
04:11see the whole table,
04:13And you can see that they all say Hasta la vista, baby.
04:16But if I put in that WHERE clause here, id=4, then you'll see that just that
04:22last one, just number 4 is the one that gets updated.
04:25So that WHERE clause is really important when you're doing update.
04:28It's actually pretty easy to accidentally overwrite an entire table in
04:33a database.
04:35If you like, you can update more than one column at a time in a row, and
04:43that looks like this.
04:46And now that fourth row, instead of having a quote from The Terminator, it has
04:50got Rosebud from Charles Foster Kane.
04:52And then finally, if you want to delete a row, it's as simple as changing this
05:00UPDATE to saying DELETE FROM t WHERE id =4, and then it will simply delete the
05:07row entirely, and there, now that row is gone.
05:11So that in a nutshell is just a quick overview of how you insert data into a
05:15table, how you update data in a table, and how you delete data from a table.
Collapse this transcript
Reading data with SELECT
00:00The SELECT statement is at the heart of the SQL language and Postgres supports
00:04all its various functions.
00:05Let's take a look at the basics.
00:07Here I've selected the album database from the database selector over here,
00:11and here's some SELECT statements operating on the album table from the album database.
00:17The first one you've seen, it's very common,
00:19this is just select everything from the table, so that will select the entire table.
00:25The second one selects just a few columns from the table.
00:28And the third one is the same as the second one, but it's actually giving us
00:33human readable names for the various columns,
00:36Artist, Album and Release Date.
00:38And you'll notice that in Postgres you need to put quotes around these if you
00:42don't want it to fold everything to lowercase.
00:44So even though there's no spaces within this string, it still needs to have quote marks.
00:49And you'll notice that there are double quote marks, they are not the single
00:51quote marks that represent an SQL string, because this is not an SQL string,
00:57this is something that's specifically for the title of the column, for Postgres purposes.
01:02So they're distinguishing that by using the double quotes instead of the single quotes.
01:06So when I go ahead and run this, see our first one is the entire table, our
01:10second one has just a few of the columns from the table,
01:14there's no Released column, and the third one has the Artist, the Album, and
01:19the Release Date. And you'll notice that those titles for the column titles are all in uppercase.
01:24So even with this second one, if I was to make this one just all caps, ARTIST
01:29like that, it would still work just fine, and it simply folds all of those
01:34column names down to lowercase.
01:36So it doesn't care that I put it all in caps,
01:39it's going to put it in lowercase anyway. And the same happens when I define the table,
01:43so the table is actually defined in all lowercase. And this is handy.
01:47It prevents errors creeping in based on case mismatch, but if you really want to
01:52have a title that has mixed case or has spaces in it like this, then you need to
01:56use those double quote marks.
01:58Now, let's take a look at another form of SELECT that is pretty common.
02:03I'm going to switch over here to the examples file from Chapter04.
02:07I'm going to take this query, which includes a subselect, and we're going to go
02:13ahead and paste that in there.
02:15So what this is going to do is it's going to select all of the tracks from the
02:20track table that are included in albums by two artists.
02:25And so you actually have to read it inside out.
02:27You take it from the parentheses and you read this part first, where it says
02:31SELECT id FROM album.
02:32That's the album table, WHERE artist= Jimi Hendrix OR artist=Johnny Winter, and
02:38that's going to return a list of album ids.
02:42Then it's going to select from the track table where album id is in that list.
02:47So we're getting the album ids from the album table and we're using that to
02:53select particular rows from the track tables.
02:56We'll go ahead and we'll hit Go here and we'll look at what comes back.
02:59And what comes back is all of the tracks from one Johnny Winter album and
03:04there's one Jimi Hendrix's album.
03:07So if I were to just take this SELECT by itself, and I'll just put that up here
03:12and I'll put a semicolon after it and we'll run it as a separate statement.
03:15You see that we get this list of these two ids, and those are the ids that are
03:20used in this WHERE clause, WHERE album_id IN, one of those, 11 and 16.
03:25You see that we only have rows from album_id 11 and 16.
03:29So that's called a subselect.
03:32Finally, we're going to look at a type of a join that doesn't actually use the
03:36JOIN keyword, and then in another movie we're going to look at joins in a
03:39little bit more detail.
03:41So here we get the title of the album from the album table, the title of the
03:45track from the track table, and the track number from the track table.
03:48And the way this works is again we're using this AS clause, but we're using it
03:53in a slightly different way.
03:54So here we're using it to label these columns, which is how we've used it before.
03:59We're also using it down here to actually alias the table name, so FROM album AS
04:04a and track AS t WHERE a.id so that would be the same as if I had written out
04:11album.id = t.album_id.
04:16And so again, that's as if I had written out track.album_id ORDER BY album title
04:22and track track_number.
04:24So having this SELECT FROM two separate tables with a comma in between them
04:30actually performs a JOIN, and this was originally way back when,
04:33this was originally the syntax for JOINs, and sometime in the 1990s, SQL
04:39evolved to include the JOIN keyword, and we'll look at the JOIN keyword in another movie.
04:44But for now what we have here is a very simple JOIN, and when we run this we see
04:49we have album titles and, again, that's the title column from the album table,
04:54track titles, that's the title column from the track table;
04:59and track_number, and there is all of our tracks associated with their album names.
05:06So that's a very simple JOIN that's done entirely with the SELECT statement.
05:10So like I said, the SELECT keyword is probably the most common keyword in all of SQL.
05:16It's really a workhorse and it does a lot of different things.
05:19These are the parts of SELECT that you're likely to use the most.
Collapse this transcript
Reading with JOIN
00:00The Join keyword is used as a clause and select for retrieving data from two or
00:03more tables in one query.
00:06This can be a little bit confusing, so let's look at an example.
00:09I'm going to select the world database. I am just going to go ahead and run this
00:12query, and you'll see that I've got a list of country names and languages that
00:17are spoken in those countries, and this is the query that produces that, and it
00:21produces it from two different tables.
00:23There is a countryLanguage table and there is a country table, so let's take a
00:27look at these two tables.
00:29We're just going to look at the first five rows from each of them, so the
00:46countryLanguage table just has country code and the language, whether or not
00:50it's the official language and the percent of the population that speaks that language.
00:54The country table on the other hand has a lot of stuff, but you'll notice
00:58that it has a corresponding code and it's got the name of the country, and these
01:02are the things that we're interested in.
01:05So when we look at this Join query here, we see we are selecting From
01:09countryLanguage As L, so that alias L refers to that country language table.
01:16So when you see l.language that's this column here, the language column from
01:21the countryLanguage table, and it's joining the country table as C, so that's
01:27this table down here.
01:28On l.countryCode = c.code, so in others words, in the countryLanguage table, it
01:34looks at the countryCode, and then it searches through the country table for
01:39that same code in its code column, and from there it gets the name.
01:44And so the Join is actually pretty simple.
01:47This is the important part right here.
01:49So the Join happens on this condition, and it works like this, for each row in
01:54the country language table, because that's our primary table there,
01:57it looks for any rows in the country table where this condition is true, and it
02:02uses those rows in the results.
02:05And so that's why in our results here we have several rows where it's true for
02:11the country of Afghanistan.
02:12We have several rows where it is true for the country of Albania, and for
02:16those rows, it simply goes out of that country table and gets the name and displays the name.
02:21Let's go and simplify this example a little bit by putting in a Where clause.
02:26We can just put this in right here and run it, and so now we're only going to
02:33display the rows where the country name is equal to the United States, and so
02:38we can see there is a number of rows in the countryLanguage table that have a
02:42country code that is equal to the country code for the United States in the country table.
02:49Let's take a look at another example;
02:52this one is from the album database.
02:56So we'll select the album database and we'll go ahead and paste this in and run it.
03:01And what we're doing here is we're displaying all of the tracks in the track
03:05table along with the artist name and the album.
03:09And it's getting the artist and the album name from the album table, so
03:13a.artist, a.title you see album As a. And it's joining those on the condition
03:19where the album_id is equal to the id column in the album table, and that makes
03:25it possible for us to display all of the tracks in the track table along with
03:29the artist name and the album name.
03:32So this is where the relational in relational database comes in.
03:36These relations are typically accomplished by using a sequential ID number in
03:42each of these tables.
03:43If you look at the album table, you see that it has these unique ID numbers and
03:55it's those ID numbers that make this possible.
03:57If you look at the track table, you'll see that there is an album ID column and
04:02that corresponds to the ID column in the album table and that makes these
04:06relationships possible.
04:08So that's a quick overview of the Join keyword.
04:11We'll be using it some throughout this course, so it's a good idea to
04:14understand how it works.
Collapse this transcript
5. SQL Expressions
Understanding SQL expressions
00:00In Postgres as in standard SQL an expression may be used anywhere a value can be used.
00:06For example, this SELECT statement will return 1 value, 25, the result of the
00:11expression 5 times 5, and the INSERT statement will insert a row with the number
00:164, a NULL value and the string your name in all Lowercase letters.
00:23Expressions use operators to operate on values or the results of other expressions.
00:28The Standard operators include the string concatenation operator, arithmetic
00:33operators, comparison operators, and boolean operators.
00:38Other special operators include IS and IS NOT for comparisons, query result
00:43matching operator is LIKE, ILIKE, and SIMILAR TO for regular expressions,
00:48BETWEEN for paired comparisons and IN and NOT IN for testing inclusion in a
00:54list or query result.
00:57CASE is the conditional operator like IF /THEN/ELSE in other languages and it's
01:02also used like a ternary conditional operator in C like languages.
Collapse this transcript
Matching patterns with LIKE
00:00Postgres has a couple of extensions to the standard SQL LIKE pattern matching operator.
00:06For example, here using the world database. If we SELECT FROM the City table
00:11WHERE Name LIKE 'Z%' ORDER BY Name, that's the standard usage of the SQL LIKE
00:19operator and it will return rows where the name column begins with capital
00:24letter Z, and so we see there is a bunch of cities that begin with the capital letter Z.
00:31Now if I change this to a lowercase z and run it again, you see we get no results.
00:38And so in order to have this operator be case insensitive, Postgres has the
00:44extension ILIKE, beginning with a letter I and that makes it case insensitive.
00:49And now you see that we get the same results, as when we have the capital Z
00:54although we are using a lowercase z.
00:58Likewise, if you want to define the records where the second letter was a W, you
01:03could use the underscore which matches one letter in SQL and a w and in this
01:09case I am using a lowercase w, but because I'm using ILIKE, it doesn't matter,
01:14either lowercase or uppercase will work the same.
01:16And the percent sign, again from standard SQL, means match any number of any
01:22kind of character to the end of the string.
01:24And so if I press Go here, we get all of the records where the second letter is a W.
01:31But now what if I wanted the records where the first letter was a K or a Z and
01:37the second letter was a W?
01:39There isn't really a way to do that with the standard LIKE operator.
01:42And so most database engines have some sort of an extension to use regular
01:47expressions or some other pattern matching system, and in fact, Postgres
01:52has SIMILAR TO which uses a kind of regular expressions there, a SQLized
02:00Regular Expression.
02:01So instead of the dot character being used to match a single character, the
02:06underscore is as it is in SQL.
02:09So this is just going to look a whole lot different than it would in standard
02:13POSIX regular expressions.
02:14We are going to have a Z and a K here, so it'll match either a Z or a K in
02:19the first position.
02:21And then we'll have the W, so that second letter is always going to be the W.
02:25And then we have to match anything after that.
02:28So we use the undersore, instead of we would use a dot in POSIX Regular
02:32Expressions, and the plus sign.
02:35And so this will get all the records that begin with a K or a Z and have a W in
02:40the second position.
02:42So that's SIMILAR TO, and that is the pattern matching expressions that are
02:47used in Postgres.
Collapse this transcript
Choosing from multiple conditions with the CASE expression
00:00The Case operator is used to select between multiple conditions, for example if
00:05we have this table here in the test Database, we get a table with a couple
00:10boolean values and I've inserted one and a zero into them and when I run this
00:15you see we get a 1 for true in column a blank for false in column B. But
00:22perhaps I want to display it differently and I can use a case conditional operator for that.
00:28So let's go over here to our Examples file from Chapter 5 and I'm just going to
00:33copy and paste this SELECT statement in right here.
00:39This has a couple of CASE conditionals in it.
00:43The first column of this result, which it says as boolA, so that's the first one.
00:47It has this case which begins there and ends with the end.
00:51WHEN a THEN, it will return a TRUE else it will return a FALSE. It's very simple.
00:57We have got exactly the same one here for b and when I run this you see our
01:01second query as boolA and boolB and the first one says TRUE and the second one says FALSE.
01:08So case looks a little bit complicated, but it's really very straightforward.
01:12And it's used in cases where you need a conditional. And in some ways some people
01:17say it's like if then else in some languages and it can be used that way.
01:22It's more commonly used like this, like for instance the ternary conditional
01:27operator in the C language, where it takes a condition and it will return either
01:32one valuable or another value.
01:34So that's the CASE statement in SQL, and it's a standard case statement in SQL.
01:39It's implemented in a standard way here in Postgres.
Collapse this transcript
Using casts to force type
00:00The purpose of a cast is to take a value of one type and force it to another type.
00:05This can come in handy at times, so here's a simple explanation of how it works.
00:10We start by creating a table and it has an integer column and a real column, and
00:14I put the same value into both of them.
00:16A simple 9 digit number, and then I select them from the table.
00:20So when I look at it you see the number on the left, the integer, has all 9
00:23digits, the number on the right has 6 digits and one of them is rounded, you
00:28notice that's 123457 and scientific engineering notation showing that its
00:35times ten to eight.
00:36So let's go-ahead and cast that left value into a real number and see what
00:41happens. Take this cast string right here.
00:44This is our 05_examples file from the Chapter 5 folder in the exercise files.
00:50And I am just going to paste it in and after this select there, and we will run that.
00:55And we see that now both of numbers are rendering the same way.
00:58So it's as if they were both type real.
01:01So we have the syntax of the cast it has a keyword CAST and then in parentheses
01:06it has the value that you are casting and the AS REAL as the new type.
01:12So I can also do other types and I have another example here where I am going to
01:17cast both of them to numeric with a fixed resolution, so there is numeric 15,2
01:26which means that it should have 15 digits of significance with the decimal point
01:30two places from the right.
01:31And when I run this you will notice that the number on the left comes out just fine.
01:35It's got all 9 of its original digits and a .00 exactly as we would expect it.
01:40And the number on the right is still rounded 123457000.000.
01:46That's because it was originally stored as a real and it lost its resolution, it
01:52actually lost that day to those significant digits, at the point when it was
01:56stored as a real, and so taking it out of real and casting it to something else
02:00isn't going to recover lost data, but it will get it to display in a certain
02:05formatting and it will actually make it into that type so that you can use it as
02:08that type in an expression that requires it to be of that type.
02:13So that's how a cast works and this is one those things that's pretty much
02:16exactly how it is in the SQL standard and so Postgres isn't doing anything
02:21special with this and its just using the standard SQL syntax.
Collapse this transcript
6. Mathematical Functions and Operators
Using operators for simple arithmetic
00:00Postgres provides a rich set of mathematical operators and functions as you can
00:04see here on this Documentation page from the Postgres web site.
00:09These are the mathematical operators that are available, and there is also a rich
00:13set of mathematical functions, including all the common trigonometric
00:18operations as well.
00:20Let's take look at how we use some of these operators in practice.
00:24So I'll bring up SID here and for example if you wanted to simply do simple
00:30arithmetic, you can say something like SELECT 5*30;
00:32and you get a result of 150 like it should be.
00:38If you want to do a simple division you can say something like SELECT 7/3
00:43and the answer is 2, because this is integer division.
00:50Seven is an integer and three is an integer, and so it's going to give you an
00:54integer division, which will ignore the remainder part.
00:57If you use the modulus operator, which is the percent sign, that will give you
01:02the remainder which is one.
01:04So 7/3 is 2 with a remainder of one.
01:08If you really want the floating-point division you can say 7.0/3; and this'll
01:15
01:15give you a double precision answer, 2. 33333 et cetera, because now 7.0 is a
01:23literal floating-point number, which is interpreted as being double precision.
01:28Let's take a look at this a little bit more in practice with an example from
01:31our world database.
01:33In the world database we have a population column.
01:36If I say Select name, population FROM country, and we'll just take a look at
01:45the first 10 rows of that query, and we see that we have population, which is
01:52in absolute numbers.
01:54In other words if the population is 100 million, let's take a look at the
01:58countries instead of limiting it to 10, let's just say, where population > 100000000;
02:08You see there are some pretty big numbers in there.
02:09So if we want to, just go ahead and format this a little bit.
02:15If we want to, we could instead look at population/1000000; and let's also sort
02:24this, ORDER BY population DESC;
02:33And now we see that we have just the countries with greater than 100 million
02:37population, and the population in millions.
02:40Of course, we can name this column if we want to.
02:43We can say As "Pop (MM)" and that gives us exactly the result that we were looking for.
02:51So that's one example of how we could use math operators in practice.
02:56Let's take a look at one more example that has to do with prices.
02:59This is actually even a little bit more common. If we take a look in our test
03:03database at the sale table,
03:10You see that we have price in hundreds of dollar and cents.
03:14And we might want to actually format that as dollars and cents instead.
03:20So instead here, let's just look at the item_id and the price, and we'll divide
03:26the price by 100 so that we get dollars instead of cents.
03:29Now the problem is that we are just getting the dollars part,
03:36we are not getting the cents part, because we did integer division again.
03:40And now if we want the cents, we have to do modulus, and then we would need to
03:43concatenate it with a period, and that's starting to get a little bit messy.
03:47Instead, what we can do is we can cast this price AS NUMERIC.
03:56Because this number has a fractional part, it's going to do that double
04:00precision, arithmetic again.
04:01And so now we get the dollars and cents, but we also get a bunch of zeros at the end.
04:07So there is one more thing we need to do in order to format this just as we want it.
04:11We can use the TO_CHAR function, which is technically a string function.
04:16It converts this number into a string, but as it does it, it allows us to format it.
04:22It's got this other operator which is a format string where we can do
04:26something like this.
04:31And now we get exactly the result that we want.
04:33And in fact, if some of these numbers were larger, we'd even put the comma in
04:36them for the thousands place.
04:38So there you have an idea of how you can use some simple arithmetic operators
04:42in your SQL.
Collapse this transcript
Using math functions
00:00Postgres provides a rich set of mathematical operators and functions as you can
00:04see here in the Postgres documentation.
00:07We have the operators up there which we talk about in a different movie in this chapter.
00:12And here's a full list of the mathematical functions that are available, quite a
00:17few, very complete and trigonometric functions as well.
00:22We are going to take a look down a couple of simple examples of how you can
00:25use this in your SQL.
00:27So bring up SID here and we will start just by creating a table in the test database.
00:32We get a couple of integers, and we will insert some values.
00:411 and 2 and 3 and 4, maybe with a couple of negative values as well, -1 and -2, and
01:06we will take look at them.
01:13So there's the values that we've inserted into our little table. And now if we
01:17want to we can look at the absolute value of these which means that even for the
01:22negative values it will show us their positive equivalence.
01:26Look at the absolute value of a and just b by itself and meant to make these 3 and 4, didn't I?
01:32There we go.
01:34And we see we have the absolute value of 1 and 3 and the negative values of
01:392 and 4 over there.
01:41Now if we change these integers to numerics, let's go ahead and copy and paste
01:48that over here, and we will change these values as well.
01:51Let's say 123.456 and 456.789 and we will make those negative over here and take
02:11a look at that result.
02:12There we have that.
02:13Now let's say we want to round that value, so if we say ROUND(a) and that uses
02:21the rounding function and without a second argument that will just round it to
02:25the decimal point and so I get 123 instead of 123.456.
02:32If instead I want to round it to two decimal places, I can say ,2 and it
02:37rounds it to two decimal places and you see that 5 gets rounded up because the
02:42digit after it is a 6.
02:44These are just a couple examples of how simple it is to use these math
02:48functions in your SQL.
02:51And in the Examples file here for Chapter 6, you notice we have the URL here,
02:57where you can find that documentation on the Postgres web site.
Collapse this transcript
7. String Functions and Operators
Finding the length of a string
00:00Postgres has a lot of string related functions and you can find a complete
00:06exhaustive listing in reference here on the Postgres web site in the Reference
00:11Manual for string functions.
00:14These are the major ones and then there is a longer list of other ones available
00:20and there is an even longer list of types of conversions that you can do,
00:25character set conversions and that can be really, really convenient.
00:29Especially, if you're migrating data from another system, I found that very
00:33convenient when I migrated data from my SQL to Postgres recently.
00:37We are going to do something a little bit different in this movie, in that I'm
00:41not going to be using SID,
00:43I am going to be using pgAdmin III.
00:45And the reason for this is I want to work with some characters that are not
00:498-bits and PHP is just not very good at that and SID is not designed to handle that.
00:55It takes all the input and it escapes it and turns it into HTML entities.
01:00So we're just going to go ahead and use the Query Builder here in pgAdmin to
01:05look at the string length functions.
01:07So I've selected the test database and I am going to press the SQL button here,
01:11and I am just going to type something in SELECT LENGTH and I am going to type in
01:17a string, This string has 30 characters.
01:24That is if I didn't make a typo.
01:25And when I execute the query, indeed the length is 30 characters.
01:30Now you'll notice that I get exactly the same result when I say CHAR_LENGTH
01:36because in fact, LENGTH and CHAR_ LENGTH are the same in Postgres.
01:41I can also say BIT_LENGTH and get the number of bits which under some
01:46circumstances may be useful.
01:48What's even more useful is the one that says OCTET_LENGTH.
01:53Now for those of you not familiar, OCTET is the technical term for an 8-bit byte
01:58of data, and in fact, this string has 30 OCTETS.
02:02But here's the interesting part.
02:03We come here to Chapter 7, I am going to open my Chapter 7 examples' file, and I
02:09am going to just select this one here.
02:11This has three Chinese characters which if Google translator is correct, means I
02:17am a rhinoceros and I am just going to select the length of this, and you'll
02:22notice that it's three characters long, and so if I say CHAR_LENGTH, it is
02:29indeed three characters long.
02:31But now if I say OCTET_LENGTH you'll notice that it actually takes nine octets
02:39to describe this and that's because these are not won by characters,
02:43these are UTF characters representing something that's way outside of that first
02:49page of data in UTF.
02:51And so we are using UTF-8 here and we can actually store this in a table and we
02:58can work with these characters and we can get the length of these characters,
03:02but if you're using PHP or another language to interact with Postgres and you
03:07need to know how much space this string is going to take, you are going to want
03:12to use OCTET_LENGTH instead of CHAR_ LENGTH to find out how big the string is,
03:18because it certainly looks like three characters and if you just say LENGTH by
03:21itself without asking for the OCTET_ LENGTH, it will tell you that it's three
03:25characters, but if you allocate memory space for 3-bytes and you try to copy
03:31this string into it, you're going to have a memory leak.
03:34So when I am using Postgres, I tend to favor OCTET_LENGTH for checking
03:40the length of strings.
Collapse this transcript
Concatenating strings
00:00Postgres has a few standard ways to concatenate strings.
00:04The most common is using the Concatenation Operator which is standard SQL,
00:09actually most of this is standard SQL.
00:12And so you can take two strings, 'This is a string' and use the SQL
00:18Concatenation operator which for people who are familiar with other languages
00:22it might look strange.
00:23It's two vertical bars which means other things in other languages.
00:27And I will type another strings 'This is another string' and we are putting a
00:32semicolon and these two strings get concatenated and you notice that there is no
00:37space in between, no nothing in between.
00:40Of course instead of using the Concatenation operator you can use the
00:43Concatenation function and it's simply spelled CONCAT and then instead of that
00:49operator you use a comma and put a closing parentheses at the end.
00:54And the result is exactly the same.
00:57Now if you want to take several strings and have some kind of a separator in
01:02between them, you can use concatenate with separator which is spelled like this
01:06CONCAT_WS and you put the separator at the beginning as the first argument and
01:13then a bunch of strings,
01:14we will just put in one more here.
01:19And when I run this, you'll notice that they get concatenated, but that
01:23separator is now used between them.
01:26So this is just a few simple examples of how Postgres uses standard SQL functions
01:31for string concatenation.
Collapse this transcript
Returning parts of a string
00:00Postgres has several standard functions for operating on parts of the string.
00:05For example, if I type in here SELECT POSITION ('string' IN 'This is a string');
00:16we will get the number of characters in from the beginning where that substring
00:21is found inside the larger string and we see that it's 11.
00:25Likewise, I can say SELECT SUBSTRING( 'This is a string' FROM 11); and so that
00:35will start 11 characters in and give me the rest of the string which we now know
00:40is a string, that says string.
00:43Or I can add to this I can say FOR 3 and it will just give me three
00:48characters starting out of 11.
00:49So I will get just str.
00:52So these are very standard functions.
00:54These are common in all the major database systems and they work pretty much the
00:58same across the board.
Collapse this transcript
Replacing strings within strings
00:00Postgres provides standard functions for replacing strings within strings. For example
00:06I can do this, SELECT REPLACE and I give the source string ('This is a string'.
00:14And then the part of the string that's going to be replaced 'is a'); with the
00:19replacement 'is not a' and when I execute that I get this is not a string.
00:27So that's probably most common way to do this.
00:29There's another interesting function called Overlay and while many large
00:34database systems have something like this,
00:36this is the particular Postgres way to do it.
00:40I can say OVERLAY and let's just take the word string here and replace it with
00:45xxxxxx and say PLACING and I do not want this comma here, 'string' FROM and I
01:00happen to know that that's 11 characters in and so I am going to say Go and now
01:05it says this is a string and so it's taken this xxxx which is 11 characters in
01:10and it's placed this string there.
01:13So this is possibly another useful function.
01:16It's something to have in your tool kit,
01:17you probably won't use it as often as the Replace function.
01:20But its good to know that it's there should you ever need it.
Collapse this transcript
Trimming and padding strings
00:00Postgres provides some simple, common effective functions for trimming strings.
00:06For example, if we have a string like this and maybe it's got a few spaces in
00:12front of it and a few spaces at the end of it,
00:19you'll notice that it displays on the screen or without those spaces and this is
00:24a really common problem. And it presents a real challenge to Web programmers
00:29because let's say somebody is entering their e-mail address to login to your web
00:34sites and they enter a couple of spaces at the beginning of it or couple of
00:38spaces at the end of it and they don't notice it, because people don't think of
00:42spaces is actually taking up space.
00:45But when we take a look at this with View Source here in the Firefox web
00:49browser, I am going to use the Context menu, I am right-clicking here and View
00:53Page Source, you can also get it with Ctrl +U on a PC or Command+U on a Mac, if
00:59you're using Firefox.
01:01We will look at this in the View Source and if we come all the way down here
01:04to the end, you see this is our results, see the column had their and the cell value,
01:10this is a string and you have got to spaces on either slide of it.
01:14But when you look at it in the browser you don't see those spaces.
01:17And so the problem is that the spaces are actually there and if you search
01:20through your database for somebody's email address and they have typed it with a
01:24space and it's in your database without a space or even worst its in your
01:28database with a space and they typed it without a space,
01:31you're not going to get a match.
01:33And so that's what the Trim functions are for.
01:35If you are trim all of your input before you store it and you can do this easily
01:39by using the SQL trim function as you store the data and then again when you
01:45compare the data, then you will fine.
01:48And so if I say SELECT TRIM and put the parenthesis on either slide of that,
01:53we will say Go and you will notice couple of things you notice it says btrim
01:57because trim is effectively an alias from the btrim which means both sides trim.
02:02And when we go back to View Source and we look at this string now, you'll notice
02:08that it's completely trimmed.
02:09It's got the spaces trimmed from the beginning and from the end.
02:13There are couple of other forms of this.
02:14There is ltrim, which just trims the left-hand side and we will look at this
02:19again in View Source and we will see that the left-hand side is trimmed and the
02:22right-hand side still has its spaces and of course there is rtrim, which does
02:30the same thing but for the right-hand side.
02:33So it's actually an important function to trim your strings especially when you
02:37are getting input from users along with all of the other things that you do to
02:40prevent SQL injection attacks and Cross Site Scripting and things like that,
02:45just want to throw trimming the strings in to that toolbox.
Collapse this transcript
Converting numbers
00:00Postgres provides a single very powerful function for converting numerics to
00:04strings and this is TO CHAR.
00:06And you will notice here on this page, there are a number of different forms of
00:10it and all the way down at the bottom here because it's so flexible and does so
00:15many different things, you'll see the different options and template characters
00:19and template patterns for formatting numbers and a number of examples as well.
00:25So let's just take a look at a couple very simple examples of this.
00:28We will start with a number, and I will just say go and you will see that it just
00:38echoes the number back and of I want to format this I can say city TO CHAR, and
00:43take that number and put in a format string.
00:47Make sure I have enough digit spaces and you will notice the format is the number with
00:58commas in place and enough digits after the decimal point.
01:02Now if I take out some use digits after the decimal point you will notice that
01:06it simply truncates them, it's not actually rounding off.
01:09There's another simple form of this called TO HEX, type in TO_HEX and just put
01:17in a little number there.
01:18You will notice that I get a hexadecimal number 15b3 and if I want that in
01:23uppercase hexadecimal, I simply say upper before it and put parenthesis around
01:28that so that it gets fit in to the upper function and we get an uppercase version of that.
01:33So this is actually a very powerful function and it has a lot of
01:37options available to it.
01:38That's the simple form of it and the most common use of it is simply to
01:43put commas or decimal points or something in a number that doesn't have it
01:46otherwise.
Collapse this transcript
8. Date and Time Functions and Operators
Getting the current time and date
00:00Like most of the time and date functions in Postgres, getting the current time
00:03and date follows the SQL standard closely. For example,
00:07I can say SELECT CURRENT_TIMESTAMP and I get the current time and date out to
00:16many microseconds, or I can just say GET CURRENT DATE and that will give me
00:22just the current date, or I can get current time, and that will get me the current time.
00:29You will notice that the time and the timestamp also give me this part here
00:34which is the Time zone relative to UTC.
00:37I am in California in the summertime and so that's -7 hours.
00:42If I want the be local time without the time zone, I can say SELECT
00:46LOCALTIMESTAMP and I get this localized string without the times zone, or I can
00:55just say GET LOCALTIME and that will give me the time component without the date component.
01:02So these are mostly used to automatically timestamp a table, for example I'm
01:07going to switch over here to my Exercise examples file.
01:12I am just going to grab a bunch of SQL here your and paste it in and what we
01:16have here is we are creating a table and his table has an integer and it also
01:21has these timestamps.
01:23So a is a timestamp with time zone and B is a timestamp without a time zone.
01:28If it has the with time zone clause that means it adds the time zone and it
01:32doesn't have the with time zone clause then it's the timestamp without a time zone.
01:37And both of these have a default value of current timestamp, with the default
01:43key word and so when I insert values into them but allow the default to
01:47happen in other words I am not inserting a value into the AMB columns watch what happens.
01:53I get this C123 and I also get these automatic timestamps and you will notice
01:58because we have so much resolution here, there is very slightly fractions of
02:02a second difference.
02:04The entire elapse time was 45 ms and you can see that the difference between
02:09this 50 and that 05 is in fact 45 ms more or less.
02:15So this is how the current timestamp is typically used to automatically insert a
02:21timestamp into a table cell.
Collapse this transcript
Specifying a specific time zone with AT TIME ZONE
00:00Postgres supports the SQL standard AT TIME ZONE construct for converting time
00:05zones to other time zones.
00:07For the purposes of this example I've created this table which has two columns,
00:11a and b. Column a has the With Time Zone attribute and column b does not.
00:16So it's being stored without the Time Zone.
00:19And I'm inserting one row with DEFAULT, DEFAULT, just so they both get
00:23the current timestamp.
00:24So when I run this, you'll see the current timestamp comes up in exactly the
00:28same timed down to the microsecond as you can see there, except column a has the
00:34Time Zone attribute, so it says, -07, which is the current time zone where I'm on the West
00:39Coast of the United States.
00:40It's in the summer, so this is Pacific Daylight Time, which is seven hours
00:45before Greenwich Mean Time.
00:46So let's go ahead and experiment with the AT TIME ZONE clause.
00:52So I'm going to say here SELECT a AT TIME ZONE 'EDT', which is Eastern Daylight
01:01Time.I'm going to say, AS a, because otherwise Postgres doesn't know how to name
01:06the column and it ends up folding the two columns together.
01:09And b AT TIME ZONE exactly the same 'EDT' AS b FROM t.
01:18So go ahead and run that, and now what we get, you'll notice on the left-hand
01:22side, it's giving us the time in the Eastern Daylight Time Zone, in other words,
01:27this is a time three hours later and you notice that it does not have the time
01:31zone attached to it.
01:33For the column without a timestamp, it does exactly the opposite thing.
01:38It treats the time that was stored as if it were at the target time zone and
01:43displays what the time here is.
01:46So the behavior of the same function on two different values with and without
01:50the Time Zone attribute is actually the opposite.
01:53If the value being operated on has the time zone attribute, AT TIME ZONE will
01:57give you the time in the time zone specified.
02:01If the value does not have a time zone attribute, AT TIME ZONE will give you
02:06your local time assuming that the value that does not have a time zone attribute
02:12is in the target time.
02:13I'm going to say this one more time one other way because it's a little bit
02:16confusing and I want to make sure that you get it.
02:19For the a value which has a time zone, AT TIME ZONE 'EDT' tells us what time it
02:24is in Eastern Time Zone.
02:26For the b value that does not have a time zone, AT TIME ZONE 'EDT' tells us what
02:30our local time is if that time in the stored value were in EDT.
02:37So this one is actually three hours earlier.
02:40This is our time here on the West Coast assuming that it's 16:12 on the East Coast.
02:45It would be 13:12 here on the West Coast.
02:48This time is 19:12 assuming that it's 16:12 here on the West Coast.
02:53This is the time that would be on the East Coast.
02:56Let's just take a look at a couple more examples.
02:58I'm going to go ahead and take this same example and I'm going to just change it
03:02so that it says UTC instead of EDT.
03:05That should work exactly the same way except with a seven hour difference
03:09instead of a three hour difference.
03:11We'll say Go and so if it's 16:15 here then it is 23:15 in UTC, which is
03:20correct, and if it's 16:15 in UTC then it would be 9:15 here.
03:26Starting to get a little more clear.
03:28Let's do this one more time with a slightly different form.
03:30I'm going to copy this and paste it down there on the next line.
03:36I'm going to say, AT TIME ZONE and instead of saying UTC I want to give it
03:40Western European Time and I don't happen to know the abbreviation for that.
03:43I know that it's one hour after UTC.
03:47So I'm going to say INTERVAL '+01:00' like that, and I'm going to copy that,
03:54I'm going to come over here, and I'm going to replace UTC over here with
03:57exactly the same thing.
03:58So you can specify your time zone as an interval relative to UTC instead of
04:04giving it an abbreviation, and so I'm going to say Go and now I should get an
04:08eight hour difference.
04:09So 16, that makes it just past midnight the same day, 16:16 that's correct, and
04:17if it were 16:16 in the UTC+ 1 then it would be 8:16 here.
04:24All right, so this is a very powerful and flexible facility for actually doing
04:30Time Zone arithmetic.
04:31For example, if you have a web site that's being accessed by people all over
04:34the world and you're keeping your local timestamps in UTC and you'd like it to
04:39be able to display them in people's local time zone then this creates an easy
04:43way for you to do that.
04:44Or if somebody uploads a file from a particular time zone and you want to
04:48convert that to another time zone.
04:50This also gives you a facility for doing that.
04:53So that's how we do Time Zone arithmetic in Postgres with standard SQL.
Collapse this transcript
Performing date and time arithmetic
00:00Postgres supports arithmetic on dates and times, using standard
00:04arithmetic operators.
00:06For example, I can simply say SELECT DATE, today's date, minus another date, and
00:20it will give me the number of days in between.
00:22Or instead of another date I can give it an INTERVAL, say 6 days and it will
00:32give me that other date, or I can do all of this with TIMESTAMPS.
00:39And so here I'm taking a date and time and I am subtracting 6 days 3 hours and 15 minutes.
00:44And it gives me a very specific date and time that's exactly 6 days 3 hours
00:49and 15 minutes earlier.
00:51So this is a very convenient feature and it allows us a lot of flexibility in
00:57how we handle dates and times in our SQL code.
Collapse this transcript
Getting parts of a timestamp with EXTRACT
00:00Postgres supports the EXTRACT function for extracting parts of dates and times.
00:05For example, we can say SELECT EXTRACT(HOUR FROM TIMESTAMP and give it a timestamp, say.
00:20And when I press Go, it says date part, but it's the hour.
00:24It says 15, which is the hour, which is exactly what we asked for.
00:28If instead I were to say MINUTE, we get one for the MINUTE part or if I were
00:35to just say MONTH, we get 10 for the Month part.
00:39So this is very convenient.
00:41In fact, we can even do this with intervals.
00:45I can say EXTRACT( MONTH FROM INTERVAL, and then give it an interval, 3 years 2
00:55months, 1 hour, 15 minutes and 2 is the month.
01:02So it extracted the months from the interval.
01:06So this is a useful tool for helping you to do math on different parts of your
01:11dates and times and intervals.
Collapse this transcript
9. PHP Interfaces
Choosing an interface
00:00PHP provides two distinct interfaces for the Postgres database system.
00:05The PDO interface PHP data objects use a normalized interface that works very
00:12similarly across the different supported database systems.
00:15Its PDO that allows me to write some of the scripts so that they work in MySQL, they
00:20work with SQL Light and they also work with Postgres with very little changes.
00:26PHP also supports a more native Postgres interface called PGSQL that more
00:32closely resembles the Postgres C library.
00:36First let's talk about PDO. PDO provides a common interface that's very similar
00:41across different database engines.
00:44This is the interface that's used most often and therefore it's the interface
00:48that gets most attention from developers.
00:51It has a rich set of methods, so it's possible to do just about anything you
00:55will want to do with your code.
00:57And it provides excellent performance, even superior performance in some cases
01:03over the native interface.
01:05The PGSQL interface is the native interface for the Postgres database engine.
01:11It was written on top of the Postgres C interface and is essentially just a wrapper.
01:16So expect it to work the same as what's documented in the Postgres documentation.
01:21It's a bit more granular, so you should be able to get all the functionality
01:25that you may need from the Postgres library.
01:28But it does not provide exception handling, so you'll need to check for errors
01:31manually in your code.
01:33For my part I prefer the PDO interface for most work and I will be showing you
01:37both in this chapter.
Collapse this transcript
Using the PHP PostgreSQL extension interface
00:00In this movie we are going to create a PHP script that accesses the database
00:04using the native Postgres interface.
00:08So we will start by making a working copy of the start.php.
00:11I am in the Chap09 folder of the Exercise Files and this is the copy of the
00:15Exercise Files that we put in the document root of the web server so that it's
00:18accessible to web server.
00:21I am going to go ahead and make a working copy of start.php and I'm going to
00:25name this example-pgsql.
00:26We will open that in the Text Editor.
00:33Before you continue, it's important that you update the password in this file to
00:37match the password you entered when you created the sid user in PG admin.
00:42You see here on line 14 I have foo.bar.
00:45This is where you'll need to put a password for your sid user exactly as you
00:49entered it in PG admin.
00:51And this is based on the sandbox code that we used in the QuickStart chapter.
00:56It's got a couple little differences.
00:58Down here in init function you notice that it doesn't connect to the database.
01:03The main function doesn't have a lot of the stuff that was there in the original
01:07version of this and you also notice that we are not calling in the BWPGSQL
01:11library, because we are not going to use that.
01:13We are going to be using the native Postgres interface instead.
01:18I am also going to delete this try block here, because the native Postgres
01:21interface does not support exceptions.
01:25So we will just start by deleting that and we are going to go ahead and
01:29initialize some variables here.
01:30tn is for the table name.
01:33So that'll get this TABLE_NAME constant.
01:35This is from these constants up here.
01:37I am just going to scroll up a little bit so you can see them.
01:39We are going to use these four constants right now.
01:42dbname for the DATABASE.
01:47user for the PGUSER and pass for the PGPASS.
01:53Now we are going to use these variables to connect to the database.
01:56There is a function called pg_connect and I am going to pass it a connection
02:06string and the connection string looks like this; host=localhost
02:12dbname=, and we will use the $dbname
02:18user=$user and password, all spelled out, =$pass
02:27Now because we don't have exceptions we have to check for errors every time, so say or error,
02:32I am going to put in a string and concatenate that with the pg_last error.
02:42That does not get the $, It's a function call.
02:46The string will say Could not connect:.
02:51Now that we've connected to the database to go ahead and send a couple queries
02:55to drop the table if it exists and to create the table.
02:59So we are going to use pg_query and we give it the database handle we just
03:04created and the query. And the query looks like DROP TABLE IF EXISTS and the
03:12TABLE_NAME which will be this variable that will get expanded and we will use or error.
03:18I am just going to copy and paste from up above here and we'll just change the
03:25string to say Query Failed.
03:30Now it's important to note here because we are in PHP that I'm using double
03:34quotes wherever I am expanding a variable inside the string and I am using
03:38single quotes wherever I am not.
03:39This is just a convention that I use.
03:42I could double quotes everywhere, but they say there's a slight performance
03:46improvement which really doesn't matter in this circumstance for using single
03:50quotes and under some circumstances if I was really worried about that I might
03:55just refuse to use the double quotes at all.
03:57In this case for convenience and for clarity I am just doing it this way.
04:01So I am going to go ahead and copy and paste this whole query and just change
04:07the query to say CREATE TABLE $tn and give it the table definition.
04:14We will have three columns a, b, and c and these will all be text columns.
04:19I'll go ahead and copy and paste and we have our error message already.
04:27Now that we have created our table we will go ahead and send out a message
04:30that says we've created our table and the message will say the Table %s
04:38created successfully.
04:41I think I've got enough letters in there.
04:43Now you will notice that my message function uses %s like printf and that's
04:48because if you look down here at the message function later in the code, you see
04:52that it uses variadic arguments just like printf.
04:55In fact, it calls vsprintf.
04:58So I like that it works just like printf.
05:00I find that really convenient,
05:01I do that a lot in my code.
05:04Now we are going to create a prepared statement.
05:06What a prepared statement does is it allows you to use one bit of SQL and just
05:11change the parameters and use it over and over again.
05:14So because we are using the native interface we can do this, we can also do
05:17this in PDO, and this is actually a real convenience and it can be a real
05:20performance gain as well.
05:23So we use pg_prepare to prepare the statement and we give it the database
05:29handle and we also give it a prepared statement name whereas I call it a statement handle.
05:35Then we are going to give it the SQL and again I am using double quotes, because
05:40I am going to expand the $tn variable and this is INSERT INTO $tn VALUES and we
05:48are going to give it the positions.
05:50Now most SQL engines will use question marks for the placeholders, for the
05:55parameters, but this one does not.
05:57This one requires number parameters with dollars signs.
05:59So $1, $2, $3, and fortunately PHP is smart enough to not expand those and not
06:07complain about those.
06:08Just to leave those alone as long as there aren't any variables that fit
06:11those particular tokens.
06:13Then I've got my or error again.
06:15I am just going to copy and paste that from above here and I am going to change
06:19this to say Prepare failed.
06:22Now once I've prepared the statement I can go ahead and use it, and re-use it
06:26with pg_execute and pg_execute gets the database handle, the prepared statement
06:34handle, and the parameters are put in an array.
06:38So put the parameters in array.
06:41We will have a, b, and c and we say or error pg_last_error.
06:51Now we can go ahead and make three copies of that and just change the parameters
06:55to 1, 2, and 3 and maybe we spell it out for the next ones, one, two, and three.
07:07So now what we've done here is we've created this prepared statement to insert
07:11into the table and we're calling that same prepared statement three different
07:15times with three different sets of parameters.
07:18Now that we've done that we can go ahead and read those rows back from the
07:21table and display them on the screen, and we are going to do that with pg_query
07:26and the difference here with this pg_query is that we are actually going to get results from it.
07:31These earlier pg_queries up above where we did the drop table, the create table,
07:36those aren't select statements and those don't return anything that we
07:40necessarily want to use.
07:41They return a status which we are using to check for error, but in this case
07:44we're going to use a results handle.
07:46We are just going to call this result and the query will look like this as the
07:51db handle and it says Select * From $tn
07:56It says very simple select statement.
07:59I am going to go ahead and terminate this with us semicolon because we have
08:02this results handle in a separate variable and I can test for that if not
08:07result for my error.
08:10error Query failed and give it the pg _last error and now that we have our
08:22results we can go ahead and display them.
08:25The way this works is recall something called pg_fetch and we are going to use
08:29the associative array version of it, and each time we call that with the
08:33results handle, it will go out to the database and it will get the next result from that query.
08:37So we put this in a while loop.
08:43Simply row = pg_fetch_assoc for the associate array version and with ($result)
08:53And that's our results handle.
08:56Now inside of this loop we simply display our results.
09:00Use copy and paste again and that looks like that.
09:12Again, we are using our variadic position parameters in message and we are
09:18referencing the elements in the associative array.
09:20That's the associative array that we got back from pg_fetch associate array
09:25and it went into row there
09:27so now we can now simply access those columns with a, b, and c just as we define
09:32them up here in the create table, a, b, and c.
09:34So this is really quite convenient to do it that way.
09:38Now that we have successfully inserted the rows into the table and read the
09:42rows back from the table, we can go ahead and drop the table and we do that with a drop table.
09:47I am just going to copy this one up there and copy down it here and just say
09:53drop table $tn and this line is actually short enough and I can put all
09:58of that on one line and just give the message that we've dropped the table.
10:02So I am saving by pressing Command+S on this Mac here, and let's just take a
10:17look at what we have done.
10:17We connected the database up here on line 32 and on line 35 we dropped table if
10:24exists using the pg_query and we used pg_ query again to create table and each of
10:31these queries actually each time we go out and do something with the database we
10:35are checking for the error and that's because this database interface does not
10:39have exception handling.
10:41Then we prepare a statement to insert into the table, and then we execute that
10:46prepared statement three times with different parameters to insert rows into the table.
10:51Finally, we have this select statement to read the rows back from the table and
10:56a while loop to fetch those rows and display them, and then we drop the table
11:02down here at the end.
11:04So let's go ahead and fire up the browser and take a look at this in action.
11:07Going out to my Exercise Files and Chap9 and example pgsql.php and there we have it.
11:15It works perfectly.
11:17Table test created successfully.
11:19I have three rows of data a, b, c, 1, 2, 3, and one, two, three spelled out,
11:23and table test dropped.
11:25So that is how you use the Postgres database engine within PHP using the
11:30native Postgres interface.
Collapse this transcript
Using the PDO interface
00:00In this movie, we're going to create a database application using the PHP PDO
00:04interface to access the Postgres Database Engine.
00:08We're going to start by making a working copy of the start.php file here in the
00:12Chapter 09 folder of the Exercise Files.
00:15This is the copy of the Exercise Files that's in the web server document root,
00:20in the htdocs folder here under the XAMPP directory.
00:24That's so that this is accessible to the web server, so that we can write our
00:28code and then test it on the web server.
00:30So I am going to go ahead and make a working copy here of start.php.
00:34I am going to name it example-PDO.php.
00:39I'll open that in the Text Editor.
00:42Before you continue, it's important that you update the password in this file to
00:45match the password you entered when you created the SID user in pgAdmin.
00:50You see here on line 14, I have foo.bar.
00:53This is where you'll need to put the password for your SID user, exactly as you
00:57entered it in pgAdmin.
01:00And this is a modified version of the sandbox code that we used in the Quick
01:05Start chapter, and you notice that this version does not call in the BWPG SQL
01:12Library, because we're not going to be using that, we're going to be using PDO directly.
01:16And you also notice that the init function is paired down, because we're not
01:20creating the database or anything in the init function.
01:22So we're going to start here in main and we're going to start right here under
01:26this $tn = TABLE_NAME;
01:29and we're going to go ahead and create a PDO object, $db = new PDO.
01:38I'm going to start with the connection string here, which looks like this, pgsql.
01:43That specifies the database engine, and a colon, and host=localhost;
01:50and port=5432 and dbname= and here we're going to use the string concatenation
02:00operator to bring in the DATABASE constant, because that is defined as a
02:04constant up here above, where these other constants are that we're also going to use.
02:09We're going to use the PGUSER constant, and the PGPASS constant.
02:14I am just going to bring this down to the next line.
02:16I will put in the semicolon right there, because we will be using that, and I am
02:21going to pass it an array, and this is a parameter array.
02:24You can put all kinds of stuff in here if you want to, but all I am going to put
02:27in here right now is PDO::ATTR_ PERSISTENT, and it's that one right there, and I
02:37am going to give it a value of true.
02:39Now, what this does is it tells the PDO driver it's okay to keep persistent
02:45connections open, and that allows if you have a web server that's handling a
02:50few connections at a time, it doesn't need to set up a connection to the
02:53database every time, it can keep those connections alive if this code is going
02:58to be used over and over again in those web server instances.
03:02And so this is actually a good performance enhancement and it doesn't really cost much.
03:07So I go ahead and use it pretty much every time.
03:09Now, I am going to go ahead and set another attribute, and I am going to do this
03:13using the set attribute method, just so you see how this is done.
03:19And this one is PDO::ATTR_ERRMODE.
03:24It's that one right there.
03:28And I am going to set it to this value PDO::ERRMODE_EXCEPTION.
03:36So that sets the error mode, so that it throws exceptions when there's an error.
03:39That way we don't need to be checking for errors with every call, instead we can
03:43just put all of our database code in this try block and catch the error once in
03:49the catch side of the try block.
03:50So now let's go ahead and execute some SQL, db-exec, and I am going to use
03:59double quotes because I am going to be expanding a string.
04:03I am going to be using this TABLE_NAME string that's defined up here, and it's
04:07DROP TABLE IF EXISTS $tn
04:10I am just going to go ahead and copy and paste here.
04:15Now I am going to create the table, CREATE TABLE $tn and three columns, a, b,
04:25and c and these are going to be TEXT columns.
04:32So now we've created our table.
04:33So we'll send out a message that says that, message('Table %s created
04:45successfully'), and we're going to give it that tn here, and so it will
04:49display the table name.
04:51Now we have created the table, and let's go ahead and populate it with a
04:55little bit of data.
04:56PDO allows us to use prepared statements, so we can take a statement handle, and
05:02say db->prepare, and then give it some SQL in here.
05:08We'll say INSERT INTO $tn VALUES, and give it placeholders, question mark,
05:16question mark, and question mark for the placeholders.
05:20And then we can execute that statement with the Statement Handle, execute, and
05:26we're going to do this three times with different data in it.
05:30We pass it an array with the parameters, and this array will have three
05:34elements to correspond with the three question marks, and it will place those
05:38parameters inside the SQL statement, and it will do escaping and make sure that
05:43it's safe when it does that.
05:44So this is really the best way to put parameters in an SQL statement;
05:50a, b, and c, and then we're going to do that three different times here, and
05:57just change the values; 1, 2, 3, and we'll spell out; one, and two, and three.
06:07So now we've populated the database, that was easy.
06:12Now, let's read that data back.
06:14$sth = db->prepare.
06:18So we're preparing another statement here; SELECT * FROM $tn.
06:26And then we set the Fetchmode for fetching the data, and we're going to fetch in
06:32an associative array.
06:33So $sth->setFetchmode(PDO::FETCH_ASSOC).
06:48And then we execute like that.
06:54And we don't have any parameters, so we don't have to pass any parameters to it.
06:58And then we can take that statement handle and we can actually iterate through
07:03it as an iterator with foreach.
07:04Now, what this does is that goes ahead and executes the fetches, row by row,
07:18putting each row into the row variable as an associative array.
07:23So now I can display those rows using message(%s, %s, %s) for the three strings,
07:33and then reference the associative array elements, go ahead and copy and paste
07:40this, and just change these.
07:44So these associative array keys correspond to the column names a, b, and c up in
07:51the CREATE TABLE statement, and that's all there is to it.
07:54Now we have fetched those rows from the table that we populated and we've
07:59displayed them, so now all that's left to do is to drop the table and exit.
08:03So $db->exec("DROP TABLE $tn") and message('Table<i>%s</i> dropped), and save
08:25that, pressing Command+S on my Mac here.
08:28Looks like I forgot a comma up there.
08:31I do also take this opportunity to do a little proofreading.
08:34We've created a new PDO object to connect to the database and we passed it the
08:39PGSQL as the type of database, and that tells PDO that this is a Postgres
08:45database that it's connecting to.
08:46We give it the host name, the port number, and the database name, and a user and
08:51password, and we set the persistent flag using that associative array there.
08:56We also set another attribute for error mode to exception, and then we execute a
09:02couple of SQL commands here;
09:04DROP TABLE IF EXISTS and CREATE TABLE, to make sure we're creating a fresh table each time.
09:09And then we insert three rows;
09:11a, b, c, 1, 2, 3, and one, two, three spelled out, and we do that with a
09:15prepared statement, and then we use another prepared statement to fetch those
09:19rows from the database. All right,
09:21so I am going to press Command+S again to make sure that I've saved this, and
09:25let's go ahead and fire it up in the browser.
09:28So navigating over to Chapter09, and we'll click on example-PDO.php, and there we have it.
09:36So this is working perfectly,
09:37it creates the table, it populates the table, it reads the table, and it drops the table.
09:44So there we have it.
09:45That's how we use the PDO interface in PHP to access a Postgres database.
Collapse this transcript
Creating a library
00:00Here I have opened the lib or library folder in the Exercise folders and this
00:06the copy of the Exercise folders that's in the web server document root in the
00:10htdocs folder and in this directory there are two files.
00:14One of them is the bwPgSQL.php.
00:19This is the database wrapper library that I created and this is actually the
00:24library that I use most of the time when I'm creating applications in PHP
00:28that use a database.
00:29Then there is the test-bwPgSQL, which is a simple test suite for testing the library.
00:36So what we're going to do we're going to take a look at this and we're going to
00:39talk about why I do this, why I think it's important to do this and what makes
00:44this a powerful choice for creating applications.
00:47So we'll go ahead and open the library in the text editor here, and let's
00:52just start by taking a little tour of the library.
00:54I call this a database CRUD wrapper.
00:57What that means is that it's a wrapper, because it basically wraps around
01:01the existing interface.
01:03The library itself uses the PDO interface to access the database, but it
01:07exposes a more friendly interface to the programmer and in some cases it might
01:12be specifically tailored to a given application . I'll often customize this for a given application.
01:18And I call it a CRUD library, because it also has some convenience functions for
01:24dealing with, creating, retrieving, updating, and deleting records in a database.
01:29At that level I tend to call them records as opposed to rows, even though they
01:32actually are rows, but it's just a slight paradigm shift in how I think about
01:37data in different circumstances.
01:40So this is an object-oriented library.
01:43So everything is in a class called the bwPgSQL, and you instantiate it by
01:49saying new bwPgSQL.
01:52You'll notice that each of the methods inside of this class, I've a little comment
01:56at the top of them that just gives a little usage so that I can look at this
02:00later and I can say, what is this and how do I use it.
02:04So this is the constructor and this does a little bit of work here.
02:07It actually instantiates a PDO object and it saves it in this private variable dbh.
02:14The this syntax in PHP is for saving things in private local variables inside of a class.
02:21If you've looked at the PDO movie in this chapter you see that this is very,
02:25very familiar how this works, and then I set the CLIENT-ENCODING to latin1 and
02:30I've this long comment here about how PHP doesn't play nice with Unicode and
02:35even UTF-8 is problematic.
02:37In the very latest versions of PHP especially the beta version that's out now as
02:42we're recording this, they're really trying to change that, they are really
02:45trying to fix how they use Unicode and perhaps by the time you're viewing this,
02:50this won't be true anymore.
02:51But I've been using this library for a long time and every once in a while I
02:55go back and revisit how PHP does Unicode, and I still haven't been satisfied
02:59with it at this point.
03:01And if this has been called with a table name, and you notice the table_name has a
03:05default value of NULL.
03:06So it's an optional parameter.
03:08If it's been called with a table_name then the table_name also gets stored in
03:12the private data up here and that's used for the CRUD applications.
03:18We have setter/getters for all these parameters;
03:20for the table_name, for the database handle, and for statement handle, and then
03:24we have some of the workhorse function.
03:26So sql_do--this gets used a lot.
03:29This performs SQL without a return result set.
03:33Instead it returns a count of the number of rows that have been affected, and
03:36again, this is very simple.
03:38It's really just a wrapper for prepare and execute.
03:41For doing multiple queries and again without a result set, it just calls the PDO exec method.
03:49sql_query actually returns a statement handle that allows you to iterate through a result.
03:56So this allows you to do something like a foreach loop, an iterator loop that
04:00actually has the SQL right there in the sql_query call, and so that's
04:05actually really convenient.
04:07In fact, let's just take a moment and divert and take a look at that in action here.
04:11This is the test suite, and you'll notice down here I have a foreach loop with
04:17the query right in the foreach loop.
04:19So I don't have to have intermediate variables.
04:20It's just very quick and easy and it just works.
04:23We can switch back to the library now.
04:27Then there is the dangerous fetchAll.
04:29I recommend that you absolutely never do this.
04:32I include it in the library just for completeness, but I've never used it and
04:35I don't recommend it.
04:36It basically reads all of the rows of your query into memory and then returns an array.
04:42There might be some circumstances where that would make sense, but most of the
04:45time that's just a really, really bad idea.
04:47Here is query_row for getting one row at a time.
04:50There is some circumstances where that be might be handy as opposed to iterating
04:54through these Statement handle.
04:55I like iterating through the Statement handle.
04:57query_value for getting one value, and again these are all very simple methods.
05:02We're going to get into some of the more complicated stuff here in a minute as
05:05we get into the CRUD, and then we have begin_transaction and commit, and again,
05:09those are just wrappers for the same named methods in the PDO Library.
05:13Now we get into the CRUD stuff.
05:15get_rec returns an associative array based on an id.
05:19So the way that I have the CRUD methods set up is it requires a column named
05:24ID that is a unique identifier, and you pass that and when it creates a new
05:30record in returns that and that's kind of the handle for a particular record
05:35or row in the table.
05:37So get_rec takes an ID and it returns a row.
05:42get_recs returns an iterable statement handle for basically all the rows in the table.
05:49It does SELECT with an asterisk.
05:52Insert inserts a new record and it uses an associative array.
05:58So you pass an associative array where the keys in the associative array are
06:03named the same as the columns in the table.
06:06You notice that it does a little bit of magic here to create the PHP insert, and
06:12in this case it uses the RETURNING clause which is specific to Postgres, and
06:17that gives it the ID that it can return.
06:20Update again it goes through a little bit of rigmarole to create the SQL and
06:26this updates a record.
06:27So you pass it the ID of the record and an associate array with just the columns
06:32that you want to update and it creates a custom SQL statement that just updates
06:38those particular columns.
06:39So you don't actually have to pass it the entire row,
06:43you just pass it the columns are changing, and that's a convenience.
06:47Delete is very simple. You pass an id.
06:49It deletes the row.
06:51get_next is again just a convenience method for getting the next record, and
06:57then we get down into some of the little utility methods.
07:00Count_recs just does SELECT COUNT.
07:03This is not a terribly efficient thing to do in Postgres, a lot of database
07:07engines like MySQL and SQLite, they have optimizations for this case.
07:13Because Postgres is so asynchronous and object-oriented there is really no way
07:17to do this efficiently.
07:19According to Postgres documentation they just don't see this as a priority.
07:22They would rather have the database be fast than convenient.
07:26So that's a design choice and again for data sets that are less than a few
07:31thousand records this shouldn't be a problem.
07:33But if you start getting these in very busy databases, busy web sites, busy
07:37database applications, you probably don't want to be calling COUNT * very often anyway.
07:43last_insert_id, this is really just for compatibility with other database
07:49engines like MySQL and SQLite who have something like this.
07:53In Postgres the serial columns like Serial Primary Key that automatically
07:58increments, what it does is it actually sets up a sequence generator, and it
08:03creates an alias and sequence generator within your table.
08:06So what this function has to do is it needs to go out there and grab the
08:09current value from the sequence generator and it approximates that methodology
08:14and you'll see in my CRUD application that I actually use something like this for compatibility.
08:19table_exists can be convenient sometimes for checking if a table actually exists
08:24and this queries the pg_tables view that comes as part of the default template
08:29for databases in Postgres.
08:31Version does two different things.
08:33It will either return the version of this library or the version of the Postgres
08:37database engine that's being connected to.
08:40These timer functions are useful for benchmarking.
08:44So what we have here is a test suite and every time I write a library like this,
08:49I will always create a corresponding test suite that goes through and exercises
08:52each of the different methods, and that's what this does.
08:55Let me scroll through a little bit slower so that you can see it.
08:57Here we've some constant definitions at the top.
09:00This is really based on my Sandbox code that you've seen elsewhere in this course.
09:04We see here, we connect to the database by creating a new bwPgSQL object.
09:10Create a table, insert some rows into the table, and that's exercising the
09:14sql_do method right there.
09:17Then we exercise the table_exists method by trying to test for a table that
09:23doesn't exist and testing for a table that does exist.
09:26Here we test sql_query, here we test sql_query_row, and now we start getting
09:33into the CRUD methods.
09:35There is get_rec, there is get_recs, there is insert, there is update, and
09:43delete, and then we DROP the TABLE.
09:46Before you test this in your browser, it's important that you update the
09:48password in this file to match the password you entered when you created the
09:52SID user in pgAdmin.
09:54You see here on line 17 I have foo.bar.
09:58This is where you'll need to put the password for your SID user exactly as you
10:02entered it in pgAdmin.
10:04So let's take a look at this in the browser.
10:06We'll go ahead and open the browser and navigate to the lib folder and there is
10:12the test-bwPgSQL.php. Here we have it.
10:16Again, this is very much like my Sandbox code that you have seen elsewhere in
10:20this course and effectively I'm just testing all of the different methods in the library.
10:25I'm displaying all of the versions at the top here.
10:27This is the version of the test suite here.
10:30This is the version of the library.
10:32Here's the version of Postgres.
10:33And I'm timing things, testing for table that does exist
10:38takes 6 milliseconds testing for a table that doesn't exist
10:40takes 1 millisecond.
10:42So these things make sense.
10:43I'm writing a library.
10:44I'm experimenting with the library, and I want to test it as I do that, and
10:49that's really all that this is about.
10:51So we can see that everything is executing just fine.
10:54The whole elapsed time set is 100 milliseconds.
10:58So I hope you can see the value of creating your own libraries.
11:00You're welcome to use my library, you're welcome to modify it, and you're
11:04welcome to use it for your own purposes.
11:06Do with it whatever you like.
11:07It's a great convenience.
11:09It allows the code to be more streamlined for you to pay more attention to the
11:13application that you're building rather than exactly how does the database work.
Collapse this transcript
10. Web Applications
Defining CRUD
00:00In this chapter we're going to look at a couple of different ways to do CRUD -
00:03Create, Read, Update, Delete.
00:05These are the basic four functions of any database application.
00:08In this movie we're looking at the CRUD application that we loaded up when we
00:12initially installed the database, and you notice I've created another
00:15shortcut on my toolbar here.
00:17We didn't do that when we first installed, but there it is, and you notice that
00:21this is just a localhost/CRUD/crud.php, and I just drag that down in my toolbar
00:29to create that button.
00:31So this is a basic CRUD application.
00:33It is a web application;
00:34it's running in a web browser.
00:36We'll look at the code in another movie, for right now we're just going to take
00:40a tour through the application itself.
00:42This keeps a database of albums and the tracks in the albums, and so it's really
00:46managing two different tables.
00:48It has got Album Table and a Tracks Table and these are joined together.
00:53For example, if I want to click on one of these Albums down here, let's click on
00:58Birds of Fire by the Mahavishnu Orchestra, great album.
01:01And you notice that we have the album data up at the top and now at the bottom
01:05we've got the tracks, and the tracks are in order of track number and they have
01:08a title and they have a duration.
01:10So rather than edit these, let's go ahead and create our own album here.
01:14I'm going to just name this one Foo, and the Artist will be Bar and the
01:19Label will be Baz, and we'll just put in our Released Date here, and I'll click Add Album.
01:27And it immediately takes me to the Edit Album screen, where I can start adding tracks.
01:31And you'll notice that the cursor is already positioned down there on the
01:35first field of the tracks, where I can enter a Track number and a Title and a Duration.
01:40Now the Duration, I can enter it in number of seconds, or I can do it in
01:45minutes and seconds.
01:47And when I press the Add button, it adds that track down below, and it puts the
01:51cursor in position to add the second track, so I'll just do that.
01:53I'm going to enter this one in number of seconds, and you'll see that
01:58it converts for me.
02:00So there is Track 2 below Track 1.
02:01Let's just add another couple of tracks here.
02:09If I want to, I can edit these tracks.
02:11I can come down here to Track #3 and I can change the Duration say to 3:45 and
02:18click Update and it updates that in the database.
02:21Or if I want to I can Delete a track, ask me to confirm, and there now that
02:27track is gone, and I can add it back in if I want to, and there Track 3 is now called 5.
02:36And you'll also notice that if I come over here to the SID application, I'm
02:40going to hold down the Command key while I click on this, and it will open it in
02:42another tab, and I select the album Database.
02:47I can just type in select * from album, and there is a list of all the albums.
02:53And you'll notice that the last one there is called Foo, the artist Bar, and
02:57label Baz, and there is the release date.
02:59And if I want to see the tracks for it, I can just say select * from track where
03:04id =, and maybe I don't know the id.
03:07Well, I see the id over here, and that's actually album_id, but instead I can
03:12give it a subselect and say, select id from album where title = 'Foo', and that
03:22gives me all the tracks there for the album called Foo.
03:25So I can actually look at this data and I can manipulate this data in SID, and
03:29that gives me some insight into what's going on over here in CRUD.
03:33Now, if you notice, if I go back over here to the main screen and I see my Foo,
03:39Bar, Baz album there, notice it's got the total duration.
03:42It's got all the information there.
03:44I can click Edit and I can see all the tracks, or if I want to I can actually
03:48delete the entire album.
03:50If I press Confirm Delete, you'll notice now that it's all gone, even the tracks are gone.
03:55If I put in here #19, because I know that that was the album id, the tracks are
04:00gone, and if I select * from album, it has actually deleted the album and it has
04:08deleted all of the tracks.
04:10So it's a fairly complete CRUD application.
04:13Now, in the next movie we'll go ahead and we'll look at the code that makes
04:16this work.
Collapse this transcript
Using PHP to insert, read, update, and delete rows in a PostgreSQL database
00:00Now we're going to take a look at the code that makes the CRUD application work.
00:03If you look in your CRUD folder in your ExerciseFiles, you'll see that there's
00:07an assets folder and inside that assets folder is a little icon file and four
00:13PHP files and an index.html file.
00:16The index.html file is really not even used at all.
00:21It says, This page intentionally left blank, and the purpose of it is in case
00:26this is on a web server someplace and somebody tries to look at a directory, I
00:30do this in all of my unused directories.
00:33You'll notice the same thing in the css directory--there's another one of those.
00:37The css directory has the main.css file, and this is exactly the same as the one
00:41for the SID program, which explains the similar color scheme.
00:45In the assets folder, you've got a footer.php.
00:49There is a bit of HTML with some variables that get replaced in PHP.
00:53There is a header.php, similar deal there,
00:57plain.php, which I think in this case is actually not even used,
01:01and main.php, which is the main layout of the middle of the screen here.
01:07And again, it's got variables that get replaced and it allows you to do things
01:11like, with these form fields there is a little bit of PHP to echo the value
01:16and things like that.
01:17It's all very simple and straight forward stuff here.
01:19There is the bottom of that file.
01:22But the main work is done here in crud.php.
01:25So this is actually a fairly long file, it's 1100 lines.
01:29It's got a number of separate functions in it.
01:33And the bottom line for this is that, like so many applications it initially
01:38started out as one thing and it kind of grew. Initially it was a demonstration
01:43for my PHP Essential Training course, and then it got modified and made a
01:48little bit more robust for MySQL, and then it got extended to also support
01:53SQLite and Postgres.
01:55And so all of this is done in exactly the same program, and in fact, if you want
01:59to take this same program and run it with SQLite, you just comment this section
02:03out here, and you uncomment this section here, and if you wanted to run with
02:07MySQL, you just uncomment this section here.
02:10You'll notice throughout the code, like here in init, you'll see something like
02:16this, a Switch statement on DBENGINE, and if it's sqlite3, it uses this,
02:21if it's mysql, it uses that,
02:23and in our case, for Postgres, which is pgsql, it uses this part here.
02:29This is the beauty really of the PDO interface in PHP is because even though
02:35there is some different setup stuff here, a lot of this code, if we come down
02:39here to get_tracks_sql,
02:42let's try one of the other ones here.
02:46Here we are, insert_album_sql.
02:49This is exactly the same.
02:51This exact same SQL works for any of those three engines.
02:55And so this is true for a lot of it.
02:57And then some of it, like for instance, the one before it, the get_tracks_sql,
03:02because the way that we handle dates and because of some of the differences in
03:05the SQL that's supported by the different engines, we have this Switch statement
03:09and we have different SQL for each of these.
03:13For now, let's go back up to init, and a lot of what I do in here has to do with
03:19PHP and things that I like and don't like about PHP, but we're going to
03:24concentrate on the SQL parts here,
03:26and so here's how I connect to the SQL database.
03:29So I'm using PDO, so I have a PDO connect string here.
03:33I set the client_encoding to latin1, and I get the version of the Postgres server.
03:39And so that ends up being displayed right down here where it says Postgres
03:43server version 9.1.1. But we're going to skip through some of this, and like I
03:51said, we're just going to concentrate on the parts that actually interact with the database.
03:55One of the first things we do is we get_ albums, and get_albums is just a simple
03:59Select on the album table.
04:02In here, also at some point we called get_album_length, and that's to display
04:07this length of the album down here.
04:10You'll notice that I have two different versions of the SQL for this, from the
04:14SQLite and the Postgres version.
04:16This wasn't a feature I had added yet when I did the MySQL version.
04:19I haven't gone back and added it yet.
04:21But you'll notice for the Postgres version I sum up all of the durations of the
04:26tracks where the album_id is the right album,
04:30and then I take the integer division for the minutes and the integer modulus for
04:35the seconds, and for the modulus I use this Format string to make sure it has
04:40that leading 0, and then I just concatenate it with the colon.
04:44So again, that gives us this display format here, 53 minutes 27 seconds for that
04:49album at the bottom.
04:50Let me back up to get_tracks.
04:56get_tracks is another one where we have to do the same kind of a trick for
05:01the duration, and so that makes this different for each of the different database engines.
05:05And this comes into play when we go over to the tracks,
05:08let's click on the tracks for this one here, and you see we're displaying each
05:12of the tracks with that duration.
05:16Then we have the insert_album_sql, again, this is pretty straightforward, the SQL is
05:20the same for each of the engines.
05:22The one difference here is that PDO has this lastInsertId model which comes from
05:29MySQL, which is probably the most popular engine on the Internet.
05:33And Postgres doesn't exactly support that model, but what it does have is a way
05:39of getting the current position of the sequence engine.
05:43Remember that the serial primary key model is supported by a sequence engine.
05:49And if you want to get the current sequence of a particular sequence you can
05:52pass lastInsertId the name of that sequence and it will return exactly the same
05:57value, and it makes it work like MySQL and also like SQLite, which imitates
06:04MySQL in this particular behavior.
06:06We do the same thing when we're inserting a track.
06:08Again, the SQL is very straightforward, and we have this same technique for
06:14getting the lastInsertId.
06:18update_album is exactly the same for all of them and it's a simple
06:22update statement in SQL.
06:24And you notice we have a prepare and an execute where we provide the parameters.
06:29update_track_sql, again, very straightforward.
06:34delete_album_sql uses two different queries and has to do this in two steps, so
06:39that it make sure that it deletes all the tracks before it deletes the album.
06:43And that's a really important sequence, because if the operation were to be
06:47interrupted, and you had deleted the album, but you hadn't deleted the tracks,
06:50those tracks would be orphaned forever.
06:52There wouldn't be any easy way for you get in there and clean that up,
06:56except perhaps manually.
06:58So first we delete the tracks, which happens here, check for errors, and then
07:03we delete the album.
07:07Here is where we delete an individual track and again, that's very
07:10straight forward, and fetching an individual album.
07:15And finally, here we have the fetch track, which we've looked at before, which
07:19has a little bit of extra logic for handling the duration.
07:22So that's a quick overview of the SQL parts of this application.
07:27Of course you've got the whole source code here and it's even part of the
07:31free Exercise Files, so if you don't have a Premium subscription, you still have these files.
07:36So feel free to go through it, look at it, modify it, and use it for your
07:40own purposes.
Collapse this transcript
Installing the testimonials database
00:00Before you can test or use the testimonials database applications, you'll need to
00:04install the testimonials database and this is really very easy to do.
00:10Here you see I have the pgAdmin III application open on my desktop and in the
00:15Object browser over here on the left I have Databases selected, and over here on
00:20the right it lists the four databases that we've had all along.
00:24And here we are going to create a new one called Testimonials.
00:28So with Databases selected in the Object browser, I just press this cool Create
00:32One of These button and it brings up the New Database dialog.
00:36So I type the Name of the new database and the owner will be Web, just like the
00:43other ones, and of course that means that it can be used by the SID user, which
00:47inherits the web user, and I just press OK and we have a new database, unless
00:53it's not showing up here.
00:54If I press Refresh, there it is.
00:56Sometimes that happens.
00:58So now I select the testimonials database in the Database browser on the right,
01:04and I just press the SQL button up here to get the SQL query browser.
01:09And I press the open button and with Exercise Files selected over here in my
01:15Exercise Files under Testimonials and then SQL.
01:19There is the SQL for creating the tables and populating the data in the
01:24testimonials database.
01:26It's called testimonials-pg.sql, and I click Open and Execute query, and there we're done.
01:37Now we have successfully created and populated the testimonials database.
01:42Now before we contest it, we need to make sure the passwords are set correctly
01:46in the scripts that will be using the testimonials database, so I'll close this
01:50and I'll come up here and I'll open db. php, and right here on line 15 you'll see
01:56I have the string foo.bar.
01:58This is where you'll need to put the password for your SID user, exactly as you
02:01entered it in pgAdmin.
02:04So we'll go ahead and close this and open the testimonials.php and we do the same thing,
02:10this time the password is on line 13, and again, you see the string foo.bar.
02:16This is where you'll need to put the password for your SID user exactly as you
02:19entered it in pgAdmin.
02:22Now let's open it in the web browser and test it.
02:25So we'll come down here and open up Firefox, and I am going to click on my
02:29Exercise Files and on testimonials, and I am going to open test page.php. That's
02:36the page that displays the testimonials.
02:39And there you have it.
02:40This is just a little test page and you see the testimonials on the right.
02:45There are just little quotes I have in the database, they are not actually
02:48testimonials and if I press Reload, I get a different random set of three
02:53testimonials each time.
02:54We'll be looking more closely at how this works in the rest of the chapter, but
02:58for now the testimonials database is installed and it's ready to use.
Collapse this transcript
An overview of the testimonials application
00:00The other application we are going to look at in this chapter is the
00:03Testimonials application and here I've brought this test page.
00:07This is in Exercise Files in the Testimonials folder and it's called
00:12testpage.php and you notice that every time you load the page, it shows this
00:17box of testimonials, and every time you reload, the testimonials change.
00:21And so you see that they are different sizes, so the page wraps a little bit
00:25differently, in this case they are just little quotes, but the reason I
00:29originally designed this application was, because on my web site I wanted to
00:32have a little box with some testimonials from customers, clients and people
00:37who've viewed my courses.
00:38And so it's a simple little application.
00:41If we look here in the testimonials folder, you'll see there is an assets
00:45folder that has some of the HTML pages as PHP because the application is written in PHP.
00:51And it's got a couple of CSS files;
00:54all of this is included in your Exercise Files.
00:56There is a db.php, and this is the main interface for editing the database.
01:01We'll look at that in a moment.
01:02There is a testimonials.php, and this is the interface for reading the
01:06testimonials database and displaying these random testimonials on the page. And
01:11there is the test page itself, which is the page we're seeing displayed there.
01:15If I bring that up, you see it's mostly HTML and it has this little bit of PHP
01:20in it right here to include the testimonials application itself, and the rest
01:25of that is just HTML.
01:26Now when you want to manage the database, you use this db.php and you notice it
01:33says at the top here there are 14 testimonials in the database, add some more.
01:37And see the interface is very similar to what we saw in the CRUD application.
01:42It's a layout that I happen to like, and so you can enter a new one at the top,
01:46or you can edit the existing ones at the bottom.
01:48And here is the difference here is we have this little paging panel here, where
01:52if I click the right arrow it will take me to page 2,
01:54If I click it again, it takes me to page 3 and now it's grayed out.
01:58I can click directly on any of the pages, and as we add more testimonials, it
02:05simply adds pages and that makes it easier to manage having a lot of data.
02:10And I always hoped to have a lot of data, but I haven't really managed mine too
02:13well on my web site.
02:14I don't take a lot of time to manage my web site.
02:16These are listed alphabetically, and if I want to click on one of these, click
02:21on Muhammad Ali, Don't count the days, make the days count.
02:24If I wanted to I could edit it, and click Update, and now about one is updated
02:32in the database there.
02:33I think that was on page 2 I guess.
02:36I can edit it again and take that extra text out, update the testimonial.
02:42Or I can add a new one. Add that, and we see there it is there.
02:56I can Edit it, or I can Delete it.
03:01And so it's all pretty straight forward.
03:03In the next movie we'll start looking at how the code works.
Collapse this transcript
Managing the database in PHP
00:00In this movie we're going to look at the code for the testimonials database
00:03management function.
00:04In your Exercise Files you find this under the Testimonials folder and in db.php.
00:12This is actually a pretty straightforward piece of code.
00:14At the top of the code here you'll find some constants are defined and we are
00:18also, including the bwPgSQL.php library.
00:23So this definitely does use that library and you can see how using a library
00:28like this makes the code quite a bit cleaner and easier to code.
00:32So you'll notice here in the init function I instantiate a new bwPgSQL object
00:40and there is a little jump function here that makes managing the state of the
00:43web connection quite a bit easier based on an action variable, whether to add,
00:48edit, update, delete.
00:50So that makes that all pretty easy.
00:53So adding an item is simply a matter of running some PHP escapes on it to make
01:00sure that it's safe and then calling db insert.
01:03And if there is an error I catch it with the PDOException, and display the error message.
01:09In delete_confirm I go out and get the record with the get_rec method and
01:15display it and give the option to confirm deleting this particular testimonial.
01:21And when it's confirmed, I go ahead and do it using the delete method.
01:27In update, again, we escape with the PHP htmlentities, and call the update
01:34method in the CRUD library.
01:36Seeing a pattern here? In the edit function we use get_rec to get the data to
01:40display and offer the user the opportunity to edit that record.
01:46For listrecs it's just a little bit more complicated, because we have the
01:50paging thing going on.
01:52Remember that we're displaying these items by page.
01:56So we need to do a little bit of math and decide how many we're displaying on a
01:59page, remember up here at the top there is a page limit and that's the constant
02:04that says, how many we are displaying on a page at a time.
02:08And so we do a little bit of math around that right here, and then we set up
02:14the paging bar and we call this list_ pagebar function, which we'll get to in a
02:17moment and then, because this is a little bit more complicated than a standard
02:22CRUD operation, we have just a little bit of SQL in here using the LIMIT and
02:26OFFSET clause for SELECT, and that allows us to display, for example, 5 on a
02:31page 5 in, or 10 in.
02:36And here we have the sql query function from the bwPgSQL library and you notice
02:41it's being used as an iterator inside the foreach loop.
02:45Listing the pagebar, this doesn't have any SQL, it doesn't actually access the database,
02:50but is database related and it's simply a matter of knowing what page number run
02:54and how many pages there are and then displaying the HTML for that.
02:59That's pretty much it, what's left here is managing the page, managing the
03:03forms, same variables, callbacks, html forms, hidden variables, messages
03:11and error messages.
03:12So you can see this is pretty straight forward,
03:15it's only about 350 lines.
03:18Comparing this to the CRUD application, you can see just how much simpler it
03:22is to deal with the database parts of an application when you have a decent
03:27CRUD library.
Collapse this transcript
Displaying the testimonials using PHP
00:00In the previous movie we looked at the code for managing the database for
00:03testimonials application.
00:05In this movie we are going to look at the code for displaying the testimonials.
00:09Here you see them on the page here and when I reload, you see we get a different
00:13set of random quotes.
00:16Of course, these will be actual testimonials, in the real application,
00:18we just got to fill it with some random quotes here.
00:21And so in this movie we are going to look at the code that actually does that.
00:24We'll take a given number of quotes out of the database and display them at random
00:29every time it's reloading.
00:31So looking in our testimonial's folder from the Exercise Files you will see
00:35a PHP file here called testimonials.php and we are going to open that in our editor.
00:41This one is really very simple.
00:43It's only 92 lines long.
00:45At the top here we have our constants for connecting the database.
00:49You will notice that there is an init function where we actually do connect to
00:54the database and that should all be very familiar at this point.
00:57We are using the bwPgSQL library for this.
01:01PHP makes some of this easy for us.
01:04I have done this same application in a number of different languages, because I
01:06use it as an example in my language courses as well.
01:09So the first thing we do here is we go out to the database and here in the foreach loop,
01:15we use this query to just grab an array of the IDs and then the number of IDs is
01:24done by counting the members of the array.
01:26That's a PHP function.
01:28Here we check to see if the amount of random quotations we want is more than we
01:33can reasonably expect to do at random out of the database, and if so, we just
01:37display a message, and I just arbitrarily decide you need to have four times as
01:41many in the database as the number of random items you want to display.
01:45And then this lovely PHP function here, array_rand will give you a certain
01:50number of random items out of an array, so I didn't have to right there in
01:54PHP, that was already done for me.
01:56And then I grab those IDs out of list and I go ahead and I call printrec with
02:02each one of them and printrec simply goes out of the database and grabs the rec
02:06with get_rec and displays it with printf.
02:10It's as simple as that.
02:11So that's a very simple application for displaying random quotes out of the database.
02:15Of course, that's the easy part, the managing the database part is what we
02:19covered in an earlier movie in this chapter.
Collapse this transcript
Conclusion
Goodbye
00:00In this course my goal was to give you a good understanding of Postgres 9 so you
00:04can use it with PHP to build powerful and compelling applications for yourself
00:09and for your clients.
00:10I have covered the basic features of Postgres, its functions, its use of SQL,
00:14and I have walked you through some real-world PHP applications that use
00:18Postgres so you can apply your knowledge to building your own projects with Postgres and PHP.
00:24I have really enjoyed creating this course for you and I sincerely hope that
00:27it's as useful for you as it has been fun for me.
Collapse this transcript


Suggested courses to watch next:

SQL Essential Training (2h 22m)
Bill Weinman

PHP with MySQL Beyond the Basics (10h 27m)
Kevin Skoglund



Are you sure you want to delete this bookmark?

cancel

Bookmark this Tutorial

Name

Description

{0} characters left

Tags

Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading
cancel

bookmark this course

{0} characters left Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading

Error:

go to playlists »

Create new playlist

name:
description:
save cancel

You must be a lynda.com member to watch this video.

Every course in the lynda.com library contains free videos that let you assess the quality of our tutorials before you subscribe—just click on the blue links to watch them. Become a member to access all 104,141 instructional videos.

get started learn more

If you are already an active lynda.com member, please log in to access the lynda.com library.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Access to lynda.com videos

Your organization has a limited access membership to the lynda.com library that allows access to only a specific, limited selection of courses.

You don't have access to this video.

You're logged in as an account administrator, but your membership is not active.

Contact a Training Solutions Advisor at 1 (888) 335-9632.

How to access this video.

If this course is one of your five classes, then your class currently isn't in session.

If you want to watch this video and it is not part of your class, upgrade your membership for unlimited access to the full library of 2,025 courses anytime, anywhere.

learn more upgrade

You can always watch the free content included in every course.

Questions? Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com.

You don't have access to this video.

You're logged in as an account administrator, but your membership is no longer active. You can still access reports and account information.

To reactivate your account, contact a Training Solutions Advisor at 1 1 (888) 335-9632.

Need help accessing this video?

You can't access this video from your master administrator account.

Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com for help accessing this video.

preview image of new course page

Try our new course pages

Explore our redesigned course pages, and tell us about your experience.

If you want to switch back to the old view, change your site preferences from the my account menu.

Try the new pages No, thanks

site feedback

Thanks for signing up.

We’ll send you a confirmation email shortly.


By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

Keep up with news, tips, and latest courses with emails from lynda.com.

By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

   
submit Lightbox submit clicked