数据库实验回顾sql
实体完整性数据库
实体完整性即主码的属性不能为空。而主码就可保证元组是不重复的,即主码值是不能重复的。设计
参照完整性code
参照完整性保证外码的值要么是被参照关系中的主码值,要么取空值。it
用户自定义完整性table
能够按系统的需求设计各类自定义的完整性检查。class
主键(promary key)用于惟一的标识表中的某一条记录,在两个表的关系中,主键用来在一个表中引用来自另外一个表中的特定记录。一个表的主键能够由多个关键字共同组成,而且主键的列不能包含空值。主键的值能惟一标识表中的每一行,这就比如全部人都有身份证,每一个人的身份证号是不一样的,能惟一标识每个人。原理
添加主键date
ALTER TABLE 表名 ADD PRIMARY KEY(列名);
设置主键select
ALTER TABLE orders ADD PRIMARY KEY(列名);
在建立表的时候,设置主键
-- 单个字段的主键 CREATE TABLE 表名( 字段名 数据类型 PRIMARY KEY ); -- 多个字段组合的主键 CREATE TABLE 表名( 字段名1 数据类型, 字段名2 数据类型, ..... PRIMARY KEY(字段名1, 字段名2, 字段名n) );
惟一约束用于保证数据表中字段值的惟一性,在 MySQL 中使用 UNIQUE 关键字添加惟一约束。在建立表时为某个字段添加惟一约束的具体语法格式以下:
CREATE TABLE 表名( 字段名 数据类型 UNIQUE, .... );
注意:被定义成惟一约束的字段,字段值不能相同。可是能够为 NULL。
惟一约束也能够添加到已经建立完成的表中,语法格式以下:
ALTER TABLE 表名 ADD UNIQUE(列名);
数据表中的 id 字段通常从1开始插入,不断增长,每次插入新数据时,都要添加一个 id 字段的值,当数据内容庞大时,容易出错。为了解决这个问题,能够将 id 字段的值设置为自动增长。在 MySQL 中使用 AUTO_INCREMENT 关键字设置表字段值自动增长。在建立表时将某个字段的值设置为自动增加,语法格式以下:
CREATE TABLE 表名( 字段名 数据类型 AUTO_INCREMENT, .... );
此外,也能够为已经建立完成的表字段设置自动增加列,语法格式以下:
ALTER TABLE 表名 MODIFY 字段名 数据类型 PRIMARY KEY AUTO_INCREMENTL;
MySQL参照完整性通常是经过MySQL外键(foreign key)实现的
删除参照约束
ALTER 表 DROP FOREIGN KEY fg_fk;
给现有表增长参照约束
ALTER TABLE`score`ADD CONSTRAINT`score_fk2`FOREIGN KEY (`sid`) REFERENCES`student`(`sid`);
数据库系统的外键值更新模式通常有3种:
默认的外键管理是Restict,即限制方式。前面实验咱们已经见识了这种方式的做用。
CASCADE,即级联方式,能够理解为株连九族,即主键改变后,引用它的外键值自动改变成新主键值来保证参照完整性。
SET NULL,置空,即主键值改变后,引用它的外键值自动改成NULL来保证参照完整性。
eg
alter table 表名 add constraint fk_js foreign key(任课教师编号) references teacher (工号) on update cascade;
像MS SQL Server等数据库管理系统有CHECK约束能够很方便地实现用户自定义完整性约束。但MySQL没有提供真正的CHECK约束。但用户自定义约束的原理都差很少,经过触发器就能够实现。
例如:学生年龄不能取负值的约束
-- insert 触发器 年龄不能为负 delimiter ; delimiter $$ create trigger st_ins_chk_age before insert on student for each row begin if new.年龄 is not NULL and new.年龄 < 0 then signal sqlstate 'HY000' set message_text = "年龄不能为负"; end if; end$$ -- update 触发器 年龄不能为负 delimiter ; delimiter $$ create trigger st_up_chk_age before update on student for each row begin if new.年龄 is not NULL and new.年龄 < 0 then signal sqlstate 'HY000' set message_text = "年龄不能为负"; end if; end$$ delimiter ;
不用外键,而利用触发器实现socre的课号要级联参照course中的课号?
score 表
-- 触发器 实现 score 外键 学号 参照 student 学号 -- score delimiter ; delimiter $$ create trigger sc_fk_ins_xh before insert on score for each row begin if (select count(*) from student where 学号=new.学号)=0 and new.学号 is not NULL then signal sqlstate 'HY000' set message_text = "Cannot add or update a child row: a foreign key constraint ..."; end if; end$$ create trigger sc_fk_up_xh before update on score for each row begin if (select count(*) from student where 学号=new.学号)=0 and new.学号 is not NULL then signal sqlstate 'HY000' set message_text = "Cannot add or update a child row: a foreign key constraint ..."; end if; end$$ delimiter ;
注意:score 中是 new ,student 中是 old
student 表
-- 触发器 实现 score 外键 学号 参照 student 学号 -- student delimiter ; delimiter $$ create trigger st_del_xh before delete on student for each row begin if (select count(*) from score where 学号=old.学号)>0 then signal sqlstate 'HY000' set message_text = "Cannot delete or update a child row: a foreign key constraint ..."; end if; end$$ create trigger st_up_xh before update on student for each row begin if (select count(*) from score where 学号=old.学号)>0 then signal sqlstate 'HY000' set message_text = "Cannot delete or update a child row: a foreign key constraint ..."; end if; end$$ delimiter ;