SQL and Table Constraints CMSC 461 Michael Wilson A few more basic commands All we’ve gone over so far, there’s two more commands I’d like to elaborate on Delete statement To get rid of existing rows in a table, use a delete statement DELETE FROM <table> WHERE <where-clause> Delete statement DELETE FROM AddressBook Where phoneType = ‘Cell’; Alter table Say you’ve discovered an issue in the schema you’ve provided to your database How do you correct that? Altering the table There are several variants on this Alter table Basic syntax: ALTER TABLE <table> <action> <action> can be: RENAME <column> to <new_column> RENAME to <new_table_name> ADD <column> <data_type> DROP <column> <data_type> ALTER <column> TYPE <data_type> Alter table Alter table can do much more than this These are kind of the more frequently applicable actions Going to leave the example part of this as an exercise for you It’s infrequently used and there are a lot of nuances to it that make it difficult to show a concrete example for Table constraints When designing your tables, you should often think about exactly how the data should fall together Putting together a database schema should not be a quick step SQL and DBMSes have built in methods for enforcing interrelated tables Keys! Remember our talk of keys from before? Extremely important when designing tables In general, most tables will have primary keys If you’re designing a table that doesn’t have one, you should question whether or not the table is designed properly Primary key constraints Your table creation scripts should always contain a primary key constraint This requires a slight modification to our create table statement Let’s look at our AddressBook table Primary key constraints CREATE TABLE AddressBook (address varchar(256), daysSinceContact integer, contactPhoneNumber varchar(64), numberType varchar(16), contactName varchar(256)); Primary key constraints Let’s add an identifier to this that will be our primary key Primary key constraints CREATE TABLE AddressBook (id integer PRIMARY KEY, address varchar(256), daysSinceContact integer, contactPhoneNumber varchar(64), numberType varchar(16), contactName varchar(256)); Primary key constraints id address lastContacted contactPhoneNum ber numberType contactName 1 111 Great Street 1 day ago 555 5555 Cell Phil 2 123 Not So Great Street Last month 555 6666 Landline Henry 3 8 Get Out of Here Way Last week 555 7777 Work Bob 4 7 RUN! Drive 2 years ago 555 8888 Cell Octavio Primary key constraints Primary If you try to insert an entry with a duplicate primary key, it will give you an error This is good – it enforces your DB schema for you Also, keys must be unique primary keys must be present Cannot be NULL, which we’ll get into later Primary key note The “id” method is pretty frequently used in DB design Easy way to have a key that you can reference by a single number Compound keys Compound keys are keys that consist of multiple columns Sometimes it requires several attributes to identify an item Compound keys dogName dogDOB favoriteToy Fido 2/20/2004 Chew toy Benjamin 6/01/2007 Ball Cujo 5/07/2008 Squeaky toy Compound keys CREATE TABLE FavoriteDogToys (dogName varchar(128), dogDOB date, favoriteToy varchar(256), PRIMARY KEY (dogName, dogDOB)); Foreign keys When you have interrelated tables, often times you’ll have a table that depends on the primary key of another table Very akin to the weak entities we saw in ER Diagramming Let’s take our previous AddressBook example and imagine a new table, Calls Foreign keys addressBookId callTime callLength 1 2/4/13 0:20:00 1 5/2/12 1:23:00 4 12/12/13 0:05:00 3 07/7/12 0:02:00 4 07/8/12 0:59:00 Foreign keys CREATE TABLE Calls ( addressBookId REFERENCES AddressBook, callTime timestamp, callLength interval ); What is the primary key in this table? Foreign keys CREATE TABLE Calls ( addressBookId REFERENCES AddressBook, callTime timestamp, callLength interval, PRIMARY KEY(addressBookId, callTime) ); Foreign keys We are unable to create any entries in the Calls table without there being a corresponding addressBookId in the AddressBook table PostgreSQL will give us an error if we attempt to do so What to do about foreign keys and deletes? Say we’ve got a situation where somebody wants to delete a row that we’re referencing What behavior do we want to exhibit? We can use ON DELETE to specify ON DELETE ON DELETE takes an action modifier NO ACTION (by default) RESTRICT If a referenced row is deleted, this row is removed as well SET NULL Prevents the deletion of a referenced row CASCADE If somebody attempts to delete something that we’re referencing, we do nothing and throw an error If a referenced row is deleted, the value in this row is set to NULL SET DEFAULT If a referenced row is deleted, the value in this row is set to the DEFAULT value for that row ON DELETE RESTRICT CREATE TABLE Calls ( addressBookId REFERENCES AddressBook ON DELETE RESTRICT, callTime timestamp, callLength interval ); If we attempt to delete an entry from AddressBook, what happens? ON DELETE CASCADE CREATE TABLE Calls ( addressBookId REFERENCES AddressBook ON DELETE CASCADE, callTime timestamp, callLength interval ); If we attempt to delete an entry from AddressBook, what happens? Why? Why not just handle all this stuff in code? Foreign keys, etc. don’t necessarily add functionality We could handle ON DELETES in code Referential integrity Referential integrity is essentially ensuring that relationships between tables remain consistent By declaring things as foreign keys, explicitly stating ON DELETEs, you ensure that it’s impossible to enter an inconsistent state Impossible to have a foreign key reference that no longer exists Your data is more predictable and reliable