视图
视图是一种虚拟的表,便于更好地在多个表中检索数据,视图也可以作写操作,不过最好作为只读。在需要多个表联接的时候可以使用视图。
create view v_student_with_classname as select student.name name, class.name class_name from student left join class where student.class_id = class.id; select * from v_student_with_classname;
约束
primiry key
任意两行绝对没有相同的主键,且任一行不会有两个主键且主键绝不为空。使用主键可以加快索引。
alter table student add constraint primary key (id);
foreign key
外键可以保证数据的完整性。有以下两种情况。
- 插入张三丰5班到student表中会失败,因为5班在class表中不存在。
- class表删除3班会失败,因为陆小凤和楚留香还在3班。
alter table student add constraint foreign key (class_id) references class (id);
unique key
唯一索引保证该列值是唯一的,但可以允许有null。
alter table student add constraint unique key (name);
check
检查约束可以使列满足特定的条件,如果学生表中所有的人的年龄都应该大于0。
不过很可惜mysql不支持,可以使用触发器代替
alter table student add constraint check (age > 0);
index
索引可以更快地检索数据,但是降低了更新操作的性能。
create index index_on_student_name on student (name); alter table student add constraint key(name );
触发器
可以在插入,更新,删除行的时候触发事件。
# 创建触发器 # 比如mysql中没有check约束,可以使用创建触发器,当插入数据小于0时,置为0。 create trigger reset_age before insert on student for each row begin if NEW.age < 0 then set NEW.age = 0; end if; end; # 打印触发器列表 show triggers;
存储过程
存储过程可以视为一个函数,根据输入执行一系列的 sql 语句。存储过程也可以看做对一系列数据库操作的封装,一定程度上可以提高数据库的安全性。
# 创建存储过程 create procedure create_student(name varchar(50)) begin insert into students(name) values (name); end; # 调用存储过程 call create_student('shanyue');
SQL 练习
1. 根据班级学生的分数进行排名,如果分数相等则为同一名次
select id, name, score, ( select count(distinct score) from student s2 where s2.score >= s1.score ) as rank from student s1 order by s1.score desc;
在where以及排序中经常用到的字段需要添加Btree索引,因此 score 上可以添加索引。
Result: