The CREATE VIEW and CREATE PROCEDURE statements are DDL because they only allow you to manipulate the database itself. They have nothing to do with the data in databases. In this chapter, we’re going to give a brief overview of a few additional DDL statements, which can be utilized to create and modify tables and indexes. Each database has a different way of organizing its objects, and therefore has dif- ferent available DDL statements. For example, MySQL has 11 different CREATE statements for these types of objects: Databases, Events, Functions, Indexes, Logfile Groups, Procedures, Serve rs, Table s, TableSpac es, Trigge rs, and Views. Oracle has over 30 different CREATE commands for the object types in its data- base. Microsoft SQL Server has over 40 different CREATE commands for its object types. In truth, most modifications to database objects, such as views and tables, can be accomplished through the visual GUI (graphical user interface), which each software vendor provides to administer their software. It is often not necessary to learn any DDL at all, since it can usually be handled with the software GUI. However, it’s useful at least to be aware of the existence of a few key statements to manipulate data objects. We’ve already seen some statements that allow us to modify views and stored procedures. In this chapter, we’ll show you some of the possibilities for modifying tables and indexes via DDL. Table Attributes In Chapter 1, we briefly discussed a few attributes of database tables, such as primary keys, foreign keys, and datatypes. In Chapter 2, we extended that dis- cussion to talk about auto-increment columns. As mentioned, SQL DDL provides CREATE statements for many types of data- base objects. In Chapter 13, we talked about the CREATE PROCEDURE and CREATE VIEW statements that handle stored procedures and views. We’re now going to bring our attention back to tables. Tables are perhaps the primary and most essential object type in a database. Without tables, nothing else really matters . All the data in a database is physically stored in tables. Most other object types relate to tables in one way or another. Views provide a virtual view of tables. Stored procedures generally act upon data in tables. Functions allow for special rules for the manipulation of data in tables. Chapter 18 ■ Maintaining Tables186 We’ll focus here on how tables can be created initially. There are a large number of attributes that can be associated with table definitions. We’re going to give an overview of some of the more important attributes and discuss what they mean. The subject of table attributes is also related to the larger topic of database design, which will be addressed in the next chapter. For now, we want to focus on the mechanics of what can be done with the tables themselves. The specifics of how tables can be designed and altered varies widely among Microsoft SQL Server, MySQL, and Oracle. We’ll talk primarily about those attributes that are common to tables in all three databases. Table Columns Tables are defined as containing any number of columns. Each column has a number of attributes specific to that column. The first and most obvious attribute is the column name. Each column must be given a name unique to that table. A second attribute of columns is the datatype, a subject that was addressed in Chapter 1. We’ve already described some notable datatypes in three main cate- gories: numeric, character, and date/time. The datatype is a key determinant of what type of data each column can contain. A third attribute of columns is whether or not it can be defined as an auto- increment column. We briefly introduced this attribute type in Chapter 2 and talked about it further in the previous chapter about modifying data. Basically, an auto-increment column means that the column is automatically assigned a numeric value, in ascending sequence, as each row is added to the table. Auto- increment columns are often used with primary keys but can also be assigned to an ordinar y column. Note that the term auto-increment is specific to MySQL. Microsoft uses the term identity to refer to the same type of attribute. DATABASE DIFFERENCES: Oracle Oracle doesn’t have an auto-increment type of attribute. Instead, Oracle requires you to define a column as a sequence and then create a trigger to populate that column with sequential values. This procedure is beyond the scope of this book. A fourth column attribute is whether or not the column is allowed to contain NULL values. The default is to allow NULL values. If you don’t want to allow a Table Columns 187 column to contain NULLs, it is normally specified via a NOT NULL keyword applied to the column description. The final column attribute we’ll mention is whether the column is assigned a default value. A default value is one that is automatically assigned to the column if no value for that column is provided when a row is added. For example, if most of your customers are in the U.S., you may want to specify that a column con- taining a country code be given a default value of U.S. Primary Keys and Indexes Let’s turn to the topic of primary keys and explain how that attribute relates to table indexes. Indexes are a physical structure that can be added to any column in a database table. Indexes serve the purpose of speeding up data retrieval when that column is involved in a SQL statement. The actual data in the index is hidden, but basically the index involves a structure that maintains information on the sort order of the column, thus allowing for quicker retrieval when specific values are requested. One downside to indexing a column is that it requires more disk storage in your database. A second negative is that indexes generally slow down data updates involving that column. This happens because any time a row is inserted or mod- ified, the index must recalculate the proper sorted order for values in that column. Any column can be indexed, but only one column can be designated as a primary key. Specifying a column as a primary key means two things: The column will be indexed, and the column will be guaranteed to contain unique values. As discussed in Chapter 1, primary keys accomplish two main benefits for the database user: They enable you to uniquely identify a single row in a table, and they allow you to easily relate tables to one another. And now, you can add a third benefit: By being indexed, the primary key enables faster data retrieval of rows involving that column. The main reason for havi ng primary keys is to guarantee unique values for all rows in a table. There always has to be a way to identify single rows for updates or deletes, and the prim ary key ensures that can be done. A primary key can actually span more than one column and can consist of two or three columns. If the primary key contains more than one column, it simply means that all those columns together will contain a unique value. This type of Chapter 18 ■ Maintaining Tables188 primary key is normally referred to as a composite primary key. As an example of when a composite primary key might be utilized, let’s say that you have a Movies table. You’d like to have a key that uniquely defines each movie in the table. Rather than use a MovieID integer value as the key, you’d like to use the movie title as the key. The problem, however, is that movies are som etimes remade with the same title. To solve the problem, you can use two columns, the movie title and the year, to form a composite primary key to uniquely define each movie. Because primary keys must contain unique values, they are never allowed to contain NULL values. Some value for the column must always be specified. Finally, primary keys are often specified as auto-increment columns. By making a primary key auto-increment, database developers don’t need to worry about assigning a unique value for the column. The auto-increment feature takes care of that requirement. Foreign Keys SQL databases also designate specific columns as a foreign key. A foreign key is simply a reference from a column in one table to a column in a different table. When setting up a foreign key, you will be asked to specify both columns. The foreign key column in the table being configured is often referred to as being in the child table. The referenced column in the other table is referred to as being in the parent table. For example, let’s say you have a Customers table with a CustomerID column that is set up as a primary key. You also have an Orders table with an OrderID column set up as a primary key and a CustomerID column. You would like to set up the CustomerID column in the Orders table as a foreign key that references the CustomerID column in the Customer table. In this case, the Orders table is the child table and the Customers table is the parent table. When you set up foreign keys, you will be able to set some specific actions for updates and deletes involving rows in the parent table. The three most common actions are: ■ No Action ■ Cascade ■ Set Null Foreign Keys 189 Let’s continue with the example of the Customers and Orders tables. The most common action to specify is No Action. This is the default action if none is specified. If you set the CustomerID column in the Orders table to No Action for updates, that means that a check is made whenever an update is attempted in the parent table on the CustomerID column. If it tries to do an update on the CustomerID, which would result in any row in the child pointing to a value that no longer exists, it will prevent that action from occurring. The same would be true if No Action is specified for deletes. This ensures that, when using the CustomerID column in both tables, all rows in the Orders properly point to an existing row in the Customers table. The second alternative for a specified action for foreign keys is Cascade. This means that when a value in the parent table is updated, and if that value affects rows in the child table, then it will automatically update all rows in the child table to reflect the new value in the parent table. Simila rly, if a row in the parent table is deleted, and if that affects rows in the child table, it will automatically delete affected rows in the child table. A third alternative for a specified action for foreign keys is Set Null, which means that when a value in the parent is updated or deleted, and if that values affects rows in the child table, it will automatically update all affected rows in the child table to contain a NULL value in the foreign key. Creating Tables The CREATE TABLE statement can be used to create new tables in a database. The syntax and available features vary among databases. We’re going to focus on a simple example that creates a table with these attributes: ■ The table name is MyTable. ■ The first column in the table is named ColumnOne and defined as a primary key. This column will be defined as an INT (integer) datatype and also as an auto-increment column. ■ The second column in the table is named ColumnTwo and defined as an INT datatype. This column will not allow NULL values. This colu mn will also be defined as a foreign key, with No Action specified for both deletes and updates, related to a column named FirstColumn in another table called RelatedTable. Chapter 18 ■ Maintaining Tables190 . both columns. The foreign key column in the table being configured is often referred to as being in the child table. The referenced column in the other table is referred to as being in the parent. subject of table attributes is also related to the larger topic of database design, which will be addressed in the next chapter. For now, we want to focus on the mechanics of what can be done with the. value as the key, you’d like to use the movie title as the key. The problem, however, is that movies are som etimes remade with the same title. To solve the problem, you can use two columns, the movie