Home > Articles

This chapter is from the book

This chapter is from the book

Creating, Destroying, and Viewing Databases

Before you can do anything else with a PostgreSQL database, you must first create the database. Before you get too much further, it might be a good idea to see where a database fits into the overall scheme of PostgreSQL. Figure 3.1 shows the relationships between clusters, databases, schemas, and tables.

Figure 3.1

Figure 3.1 Clusters, databases, schemas, and tables.

At the highest level of the PostgreSQL storage hierarchy is the cluster. A cluster is a collection of databases. Each cluster exists within a single directory tree, and the entire cluster is serviced by a single postmaster. A cluster is not named—there is no way to refer to a cluster within PostgreSQL, other than by contacting the postmaster servicing that cluster. The $PGDATA environment variable should point to the root of the cluster’s directory tree. A cluster is serviced by a single postmaster process. The postmaster listens for connection requests coming from client applications. When a connection request is received (and the user’s credentials are authenticated), the postmaster starts a new server process and connects the client to the server. A single client connection can only interact with a single database at any given time (but a client application can certainly open multiple connections if it needs to interact with several databases simultaneously). A postmaster process can connect a client application to any of the databases in the cluster serviced by that postmaster.

Four system tables are shared between all databases in a cluster: pg_group (the list of user groups), pg_database (the list of databases within the cluster), pg_shadow (the list of valid users), and pg_tablespace (the list of tablespaces).

Each cluster contains one or more databases. Every database has a name that must follow the naming rules described in the previous section. Database names must be unique within a cluster. A database is a collection of schemas.

A schema is a named collection of tables (as well as functions, data types, and operators). The schema name must be unique within a database. Table names, function names, index names, type names, and operators must be unique within the schema. A schema exists primarily to provide a naming context. You can refer to an object in any schema within a single database by prefixing the object name with schema-name. For example, if you have a schema named bruce, you can create a table within that schema as

CREATE TABLE bruce.ratings ( ... );
SELECT * FROM bruce.ratings;

Each connection has a schema search path. If the object that you are referring to is found on the search path, you can omit the schema name. However, because table names are not required to be unique within a database, you may find that there are two tables with the same name within your search path (or a table may not be in your search path at all). In those circumstances, you can include the schema name to remove any ambiguity.

To view the schema search path, use the command SHOW SEARCH_PATH:

movies=# SHOW SEARCH_PATH;
search_path  
--------------
 $user,public
(1 row)

The default search path, shown here, is $user,public. The $user part equates to your PostgreSQL user name. For example, if I connect to psql as user bruce, my search path is bruce,public. If a schema named bruce does not exist, PostgreSQL will just ignore that part of the search path and move on to the schema named public. To change the search path, use SET SEARCH_PATH TO:

movies=# SET SEARCH_PATH TO ‘bruce’,’sheila’,’public’;
SET

You create a new schema with the CREATE SCHEMA command and destroy a schema with the DROP SCHEMA command:

movies=# CREATE SCHEMA bruce;
CREATE SCHEMA

movies=# CREATE TABLE bruces_table( pkey INTEGER );
CREATE TABLE

movies=# \d 
      List of relations
 Name           | Schema | Type  | Owner 
----------------+--------+-------+-------
 bruces_table   | bruce  | table | bruce
 tapes          | public | table | bruce
(2 rows)

movies=# DROP SCHEMA bruce;
ERROR:  Cannot drop schema bruce because other objects depend on it
        Use DROP ... CASCADE to drop the dependent objects too

movies=# DROP SCHEMA bruce CASCADE;
NOTICE:  Drop cascades to table bruces_table
DROP SCHEMA

Notice that you won’t be able to drop a schema that is not empty unless you include the CASCADE clause. Schemas are a relatively new feature that first appeared in PostgreSQL version 7.3. Schemas are very useful. At many sites, you may need to keep a "development" system and a "production" system. You might consider keeping both systems in the same database, but in separate schemas. Another (particularly clever) use of schemas is to separate financial data by year. For example, you might want to keep one year’s worth of data per schema. The table names (invoices, sales, and so on) remain the same across all schemas, but the schema name reflects the year to which the data applies. You could then refer to data for 2001 as FY2001.invoices, FY2001.sales, and so on. The data for 2002 would be stored in FY2002.invoices, FY2002.sales, and so on. This is a difficult problem to solve without schemas because PostgreSQL does not support cross-database access. In other words, if you are connected to database movies, you can’t access tables stored in another database. Starting with PostgreSQL 7.3, you can keep all your data in a single database and use schemas to partition the data.

When you create a schema, you can specify an optional tablespace—by default, tables created within the schema will be stored in the schema’s tablespace. We discuss tablespaces in more detail in the nextwith the CREATE SCHEMA section.

Tablespaces

Starting with PostgreSQL version 8.0, you can store database objects (tables and indexes) in alternate locations using a new feature called a tablespace. A tablespace is a name that you give to some directory within your computer’s filesystem. Once you create a tablespace (we’ll show you how in a moment), you can create schemas, tables, and indexes within that tablespace. A tablespace is defined within a single cluster—all databases within a cluster can refer to the same tablespace.

To create a new tablespace, use the CREATE TABLESPACE command:

CREATE TABLESPACE tablespacename 
  [ OWNER username ] 
  LOCATION ‘directory

The tablespacename parameter must satisfy the normal rules for all identifiers; it must be 63 characters or shorter and must start with a letter (or the name must be quoted). In addition, you can’t create a tablespace whose name begins with the characters ‘pg_’ since those names are reserved for the PostgreSQL development team. If you omit the OWNER username clause, the new tablespace is owned by the user executing the CREATE TABLESPACE command. By default, you can’t create an object in a tablespace unless you are the owner of that tablespace (or you are a PostgreSQL superuser). You can grant CREATE privileges to other users with the GRANT command (see Chapter 23, "Security" for more information on the GRANT command).

The interesting part of a CREATE TABLESPACE command is the LOCATION ‘directory’ clause. The LOCATION clause includes a directory—objects created within the tablespace are stored in that directory. There are a few rules that you must follow before you can create a tablespace:

  • You must be a PostgreSQL superuser

  • PostgreSQL must be running on a system that supports symbolic links (that means you can’t create tablespaces on a Windows host)

  • The directory must already exist (PostgreSQL won’t create the directory for you)

  • The directory must be empty

  • The directory name must be shorter than 991 characters

  • The directory must be owned by the owner of the postmaster process (typically a user named postgres)

If all of those conditions are satisfied, PostgreSQL creates the new tablespace.

When you create a tablespace, the PostgreSQL server performs a number of actions behind the scenes. First, the permissions on the directory are changed to 700 (read, write, and execute permissions for the directory owner, all other permissions denied). Next, PostgreSQL creates a single file named PG_VERSION in the given directory (the PG_VERSION file stores the version number of the PostgreSQL server that created the tablespace—if the PostgreSQL developers change the structure of a tablespace in a future version, PG_VERSION will help any conversion tools understand the structure of an existing tablespace). If the permission change succeeds, PostgreSQL adds a new row to the pg_tablespace table (a cluster-wide table) and assigns a new OID (object-id) to that row. Next, the server uses the OID to create a symbolic link between your cluster and the given directory. For example, consider the following scenario:

movies# CREATE TABLESPACE mytablespace LOCATION ‘/fastDrive/pg’;
CREATE TABLESPACE

movies# SELECT oid, spcname, spclocation
movies-#   FROM 
movies-#     pg_tablespace
movies-#   WHERE
movies-#     spcname = ‘mytablespace’;
  oid  |   spcname    | spclocation
-------+--------------+--------------
 34281 | mytablespace | /fastDrive/pg

In this case, PostgreSQL assigned the new tablespace (mytablespace) an OID of 34281. PostgreSQL creates a symbolic link that points from $PGDATA/pg_tblspc/34281 to /fastDrive/pg. When you create an object (a table or index) inside of this tablespace, the object is not created directly inside of the /fastDrive/pg directory. Instead, PostgreSQL creates a subdirectory in the tablespace and then creates the object within that subdirectory. The name of the subdirectory corresponds to the OID of the database (that is, the object-id of the database’s entry in the pg_database table) that holds the new object. If you create a new table within the mytablespace tablespace, like this:

movies# CREATE TABLE foo ( data VARCHAR ) TABLESPACE mytablespace;
CREATE TABLE

Then find the OID of the new table and the OID of the database (movies):

movies# SELECT oid FROM pg_class WHERE relname = ‘foo’;
  oid
-------
 34282
(1 row)

movies# SELECT oid FROM pg_database WHERE datname = ‘movies’;
  oid
-------
 17228
(1 row)

You can see the relationships between the tablespace, the database subdirectory, and the new table:

$ ls -l $PGDATA/pg_tblspc
total 0
lrwxrwxrwx    1 postgres postgres       12 Nov  9 19:31 34281 -> /fastDrive/pg

$ ls -l /fastDrive/pg
total 8
drwx------    2 postgres postgres     4096 Nov  9 19:50 17228
-rw-------    1 postgres postgres        4 Nov  9 19:31 PG_VERSION

$ ls -l /fastDrive/pg/17228
total 0
-rw-------    1 postgres postgres        0 Nov  9 19:50 34282

Notice that $PGDATA/pg_tblspc/34281 is a symbolic link that points to /fastDrive/pg (34281 is the OID of mytablespace’s entry in the pg_tablespace table), PostgreSQL has created a subdirectory (17228) for the movies database, and the table named foo was created in that subdirectory (in a file whose name, 34282, corresponds to the table’s OID). By creating a subdirectory for each database, PostgreSQL ensures that you can safely store objects from multiple databases within the same tablespace without worrying about OID collisions.

When you create a cluster (which is done for you automatically when you install PostgreSQL), PostgreSQL silently creates two tablespaces for you: pg_default and pg_global. PostgreSQL creates objects in the pg_default tablespace when it can’t find a more appropriate tablespace. The pg_default tablespace is always located in the $PGDATA/base directory. The pg_global tablespace stores cluster-wide tables like pg_database, pg_group, and pg_tablespace—you can’t create objects in the pg_global tablespace.

The name of the pg_default tablespace can be a bit misleading. You may think that PostgreSQL always creates an object in pg_default if you omit the TABLESPACE tablespacename clause, but that’s not the case. Instead, PostgreSQL follows an inheritance hierarchy to find the appropriate tablespace. If you specify a TABLESPACE tablespacename clause when you execute a CREATE TABLE or CREATE INDEX command, the server creates the object in the given tablespacename. If you don’t specify a tablespace and you’re creating an index, the index is created in the tablespace of the parent table (that is, the table that you are indexing). If you don’t specify a tablespace and you’re creating a table, the table is created in the tablespace of the parent schema. If you are creating a schema and you don’t specify a tablespace, the schema is created in the tablespace of the parent database. If you are creating a database and you don’t specify a tablespace, the database is created in the tablespace of the template database (typically, template1). So, an index inherits its tablespace from the parent table, a table inherits its tablespace from the parent schema, a schema inherits its tablespace from the parent database, and a database inherits its database from the template database.

To view the databases defined in a cluster, use the \db (or \db+) command in psql:

movies=# \db+
                     List of tablespaces
     Name     |   Owner  |     Location     | Access privileges
--------------+----------+------------------+------------------
 mytablespace | postgres | /fastDrive/pg    |
 pg_default   | postgres |                  |
 pg_global    | postgres |                  | {pg=C/pg}
(4 rows)

To see a list of objects defined with a given tablespace, use the following query:

SELECT relname FROM pg_class 
    WHERE reltablespace = 
    (
      SELECT oid FROM pg_tablespace WHERE spcname = ‘tablespacename’ 
    );

Don’t confuse schemas and tablespaces—they both provide organization for the tables and indexes in your cluster, but they are definitely not the same thing. A tablespace affects the physical organization of data within a cluster (that is, it a tablespace defines where your data is stored). A schema affects the logical organization of data within a database—a schema affects name resolution; a tablespace does not. A schema acts as a part of a name; once you’ve created an object, you can ignore its physical location (its tablespace).

Creating New Databases

Now let’s see how to create a new database and how to remove an existing one.

The syntax for the CREATE DATABASE command is

CREATE DATABASE database-name
    [ WITH [ OWNER    [=] {username|DEFAULT} ]
           [ TEMPLATE [=] {template-name|DEFAULT} ]
           [ ENCODING [=] {encoding|DEFAULT} ]
           [ TABLESPACE [=] tablespace ]]

As I mentioned earlier, the database-name must follow the PostgreSQL naming rules described earlier and must be unique within the cluster.

If you don’t include the OWNER=username clause or you specify OWNER=DEFAULT, you become the owner of the database. If you are a PostgreSQL superuser, you can create a database that will be owned by another user using the OWNER=username clause. If you are not a PostgreSQL superuser, you can still create a database if you have the CREATEDB privilege, but you cannot assign ownership to another user. Chapter 21, "PostgreSQL Administration," describes the process of defining user privileges.

The TEMPLATE=template-name clause is used to specify a template database. A template defines a starting point for a database. If you don’t include a TEMPLATE=template-name or you specify TEMPLATE=DEFAULT, the database named template1 is copied to the new database. All tables, views, data types, functions, and operators defined in the template database are duplicated into the new database. If you add objects (usually functions, operators, and data types) to the template1 database, those objects will be propagated to any new databases that you create based on template1. You can also trim down a template database if you want to reduce the size of new databases. For example, you might decide to remove the geometric data types (and the functions and operators that support that type) if you know that you won’t need them. Or, if you have a set of functions that are required by your application, you can define the functions in the template1 database and all new databases will automatically include those functions. If you want to create an as-distributed database, you can use template0 as your template database. The template0 database is the starting point for template1 and contains only the standard objects included in a PostgreSQL distribution. You should not make changes to the template0 database, but you can use the template1 database to provide a site-specific set of default objects.

You can use the ENCODING=character-set clause to choose an encoding for the string values in the new database. An encoding determines how the bytes that make up a string are interpreted as characters. For example, specifying ENCODING=SQL_ASCII tells PostgreSQL that characters are stored in ASCII format, whereas ENCODING=ISO-8859-8 requests ECMA-121 Latin/Hebrew encoding. When you create a database, all characters stored in that database are encoded in a single format. When a client retrieves data, the client/server protocol automatically converts between the database encoding and the encoding being used by the client. Chapter 22, "Internationalization and Localization," discusses encoding schemes in more detail.

The TABLESPACE=tablespace-name clause tells PostgreSQL that you want to create the database in an alternate location (that is, the database should not be created in the usual $PGDATA/base directory). You must create a tablespace before you can use it. If you don’t include a TABLESPACE clause in the CREATE DATABASE command, the new database is created in the same tablespace as the template database.

If you’re using an older version of PostgreSQL (older than 8.0), you can’t use tablespaces to create a database in a non-standard location. Instead, you must use a feature known as a location. In versions of PostgreSQL older than 8.0, the last option for the CREATE DATABASE command is the LOCATION=path clause. In most cases, you will never have to use the LOCATION option, which is good because it’s a little strange.

If you do have need to use an alternate location, you will probably want to specify the location by using an environment variable. The environment variable must be known to the postmaster processor at the time the postmaster is started and it should contain an absolute pathname.

The LOCATION=path clause can be confusing. The path might be specified in three forms:

  • The path contains a /, but does not begin with a /—this specifies a relative path

  • The path begins with a /—this specifies an absolute path

  • The path does not include a /

Relative locations are not allowed by PostgreSQL, so the first form is invalid.

Absolute paths are allowed only if you defined the C/C++ preprocessor symbol "ALLOW_ABSOLUTE_DBPATHS" at the time you compiled your copy of PostgreSQL. If you are using a prebuilt version of PostgreSQL, the chances are pretty high that this symbol was not defined and therefore absolute paths are not allowed.

So, the only form that you can rely on in a standard distribution is the last—a path that does not include any "/" characters. At first glance, this may look like a relative path that is only one level deep, but that’s not how PostgreSQL sees it. In the third form, the path must be the name of an environment variable. As I mentioned earlier, the environment variable must be known to the postmaster processor at the time the postmaster is started, and it should contain an absolute pathname. Let’s look at an example:

$ export PG_ALTERNATE=/bigdrive/pgdata
$ initlocation PG_ALTERNATE
$ pg_ctl restart -l /tmp/pg.log -D $PGDATA
...
$ psql -q -d movies
movies=# CREATE DATABASE bigdb WITH LOCATION=PG_ALTERNATE;
...

First, I’ve defined (and exported) an environment variable named PG_ALTERNATE. I’ve defined PG_ALTERNATE to have a value of /bigdrive/pgdata—that’s where I want my new database to reside. After the environment variable has been defined, I need to initialize the directory structure—the initlocation script will take care of that for me. Now I have to restart the postmaster so that it can see the PG_ALTERNATE variable. Finally, I can start psql (or some other client) and execute the CREATE DATABASE command specifying the PG_ALTERNATE environment variable.

This all sounds a bit convoluted, and it is. The PostgreSQL developers consider it a security risk to allow users to create databases in arbitrary locations. Because the postmaster must be started by a PostgreSQL administrator, only an administrator can choose where databases can be created. So, to summarize the process:

  1. Create a new environment variable and set it to the path where you want new databases to reside.

  2. Initialize the new directory using the initlocation application.

  3. Stop and restart the postmaster.

  4. Now, you can use the environment variable with the LOCATION=path clause.

createdb

The CREATE DATABASE command creates a new database from within a PostgreSQL client application (such as psql). You can also create a new database from the operating system command line. The createdb command is a shell script that invokes psql for you and executes the CREATE DATABASE command for you. For more information about createdb, see the PostgreSQL Reference Manual or invoke createdb with the --help flag:

$ createdb --help
createdb creates a PostgreSQL database.
 
Usage:
  createdb [OPTION]... [DBNAME] [DESCRIPTION]
 
Options:
  -D, --tablespace=TABLESPACE  default tablespace for the database
  -E, --encoding=ENCODING      encoding for the database
  -O, --owner=OWNER            database user to own the new database
  -T, --template=TEMPLATE      template database to copy
  -e, --echo                   show the commands being sent to the server
  -q, --quiet                  don’t write any messages
  --help                       show this help, then exit
  --version                    output version information, then exit
 
Connection options:
  -h, --host=HOSTNAME          database server host or socket directory
  -p, --port=PORT              database server port
  -U, --username=USERNAME      user name to connect as
  -W, --password               prompt for password
 
By default, a database with the same name as the current user is created.
 
Report bugs to <pgsql-bugs@postgresql.org>.

Dropping a Database

Getting rid of an old database is easy. The DROP DATABASE command will delete all of the data in a database and remove the database from the cluster.

For example:

movies=# CREATE DATABASE redshirt;
CREATE DATABASE
movies=# DROP DATABASE redshirt;
DROP DATABASE

There are no options to the DROP DATABASE command; you simply include the name of the database that you want to remove. There are a few restrictions. First, you must own the database that you are trying to drop, or you must be a PostgreSQL superuser. Next, you cannot drop a database from within a transaction block—you cannot roll back a DROP DATABASE command. Finally, the database must not be in use, even by you. This means that before you can drop a database, you must connect to a different database (template1 is a good candidate). An alternative to the DROP DATABASE command is the dropdb shell script. dropdb is simply a wrapper around the DROP DATABASE command; see the PostgreSQL Reference Manual for more information about dropdb.

Viewing Databases

Using psql, there are two ways to view the list of databases. First, you can ask psql to simply display the list of databases and then exit. The -l option does this for you:

$ psql -l
     List of databases
   Name    |     Owner   | Encoding
-----------+-------------+----------
 template0 | postgres    | UNICODE
 template1 | postgres    | UNICODE
 movies    | bruce       | UNICODE
(3 rows)
$ 

From within psql, you can use the \l or \l+ meta-commands to display the databases within a cluster:

movies=# \l+
                   List of databases
   Name    |     Owner     | Encoding |       Description
-----------+---------------+----------+--------------------------
 template0 | postgres      | UNICODE  | 
 template1 | postgres      | UNICODE  | Default template database
 movies    | bruce         | UNICODE  | Virtual Video database
 (3 rows) 

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020