Integrity constraints and database design
Integrity constraints can be arbitrary predicates that ensure the consistency and the validity of the values in a database. They act as guards against any accidental damage that could happen to the database. During this lab, you will practice using a set of integrity constraints that have been studied during the lecture.
Exercises
- Given the University Database (
univdb-sqlite.db), identify the data type of each attribute (field) in the relationtakes. 
    ID  varchar(5),
    course_id varchar(8),
    sec_id    varchar(8),
    semester  varchar(6),
    year  numeric(4, 0),
    grade varchar(2)- identify the primary keys for each of the relations (student, instructor, department, takes and teaches).
 
| Relation | PRIMARY KEY | 
|---|---|
| student | ID | 
| instructor | ID | 
| department | dept_name | 
| takes | (ID, course_id, sec_id, semester, year) | 
| teaches | (ID, course_id, sec_id, semester, year) | 
| section | (course_id, sec_id, semester, year) | 
| course | course_id | 
| advisor | s_id | 
| prereq | (course_id, prereq_id) | 
| classroom | (building, room_no) | 
The ID in table takes refers to the student id and the id in the teaches refers to the instructor id.
- Identify the foreign keys in each of the relations in the previous question.
 
| Foreign Key | Referencing Relation | Referenced Relation | 
|---|---|---|
| s_id | advisor | student | 
| i_id | advisor | instructor | 
| ID | takes | student | 
| (course_id, sec_id, semester, year) | takes | section | 
| (course_id, sec_id, semester, year) | teaches | section | 
| (building, room_no) | section | classroom | 
| course_id | prereq | course | 
| prereq_id | prereq | course | 
| course_id | section | course | 
| dept_name | instructor | department | 
| dept_name | student | department | 
| dept_name | course | department | 
- Create a table 
country(ID, name, continent), where the values of continent is restricted to take a value of (Asia,Africa,Europe,North America,South AmericaandAustralia). 
  CREATE TABLE counttry (
    ID VARCHAR (3) PRIMARY KEY,
    name VARCHAR (8) NOT NULL,
    continent VARCHAR (20) 
    CHECK (continent IN ('Asia', 'Africa', 'Europe', 
        'North America', 'South America', 'Australia'))
    );- Add an attribute in each of the 
studentandinstructorrelations calledhome countrythat is a foreign key referencing thecountrytable. Check this Link for an example. 
We can use:
  ALTER TABLE STUDENT ADD COLUMN home_country_id 
  REFERENCES countrySimilarly,
  ALTER TABLE INSTRUCTOR ADD COLUMN home_country_id 
  REFERENCES countryHowever, older versions of SQLite do not allow adding foreign keys to existing tables. We can use a workaround as follows. We create a new table ‘student_new’ with additional attribute ‘home_country’
  CREATE TABLE student_new( 
    ID  varchar(5),
      name  varchar(20) NOT NULL,
      dept_name varchar(20),
      tot_cred  numeric(3, 0) CHECK("tot_cred" >= 0),
      home_country_id char(3),
      PRIMARY KEY(ID),
      FOREIGN KEY(dept_name) REFERENCES department on delete set null,
    FOREIGN KEY(home_country_id) REFERENCES country(ID) on delete set null
  );We add a new column into the student relation
    ALTER TABLE student ADD COLUMN home_country_id;Now, we copy the contents of the student relation into the student_new relation.
  INSERT INTO student_new SELECT * FROM student;Check if the contents were copied correctly using
    SELECT * FROM student_new;Delete the old relation of student
    DROP TABLE student;Rename the new relation from student_new to student
    ALTER TABLE student_new RENAME TO student;- Write an 
SQLquery to remove the record of the student withID= 12345. 
    DELETE FROM student 
    WHERE ID = '12345';- If you know that student with 
ID= 12345 is referenced in the advisor relation, how can we delete the record without receiving an error message? 
This will depend on the referntial integrity policy. If the policy is SET NULL, SET DEFAULT or CASCADE, we will not receive an error message. If the policy is No ACTION, we can turn the referential integrity off using
  PRAGMA foreign_keys = OFF;We can delete any records. The DBMS will not check for violations of the referential integrity.
- Now, try the code 
INSERT INTO advisor values(55555, 88888); 
Since we turned off the referential integrity, the record will be inserted successfully. However, we cannot do that when the referential integrity is on. We will receive the error message
  Execution finished with errors.
  Result: FOREIGN KEY constraint failed
- Check if the referential integrity is forced or not then switch it and try the previous three exercises again.
 
You can turn on/off the referential integrity in SQLite using
  PRAGMA foreign_keys = OFF (or 0); (ON or 1)- According to the available data, identify the carnality of the relationships between 
studentandinstructor. Is there a better way to represent such relationship (justify your answer). 
From the available data, we can see that a student can have only one advisor and the instructor can be an advisor for multiple students. The cardinality of the relationship is many-1 (many students - 1 instructor).
If a student is allowed to have only one advisor, then a better design would add the instructor id as a foreign key in the student table instead of creating a new relation advisor.
Useful queries
- Display the schema of a relation using:
 
PRAGMA table_info(tab_name);- Check the policy for referential integrity using:
 
PRAGMA foreign_key_list(tab_name);- Check if the referential integrity is forced or not using:
 
PRAGMA foreign_keys;- Force the referential integrity in SQLite using:
 
PRAGMA foreign_keys = 1;     # use 0 to force no referential integrity You can also export the database to a .sql file and check the complete code of the database.