Finally,终于开始接触一点实际的东西了——数据定义
SQL语言介绍什么的就懒得说了,反正我只知道Oracle、MySQL什么的都支持,而且很好用。我主要使用的是MySQL,所以使用的SQL语句都只是适用于MySQL的,至于在Oracle等其他数据库上就不知道适不适用了。
具体参见MySQL关于Data Defination Statement的相关文档:https://dev.mysql.com/doc/refman/5.7/en/alter-table.html
SQL语言的动词以及三级模式
SQL的动词:
数据查询:SELECT
数据定义:CREATE、DROP、ALTER
数据操纵:INSERT、UPDATE、DELETE
数据控制:GRANT、REVOKE
三级模式:没错就是我之前的那篇《数据库系统概论学习笔记(一)》里的三级模式两级映射中的模式。
外模式 —— 视图
模式 —— 数据库
内模式 —— 存储文件
理解用例:学生-课程数据库
有三张基本表,分别是
学生表:Student(Sno,Sname,Ssex,Sage,Sdept)
课程表:Course(Cno,Cname,Cpno,Ccredit)
学生选课表:SC(Sno,Cno,Grade)
数据定义(Data Definition)
模式定义
CREATE SCHEMA <模式名> 或 CREATE DATABASE <数据库名>
在MySQL一般是用CREATE DATABASE <数据库名>来定义。因为在MySQL中Schema和Database是一个概念,这与其他的DBMS可能会有些区别。
CREATE SCHEMA is a synonym for CREATE DATABASE.
具体定义方式见官方介绍:https://dev.mysql.com/doc/refman/5.7/en/create-database.html
定义一个名为test的数据库,并用show databases;
进行查看:
同样我们可以试一下show schemas;
可见MySQL的官方解释并没有欺骗我们(呵呵……),在MySQL中Schema和Database确实是同样的概念。
删除模式
DROP SCHEMA <模式名> 或 DROP DATABASE <数据库名>
在MySQL的官方文档中并没有提到“CASCADE | RESTRICT”相关的概念,根据官方的说明(https://dev.mysql.com/doc/refman/5.7/en/drop-database.html)MySQL在执行删除模式时应该是默认的CASCADE模式。
下图所示是删除模式“test”,在“test”中还存在一张表“student”,结果是MySQL并没做出任何询问或警告,就这么欢快的连带着student这张表一起把模式给删除了!!!所以执行这个操作一定要谨慎!!!
基本表定义
依照前文“理解用例”的三个表分别建立基本表Student、Course、SC。
注:每一个基本表都属于一个模式,在MySQL中建立表之前必须先选择模式(数据库),语句为“use <模式名>”。
CREATE TABLE Student
(
Sno CHAR(9) PRIMARY KEY, /* 定义‘主键’的一种方法 */
Sname CHAR(20) UNIQUE, /* Sname 取唯一值 */
Ssex CHAR(2),
Sage SMALLINT,
Sdept CHAR(20)
);
CREATE TABLE Course
(
Cno CHAR(4),
Cname CHAR(40),
Cpno CHAR(4),
Ccredit SMALLINT,
PRIMARY KEY (Cno), /* 定义‘主键’的另一种方法 */
FOREIGN KEY (Cpno) REFERENCES Course(Cno) /* 参照完整性约束,参照表和被参照表可以是同一张表 */
);
CREATE TABLE SC
(
Sno CHAR(9),
Cno CHAR(4),
Grade SMALLINT,
PRIMARY KEY (Sno,Cno),
FOREIGN KEY (Sno) REFERENCES Student(Sno),
FOREIGN KEY (Cno) REFERENCES Course(Cno)
);
/* 插入记录(属于数据更新部分) */
INSERT INTO Student VALUES ('200215121','李勇','男',20,'CS');
INSERT INTO Student VALUES ('200215122','刘晨','女',19,'CS');
INSERT INTO Student VALUES ('200215123','王敏','女',18,'MA');
INSERT INTO Student VALUES ('200215125','张立','男',19,'IS');
/* 因为外键的约束,所以不能按顺序插入 */
INSERT INTO Course VALUES ('2','数学',null,2);
INSERT INTO Course VALUES ('6','数据处理',null,2);
INSERT INTO Course VALUES ('4','操作系统','6',3);
INSERT INTO Course VALUES ('7','PASCAL语言','6',4);
INSERT INTO Course VALUES ('5','数据结构','7',4);
INSERT INTO Course VALUES ('1','数据库','5',4);
INSERT INTO Course VALUES ('3','信息系统','1',4);
INSERT INTO SC(Sno,Cno,Grade) VALUES ('200215121','1',92);
INSERT INTO SC(Sno,Cno,Grade) VALUES ('200215121','2',85);
INSERT INTO SC(Sno,Cno,Grade) VALUES ('200215121','3',88);
INSERT INTO SC(Sno,Cno,Grade) VALUES ('200215122','2',90);
INSERT INTO SC(Sno,Cno,Grade) VALUES ('200215122','3',80);
MySQL常用数据类型
数字类型:INT、FLOAT、DOUBLE
字符串类型:CHAR、VARCHAR
日期和时间类型:DATE、DATETIME
具体请参考官方文档吧:https://dev.mysql.com/doc/refman/5.7/en/data-types.html
修改基本表
ALTER TABLE <表名> [alter_specification [, alter_specification] …]
具体能够修改的内容非常多,参见官方文档:https://dev.mysql.com/doc/refman/5.7/en/alter-table.html
我这里就记录几个常用的方法:
1、增加&删除列
在student表中增加一列“入学时间(Sentrance)”,数据类型为“DATE”,再删除该列。
/* 增加Sentrance列 */
ALTER TABLE student
ADD Sentrance DATE;
SELECT * FROM student;
/* 删除Sentrance列 */
ALTER TABLE student
DROP Sentrance;
SELECT * FROM student;
2、修改数据类型
MySQL提供了两种方法实现此功能,分别是“CHANGE”和“MODIFY”。
首先,我们用“CHANGE”将student表中Sage的数据类型由SMALLINT改为Integer,在这里我们使用desc student
来观察表的状态。
desc student;
ALTER TABLE student
CHANGE Sage Sage Integer;
desc student;
“CHANGE”的意义实际上可以理解为“重新定义列”,所以第一个“Sage”表示原列名,第二个“Sage为新列名”。
仅仅是修改一下属性,还要写两遍列名必然觉得太多余了,所以MySQL还提供了一个方法“MODIFY”。下面,我们用“MODIFY”将“Sage”的属性从新改回SMALLINT。
desc student;
ALTER TABLE student
MODIFY Sage SMALLINT;
desc student;
3、增加&删除约束条件
给课程名Cname增加“UNIQUE”约束条件:
desc Course;
ALTER TABLE Course
ADD UNIQUE(Cname);
desc Course;
删除“UNIQUE”约束条件:
ALTER TABLE Course
DROP KEY Cname;
desc Course;
注:还有一种常用的修改,即修改“Foreign Key”。实例放在后文“复制&删除基本表”中
复制&删除基本表
表的复制
为了测试删除功能,我首先需要复制一张SC表:
CREATE TABLE sub_SC LIKE SC; /* 按照SC的表结构建立新表sub_SC */
/* 将SC内所有记录插入新表 */
INSERT INTO sub_SC
SELECT * FROM SC;
这样虽然将“Primary Key”复制过来了,但是参照完整性相关的约束条件并没有成功复制。
增加“外键”约束条件
为了更好的测试,我们用“ALTER”自行加上。
ALTER TABLE sub_SC
ADD FOREIGN KEY (Sno) REFERENCES student(Sno);
ALTER TABLE sub_SC
ADD FOREIGN KEY (Cno) REFERENCES course(Cno);
有时我们为已经建立的表增加外键约束的时候,会遇到编号为1452的错(如下图),其原因是“表中插入外键的属性值,在其参照表的主键值中不存在”。
删除表
DROP TABLE <表名> [ RESTRICT | CASCADE ]
MySQL 5.7以前的版本可以支持“RESTRICT”和“CASCADE”这两个关键字的功能。
RESTRICT:有限制的删除。
①、欲删除的表不能被其他表的约束所引用。
②、不能有视图。
③、不能有触发器。
④、不能有存储过程或函数。
CASCADE:级联删除。就是把RESTRICT的四个限制条件所说的内容一并删除。
MySQL 5.7以后的版本虽然承认这两个关键字,但是 …… 没什么卵用:
In MySQL 5.7, they do nothing.
参见:https://dev.mysql.com/doc/refman/5.7/en/drop-table.html
前面我们已经完整的复制了一张SC表“sub_SC”,我们试着执行以下删除表的语句DROP TABLE sub_SC;
毫无意外,MySQL又欢快的删除了,什么提示都没有!!!
索引的建立
CREATE [UNIQUE | FULLTEXT | SPATIAL] INDEX <索引名>
ON <表名>(<列名>,…)
索引属于内模式,建立索引是加快查询速度的有效手段。
在学生学号(Sno)建立一个以Hash方式查找的索引“index_hash_sno”:
CREATE INDEX index_hash_sno
ON student(Sno) USING HASH;
MySQL不仅支持以HASH方式建立索引,还支持“BTREE”的方式,具体请参考官方文档:
https://dev.mysql.com/doc/refman/5.7/en/create-index.html
删除索引
DROP INDEX index_hash_sno ON student;