MySQL 语法整理(4)

本篇博客讲解MySQL一些基本的插入删除更新语句,以及讲解内外左右连接。

delete:删除语句,会删除满足条件的记录或者表

/*delete:删除语句,where指定删除对象,会把所有满足的记录全部删除*/
DELETE FROM instructor
WHERE dept_name='Finance';

/*常见的两个表之间进行删除*/
DELETE FROM instructor
WHERE dept_name IN 
	(SELECT dept_name
	FROM department
	WHERE building ='Watson');

insert:插入操作。

/*插入操作,如果不表明插入元素,默认按表元素排列*/
INSERT INTO course
	VALUES('CS-437','Database Systems','Comp. Sci.',4);

/*将表A的结果插入到表B中,注意select的元素的类型和数目要一致,不然会报错*/
INSERT INTO instructor
	SELECT ID,NAME,dept_name,18000 -- 最后一个18000是工资
	FROM student
	WHERE dept_name='Physics' AND tot_cred > 10; -- 选取物理系学分大于10的学生

update:更新操作。

/*更新操作,即该表原有表中的记录*/
UPDATE instructor
	SET salary = salary * 1.05; -- 这里set是赋值符号,表示将原工资乘与1.05

inner join:内连接,outer join:外连接。先来说一下什么是内连接和外连接。两个表进行连接,会存在某个表的主键不在另外一个表出现的情况。比如学生表和选课表,会出现有的学生没有选到课的情况,如果我们将两个表连接起来,会出现有的学生无法与选课表中记录匹配,那对于那些没有选课的同学怎么办呢?对于内连接会直接无视,即不会放入结果表中;但如果是外连接,虽然有的学生没有修课程,但是我们也可以加入到结果表中,令他们修的课程信息值为null就可以了。总结一下,内连接的表不允许空值,而外连接则允许。

/*只用内连接inner join连接takes和student表*/
SELECT *
FROM student JOIN takes ON student.ID = takes.ID -- on后面加连接条件

MySQL 语法整理(4)_第1张图片

/*查询出所有学生的选课情况,包括没有选课的学生,使用左外连接
左外连接就是左边不允许空值,右表可以空值*/
SELECT *
FROM student LEFT OUTER JOIN takes ON student.ID=takes.ID;

MySQL 语法整理(4)_第2张图片

上面介绍了左外连接,右外连接同理。那么存在左右外连接吗?是真实存在的,只不过我们不叫左右外连接,而是叫全外连接。MySQL不支持全外连接的语句:full outer join,但是全外连接不就是左外连接合并右外连接嘛,只需一个union就可以搞定了。

SELECT *
FROM (SELECT id,NAME -- select的键必须与下面union的一致
	FROM student
	WHERE dept_name='Comp. Sci.')
	AS Cstudent1 (id , NAME)
	LEFT OUTER JOIN
	(SELECT id
	FROM takes
	WHERE semester='Spring' AND YEAR=2009)
	AS Cspring1 (id)
	ON Cstudent1.id= Cspring1.id
UNION 
SELECT *
FROM (SELECT id,NAME
	FROM student
	WHERE dept_name='Comp. Sci.')
	AS Cstudent2 (id , NAME)
	RIGHT OUTER JOIN
	(SELECT id
	FROM takes
	WHERE semester='Spring' AND YEAR=2009)
	AS Cspring2 (id)
	ON Cstudent2.id= Cspring2.id;

MySQL 语法整理(4)_第3张图片

讲完了内外连接,接下来我们说一下视图,存储过程,函数和触发器,内容会比较多,但是很实用!view:视图。视图作用相当于建立了一张固定的表,平时我们会在查询中建立一些临时表,一旦查询结束,临时表就会被系统删除。而视图建立后,我们随时都能使用。

/*通过view语句来建立一个视图faculty*/
CREATE VIEW faculty AS 
 SELECT ID,NAME,dept_name 
 FROM instructor;
 
 /*建立一个2009年秋季物理课的视图*/
CREATE VIEW physics_fall_2009 
AS
	SELECT course.course_id,sec_id,building,room_number 
	FROM course,section 
	WHERE course.course_id = section.course_id 
	AND course.dept_name='Physics' 
	AND section.semester='Fall' AND section.year='2009';
	
/*对physics_fall_2009视图进行查询,其实视图在查询时跟普通表没什么区别*/
SELECT course_id 
FROM physics_fall_2009 
WHERE building='Watson';

faculty视图如下所示:
MySQL 语法整理(4)_第4张图片

/*在视图的基础上又建立一个视图,禁止套娃!*/
CREATE VIEW physics_fall_2009_Waston 
AS 
	SELECT course_id,room_number 
	FROM physics_fall_2009 
	WHERE building='Watson';

上述我们仅仅是对新建立的视图进行查询,那视图可以支持插入和删除操作吗?其实是可以的,但是有局限,那就是该视图必须来自一个表,同时我们进行投影操作建立的视图,其余没有投影的键必须允许为空。

/*这个faculty视图由于只是进行了简单的进行了单表投影选择操作,因此可以支持插入*/
INSERT INTO faculty 
VALUES('30765','Green','Music');

/*这里演示了多表查询之下创立的视图不能插入,我估计原因是视图表面上用起来是一个表
其实系统并非实际建了这个视图表,而是通过索引来连接视图和原表,由于该视图涉及到两个表
因此无法插入*/
create view instructor_info 
as 
 select ID, name, building 
 from instructor, department 
 where instructor.dept_name = department.dept_name; 
-- 插入记录:
insert into instructor_info 
values ('69987','White','Taylor');

MySQL 语法整理(4)_第5张图片
报错信息如上。这也很好理解为什么报错,该视图是由多个表拼凑起来的,那如果要插入,怎么将插入的数据分配回原来的表呢?视图我们可以看出是一个索引表,而并不是一张真正的表。

视图中还会出现一种情况:比如某个视图展示历史系老师的信息,该视图从instructor表中建立的,当我往该视图中插入一条音乐老师的信息,虽然我们刷新视图发现没有记录,但是查看instructor发现该记录是真是插入的。

/*创建一个历史系老师*/
CREATE VIEW history_instructors 
AS
	SELECT * 
	FROM instructor 
	WHERE dept_name= 'History';

-- 插入一条不是History老师的记录,视图中是不会查询到的,但是instructor表会保存
INSERT INTO history_instructors 
 VALUES ('25566','Brown','Biology',100000)

-- 这里就可以插入并且能查询到了,因为视图会查询到dept_name= 'History'的老师
INSERT INTO history_instructors 
 VALUES ('68583','Califieri','History',100000);

-- 然后对视图进行查询
SELECT * FROM history_instructors; -- 会发现没有新插入的记录

with check option:在插入时检测是否符合视图的定义。

-- 使用with check option重建一下视图
CREATE VIEW history_instructors AS 
	SELECT * 
	FROM instructor 
	WHERE dept_name= 'History' 
	WITH CHECK OPTION;

-- 插入Biology老师的记录,此时会报错,原因是我们的系不是历史系
INSERT INTO history_instructors 
VALUES ('25566','Brown','Biology',100000)
/*定义视图时加上了 WITH CHECK OPTION 子句,对该视图进行插入、
修改和删除操作时,RDBMS 会自动加上 dept_name= ’History’的条件。*/

报错如图所示:
MySQL 语法整理(4)_第6张图片

先来介绍一下表的一些数据类型

MySQL支持所有标准SQL数值数据类型。

这些类型包括严格数值数据类型(INTEGER、SMALLINT、DECIMAL和NUMERIC),以及近似数值数据类型(FLOAT、REAL和DOUBLE PRECISION)。

关键字INT是INTEGER的同义词,关键字DEC是DECIMAL的同义词。

BIT数据类型保存位字段值,并且支持MyISAM、MEMORY、InnoDB和BDB表。

作为SQL标准的扩展,MySQL也支持整数类型TINYINT、MEDIUMINT和BIGINT。下面的表显示了需要的每个整数类型的存储和范围。
MySQL 语法整理(4)_第7张图片
日期和时间类型
表示时间值的日期和时间类型为DATETIME、DATE、TIMESTAMP、TIME和YEAR。

每个时间类型有一个有效值范围和一个"零"值,当指定不合法的MySQL不能表示的值时使用"零"值。

TIMESTAMP类型有专有的自动更新特性
MySQL 语法整理(4)_第8张图片
字符串类型
字符串类型指CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET。该节描述了这些类型如何工作以及如何在查询中使用这些类型。
MySQL 语法整理(4)_第9张图片

接下来介绍一下建表的一些操作,not null:非空约束,就是不允许为空值

/*非空约束*/
CREATE TABLE instructor 
(ID VARCHAR(5), NAME VARCHAR(20) NOT NULL, /*非空约束*/ 
dept_name VARCHAR(20), 
salary NUMERIC(8,2) CHECK (salary > 29000), 
PRIMARY KEY (ID), 
FOREIGN KEY (dept_name) REFERENCES department ON DELETE SET NULL 
);

unique:唯一,特别适合一些主键

/*unique使得name必须唯一*/
CREATE TABLE instructor 
(ID VARCHAR(5), 
NAME VARCHAR(20) UNIQUE, /*unique 约束*/ 
dept_name VARCHAR(20), 
salary NUMERIC(8,2) CHECK (salary > 29000), 
PRIMARY KEY (ID), FOREIGN KEY (dept_name) REFERENCES department ON DELETE SET NULL 
);

check:系统会检查并限定填入的数据,之前我们也是用check限制视图的插入。

/*使用check来限定填入的数据*/
CREATE TABLE section
(course_id VARCHAR(8)
, sec_id VARCHAR(8), 
semester VARCHAR(6) CHECK (semester IN ('Fall', 'Winter', 'Spring', 'Summer')), 
YEAR NUMERIC(4,0) CHECK (YEAR > 1701 AND YEAR < 2100), 
building VARCHAR(15), 
room_number VARCHAR(7), 
time_slot_id VARCHAR(4), 
PRIMARY KEY (course_id, sec_id, semester, YEAR) 
);

on delete set null:当某个表的记录被删除,该记录为外键的其他表记录设为空值。听着很拗口,举个例子大家就懂了。

-- 可自行在在 department 表中执行 delete 操作,违约后,course 表中相对应元组的
-- det_name 设为空值;
create table course 
(course_id varchar(8), 
title varchar(50), 
dept_name varchar(20), 
credits numeric(2,0) check (credits > 0), 
primary key (course_id), -- 设置主键
foreign key (dept_name) references department on delete set null 
);

on delete cascade:联级删除。

-- 级联删除 on delete cascade
create table course 
(course_id varchar(8), 
title varchar(50), 
dept_name varchar(20), 
credits numeric(2,0) check (credits > 0), 
primary key (course_id), 
foreign key (dept_name) references department on delete cascade
);
-- 可在 department 表中执行 delete 操作,违约后,course 表中相对应元组也被自动删除

create user:创建用户。

/*在本机上创建 s1 用户,但是由于SQLyog版本问题,会无法登录*/
CREATE USER 's1'@'localhost' IDENTIFIED BY 's1';
-- 更换了IDENTIFIED WITH mysql_native_password BY语句,这样就可以登录了
CREATE USER 's1'@'localhost' IDENTIFIED WITH mysql_native_password BY '123';
-- 刷新权限
FLUSH privilege;

grant:赋予权限。

/*将university的department表查询授权给s1用户,其他修改或者删除操作均没有授予*/
GRANT SELECT ON university.department TO 's1'@'localhost'; -- 后面的@localhost表示主机登录才有该权限
/*将university的department表的budget行的更新权限给s1用户	*/
GRANT UPDATE(budget) ON university.department TO 's1'@'localhost';
/*查看s1用户的权限*/
SHOW GRANTS FOR s1@localhost;

drop user:删除用户。

/*删除用户*/
DROP USER 's1'@'localhost';

set password for:给用户设置或修改密码。

/*修改用户密码*/
SET PASSWORD FOR '用户名'@'主机' = PASSWORD('新密码');

/*查询root用户的信息,用户的信息都在USER表中,要想访问得有select权限*/
SELECT HOST,USER 
FROM USER 
WHERE USER='root';

create role:创建角色。角色我认为相当于一个权限的模板,比如我创建一个角色,给角色赋予某些数据库中某些表的权限,只要我把用户加入到该角色中,就拥有了该用户的权限,有点类似Linux的组用户的权限。

/*-创建角色*/
CREATE role instructor;
/*为角色授权*/
GRANT SELECT ON university.takes TO instructor; 
/*将 s1 加入到 instructor 中,s1 就拥有了该角色的权限*/
GRANT instructor TO 's1'@'localhost';

你可能感兴趣的:(MySQL学习,mysql,数据库)