MySQL数据库基础

本文详细介绍了MySQL数据库的基础知识,包括数据库服务器、数据库、数据表等五个基本概念,以及数据库分类,重点讲解了MySQL的特点和配置。进一步,文章探讨了SQL的四种分类,如DDL、DML、DQL和TPL,并提供了代码示例。还涵盖了数据类型、约束和索引等进阶主题,最后通过代码练习巩固了所学内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

My SQL数据库

一、数据库的基础知识

1.数据库

数据库(database)就是一个存储和管理数据的仓库。为了方便数据的存储和管理,它将数据按照特定的规律存储在磁盘上。通过数据库管理系统,可以有效地组织和管理存储在数据库中的数据。是一个长期存储在计算机内的、有 组织的、有共享的、统一管理的数据集合。

2.数据库的五个基本概念

数据库服务器、数据库、数据表、数据字段、数据行

1.数据库服务器

​ 是指用来运行数据库服务的一台电脑。小型项目通常为一台,中大型项目通常是多台数据库服务器共同来存储或计算。由于数据安全非常重要,所以我们需要对数据库服务器里边的数据进行备份管理

2.数据库

​ 一个数据库服务器里面可以有多个数据库。主要用来分类使用。我们可以建立学员管理系统数据库、电子商城数据库、CRM数据库、ERP数据库等等,主要用来将各个不同用途的数据,按照业务进行划分。

3.数据表

​ 例如,在学员管理系统中。根据业务的不同又分为了不同的数据表。专门用来存放不同人员的数据。例如:学员数据表(学号、用户名、密码);老师数据表(用户名、密码、工作经验)

4.数据字段(数据列)

​ 就是我们日常所见表格里面的列。在表格中,我们会将一张用户表分成多个列。如:用户编号、用户名、性别、年龄等是字段,在真正的数据库中数据字段需换成英文,需要写成:id,username,sex,age等。

5.数据行

​ 真正的数据存在在每一个表的行里面。字段(列)划分出来了一个表应该按照什么样的格式存数据。而行,是真正的数据。每一行需要遵循数据字段(列)的规范和要求进行存入数据。

3.数据库的分类

关系型数据库

​ 就是使用二维表格(Table)的方式来存放数据的数据库,多表间建 立关联关系,通过分类、合并、连接、选取等运算实现访问。

​ 数据库中的数据都是项目中的数据,所以数据库中的数据表示的就是Java对象

​ 那么关系型数据库这个二维表格,每一个表格就相当于一个Java类,表头就表示Java类的属性,从第二行开始,每一个行表示一个Java对象

​ 常见的关系型数据库:MySQLOracle、Microsoft SQL Server、IBM Db 2等,最常用的是MySQL。

非关系型数据库

​ 常见的非关系型数据库:RedisMongoDB 、ElastecSearch等。多数使用哈希表,表中以键值(keyvalue)的方式实现特定的键和一个指针指向的特定数据。

网状结构数据库

​ 美国通用电气公司IDS(Integrated Data Store),以节点形式存储和访问。

层次结构数据库

​ IBM公司IMS(Information Management System)定向有序的树状结构 实现存储和访问。

4.数据库管理系统

1.概念

​ 数据库管理系统(DataBase Management System,DBMS):指一种操作和管理数据库的大型软件,用于建立、使用和维护数据库,对数据库进行统一管理和控制,以保证数据库的安全性和完整性。用户通过数据库管理系统访问数据库中的数据。

2.常见数据库管理系统

Oracle:被认为是业界目前比较成功的关系型数据库管理系统。Oracle数据库可以运行在 UNIX、Windows等主流操作系统平台,完全支持所有的工业标准,并获得最高级别的ISO标 准安全性认证。

DB2:IBM公司的产品,DB2数据库系统采用多进程多线索体系结构,其功能足以满足大中 公司的需要,并可灵活地服务于中小型电子商务解决方案。

SQL Server:Microsoft 公司推出的关系型数据库管理系统。具有使用方便可伸缩性好与相 关软件集成程度高等优点。

SQLLite:应用在手机端的数据库。

5.MySQL

​ MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。 MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面MySQL是最好的 RDBMS(Relational Database Management System,关系数据库管理系统) 应用软件之一。

​ My SQL是一款完全免费的产品,用户可以直接从网上下载使用,而不必支付任何费用。此外,My SQL数据库的跨平台性也是其一个很大的优势之一;My SQL是一个真正的多用户、多线程SQL数据库服务器。它是以客户机/服务器结构实现的,由一个服务器守护程序以及很多不同的客户程序和库组成。

MySQL 5.5融合了MySQL数据库和InnoDB存储引擎的优点,能够提供高性能的数据管理解决方案,包括:

​ InnoDB作为默认的数据库存储引擎;

​ 改善性能和可扩展性,全面利用各平台现代、多核构架的计算能力;

​ 提高实用性;

​ 提高易管理性和效率;

​ 提高可用性。

官方下载地址:

http://dev.mysql.com/downloads/mysql/

安装MySQL注意事项:

​ 双击即可,大部分都是一路next

​ 关键节点注意事项:

  1. 选中“Typical”,典型安装模式

  2. 选中“Detailed Configuration”(详细配置)单选按钮

  3. 选中“Developer Machine”(开发者机器)单选按钮

  4. 选中“Multifunctional Database”(多功能数据库)单选按钮

  5. 服务端口3306,不建议更改

  6. 字符集注意要选“Manual Selected Default Character Set/Collation”单选按钮,设置字符集编码为utf8

  7. 设置密码尽量简单,注意不要忘了

    用户名:root 密码:root

卸载MySQL

​ 控制台卸载。

​ 找到mysql的安装目录进行删除。

​ programdata 删除mysql

​ 注意:如果卸载后,如有未删除的MySQL服务,可采用手动删除。

​ 以管理员身份打开命令行,输入 sc delete MySQL5.7 + 回车。

配置环境变量
Windows

​ 创建MYSQL_HOME:C:\Program Files\MySQL\MySQL Server 5.7

​ 追加PATH:%MYSQL_HOME%\bin;

MacOS / Linux

​ 终端中输入cd ~ 进入目录,并检查.bash_profile是否存在,有则追加,无则 创建

​ 创建文件 touch .bash_profile

​ 打开文件 open .bash_profile

​ 输入export PATH=${PATH}:/usr/local/mysql/bin 保存并退出终端

MySQL目录结构

核心文件介绍

文件名称内容
bin命令文件
lib库文件
include头文件
Share字符集、语言等信息
MySQL配置文件

在MySQL安装目录中找到my.ini文件,并打开my.ini文件查看几个常用配置参数

参数描述
default-character-set客户端默认字符集
character-set-server服务器端默认字符集
port客户端和服务器端的端口号
default-storage-engineMySQL默认存储引擎 INNODB
启动MySQL

​ 在命令提示符(cmd)页面我们cd到MySQL的bin目录下,就可通过命令启动或停止MySQL。命令如下:

​ 启动mysql: net start mysql

​ 关闭mysql: net stop mysql

​ 登录mysql: mysql -u root -p (-u : username,-p : password)

6.数据库客户端工具

1.Navicate

​ Navicat是一套快速、可靠并价格相宜的数据库管理工具,专为简化数据库的管理及降低系统管理 成本而设。它的设计符合数据库管理员、开发人员及中小企业的需要。Navicat 是以直觉化的图形 用户界面而建的,让你可以以安全并且简单的方式创建、组织、访问并共用信息。

2.SQLyog(小海豚)

​ MySQL可能是世界上最流行的开源数据库引擎,但是使用基于文本的工具和配置文件可能很难进 行管理。SQLyog提供了完整的图形界面,即使初学者也可以轻松使用MySQL的强大功能。其拥有 广泛的预定义工具和查询、友好的视觉界面、类似 Excel 的查询结果编辑界面等优点。

二、SQL分类

数据定义语言(DDL ,Data Definition Language)语句:数据定义语句,用于定义不同的数据对象、数据库、表、列、索引等。常用的语句关键字包括create、drop、alter等。

数据操作语言(DML , Data Manipulation Language)语句:数据操纵语句,用于添加、删除、更新和查询数据库记录,并检查数据的完整性。常用的语句关键字主要包括insert、delete、update和select等。(DML:添加,修改,删除,DQL:查询)。

数据控制语言(DCL, Data Control Language)语句:数据控制语句,用于控制不同数据段直接的许可和访问级别的语句。这些语句定义了数据库、表、字段、用户的访问权限和安全级别。主要的语句关键字包括grant、revoke等。

1.数据定义语言 - DDL

对于库的操作
对于库的操作代码
遍历数据库SHOW DATABASES
使用数据库USER 数据库名
创建数据库CREATE DATABASE 数据库名
删除数据库DROP DATABASE 数据库名
对于表的操作
对于表的操作代码
遍历表SHOW TABLES;
创建表CREATE TABLE 表名(字段 类型,…字段 类型);
修改表名ALTER TABLE 旧表名 RENAME 新表名;
删除表DROP TABLE 表名;
获取表信息DESC 表名;
对于字段的操作
对于字段的操作代码
添加字段ALTER TABLE 表名 ADD 字段 类型;
删除字段ALTER TABLE 表名 DROP 字段 类型;
修改字段名ALTER TABLE 表名 CHANGE 旧字段 新字段;
修改字段类型ALTER TABLE 表名 MODIFY 字段 类型;
查询所有字段信息DESC 表名;
查询创建表信息SHOW CREATE TABLE 表名;
代码演示
#查询所有数据库
SHOW DATABASES;

#创建数据库
CREATE DATABASE 2104javaee;

#使用数据库
USE 2104javaee;

#查询该数据库中所有的表
SHOW TABLES;

#删除数据库
DROP DATABASE 2104javaee;

#创建表
CREATE TABLE db_student(
	s_id INT(3),
	s_name VARCHAR(32),
	s_sex CHAR(3),
	s_salary FLOAT(8,2)
)

#获取表信息
DESC db_student;

#获取创建表信息
SHOW CREATE TABLE db_student;

#修改表名
ALTER TABLE db_student RENAME student;

#删除表
DROP TABLE student;

#创建表
CREATE TABLE student(
	s_id INT(3),
	s_name VARCHAR(32),
	s_sex CHAR(3),
	s_salary FLOAT(8,2)
)

#修改字段类型
ALTER TABLE student MODIFY s_sex char(1);

#获取表信息
DESC student;

#添加字段
ALTER TABLE student ADD course VARCHAR(32);

#删除字段
ALTER TABLE student DROP course;

#修改字段名+类型
ALTER TABLE student CHANGE s_id id INT(3);
ALTER TABLE student CHANGE s_name name VARCHAR(20);
ALTER TABLE student CHANGE s_sex sex char(1);
ALTER TABLE student CHANGE s_salary salary FLOAT(8,2);

#获取表信息
DESC student;

2.数据操作语言 - DML

对数据的添加、修改、删除代码
插入数据(不指定字段)INSERT INTO 表名 VALUES(值1,值2,值n);
插入数据(指定字段,推荐使用)INSERT INTO 表名(字段1,字段2,字段n) VALUES(值1,值2,值n);
更新数据(该字段上所有的数据都更改)UPDATE 表名 SET 字段=值;
更新数据(更改单个字段上的数据+单个条件)UPDATE 表名 SET 字段=值 WHERE 条件;
更新数据(更改单个字段上的数据+多个条件)UPDATE 表名 SET 字段=值 WHERE 条件 AND 条件;
更新数据(更改单个字段上的数据+多个条件)UPDATE 表名 SET 字段=值 WHERE 条件 OR 条件;
更新数据(更改多个字段上的数据+单个条件)UPDATE 表名 SET 字段=值,…,字段=值 WHERE 条件;
更新数据(更改多个字段上的数据+多个条件)UPDATE 表名 SET 字段=值,…,字段=值 WHERE 条件 AND 条件;
更新数据(更改多个字段上的数据+多个条件)UPDATE 表名 SET 字段=值,…,字段=值 WHERE 条件 OR 条件;
删除所有数据(不建议使用,清空数据后再添加数据id从1开始)TRUNCATE TABLE 表名;
删除所有数据DELETE FROM 表名;
删除数据+条件DELETE FROM 表名 WHERE 条件;

补:两种清空表的优缺点

DELETE FROM 表名;
#效果:删除表中的所有记录  
#缺点:本身是将数据一行一行的删除,所以如果数据量比较大,删除的效率就很低

TRUNCATE TABLE 表名;
#效果:删除表中的所有记录
#删除效率较高,实现方式是:将该表直接删除,然后创建一个同名的表

3.数据查询语言 - DQL(重点)

对数据的查询代码
查询所有数据SELECT * FROM 表名;
查询指定字段上的数据SELECT 字段,字段 FROM 表名;
查询指定字段上的数据+别名SELECT 字段 AS ‘别名’ FROM 表名;
查询指定字段上的数据+去重SELECT DISTINCT 字段 FROM 表名;
查询指定字段上的数据+条件SELECT * FROM 表名 WHERE 条件 AND 条件;
SELECT * FROM 表名 WHERE 条件 OR 条件;
SELECT * FROM 表名 WHERE 条件 NOT 条件;
使用算数运算符来作为条件:> >= < <= = != …
查询指定字段上的数据是否为NULLSELECT * FROM 表名 WHERE 字段 IS NULL;
SELECT * FROM 表名 WHERE 字段 IS NOT NULL;
查询指定字段是否在指定范围中SELECT * FROM 表名 WHERE 字段 BETWEEN 最小值 AND 最大值;
枚举查询:查询指定字段的值是否属于指定的集合SELECT * FROM 表名 WHERE 字段 IN(值1,值2,值n);
效果:字段的值与in后面的集合中某一个值相等,则条件成立
模糊查询(like):
%表示不确定多少个字符
_表示一个字符
[]表示匹配[]中的任意一个字符
[^]表示不匹配[]中的任意一个字符
SELECT * FROM 表名 WHERE 字段 LIKE ‘%内容%’;
SELECT * FROM 表名 WHERE 字段 LIKE ‘_内容’;
查询数据+排序
ASC:升序(默认)
DESC:降序
SELECT * FROM 表名 ORDER BY 字段 ASC;
SELECT * FROM 表名 ORDER BY 字段 DESC;
查询数据+多字段排序SELECT * FROM 表名 ORDER BY 字段 DESC,字段 ASC;
限制查询(限制查询出结果的条数)SELECT * FROM LIMIT 数量;
限制查询 + 排序SELECT * FROM 表名 ORDER BY 排序关键字 DESC/ASC LIMIT 数量;
注意:先排序再限制
分页查询SELECT * FROM 表名 LIMIT 偏移量,数量;
*分页公式:SELECT * FROM student LIMIT ((页数-1)获取条数,获取条数)
聚合查询求总和SUM :SELECT SUM(字段) FROM 表名;
统计总数COUNT(主键):SELECT COUNT(字段) FROM 表名;
求最大值MAX :SELECT MAX(字段) FROM 表名;
求最小值MIN :SELECT MIN(字段) FROM 表名;
求平均值AVG :SELECT AVG(字段) FROM 表名;
子查询SELECT * FROM 表名 WHERE 字段=(子查询语句);
注意:子查询出的结果再复制给前面的sql语句
分组查询SELECT 字段,AVG(字段) FROM 表名 GROUP BY 字段;
分组查询+条件SELECT 字段,AVG(字段) FROM 表名 GROUP BY 字段 HAVING 条件;
三表联合查询SELECT * FROM t_employees e
INNER JOIN t_departments d
ON e.department_id = d.department_id
INNER JOIN t_locations l
ON d.location_id = l.location_id
多表联合查询内连接SELECT s.name,t.name FROM student s,teacher t WHERE s.t_id=t.id;
SELECT s.name,t.name FROM student s INNER JOIN teacher t ON s.t_id=t.id;
多表联合查询:自动连接(不建议使用)SELECT s.name,t.name FROM student s NATURAL JOIN teacher t ;
多表联合查询:左连接SELECT s.name,t.name FROM student s LEFT JOIN teacher t ON s.t_id=t.id;
多表联合查询:右连接
左连接和右链接统称为外连接[OUTER]
SELECT s.name,t.name FROM student s RIGHT JOIN teacher t ON s.t_id=t.id;
合并两个查询结果(SELECT s.name,t.name FROM student s LEFT JOIN teacher t ON s.t_id=t.id;)
UNION ALL
(SELECT s.name,t.name FROM student s RIGHT JOIN teacher t ON s.t_id=t.id;)
全连接(并集,去重)(SELECT s.name,t.name FROM student s LEFT JOIN teacher t ON s.t_id=t.id;)
UNION
(SELECT s.name,t.name FROM student s RIGHT JOIN teacher t ON s.t_id=t.id;)
交集SELECT * FROM student WHERE age>21 AND id IN (SELECT id FROM student WHERE id<5);
差集SELECT * FROM student WHERE age>21 AND NOT id IN (SELECT id FROM student WHERE id<5);
代码演示
#创建表 + 主键 + 主键自动增长
#主键:不能重复并且不能为空(null)
#创建表,将id设为主键,且自动增长
#PRIMARY KEY:主键
#auto_increment:自动增长
CREATE TABLE student(
		id INT(32) PRIMARY KEY auto_increment,
		name VARCHAR(32),
		sex VARCHAR(32),
		age INT(3),
		salary FLOAT(8,2),
		course VARCHAR(32)
);

#插入数据
INSERT INTO student VALUES(1,'小舞','男',18,8000,'JAVA');

INSERT INTO student(name,sex,age,salary,course)VALUES('麻生希','女',29,13000,'JAVA');
INSERT INTO student(name,sex,age,salary,course) VALUES('刘德华','男',62,20000,'JAVA');
INSERT INTO student(name,sex,age,salary,course) VALUES('霍华德','男',36,6000,'HTML');
INSERT INTO student(name,sex,age,salary,course) VALUES('霍建华','男',38,9000,'HTML');
INSERT INTO student(name,sex,age,salary,course) VALUES('华晨宇','男',25,3500,'PYTHON');
INSERT INTO student(name,sex,age,salary,course) VALUES('水野朝阳','女',27,15000,'PYTHON');
INSERT INTO student(name,sex,age,salary,course) VALUES('欧阳正华','男',47,18000,'JAVA');

#修改数据(所有的年纪都改成50岁)
UPDATE student SET age=50;

#修改数据+条件
#需求:把刘德华的年龄改为50
UPDATE student SET age=50 WHERE id=3;

#修改数据 + 条件
#需求:把id大于5或者年龄大于30的学生的工资改成8000
UPDATE student SET salary=8000 WHERE id>5 OR age>30;

#修改数据 + 条件
#需求:把id大于5和者年龄大于30的学生的工资改成8000
UPDATE student SET salary=8000 WHERE id>5 AND age>30;

#删除数据(清空所有数据)
DELETE FROM student;
TRUNCATE TABLE student;#清空后,再添加时id从1开始(不推荐使用,因为恢复备份时会造成id冲突,从而数据恢复失败)

#删除数据+条件
#需求:把id为2的数据删除
DELETE FROM student WHERE id=2;

#查询所有字段
SELECT * FROM student;

#查询指定字段
SELECT name,age FROM student;

#查询指定字段+别名
SELECT name AS '姓名',age AS '年龄' FROM student;

#查询数据+条件
SELECT name FROM student WHERE age<28;

#查询数据+去重
SELECT DISTINCT course FROM student;

#判断字段的值是否为null
#不能使用=或者!=来进行判断
#应该使用IS NULL/IS NOT NULL来进行判断
#需求:查询student表中age字段值为null的记录
SELECT * FROM student WHERE age IS NULL;
#需求:查询student表中age字段值不为null的记录
SELECT * FROM student WHERE age IS NOT NULL;

#between...and...
#用来判断指定字段的指定是否在指定范围中
#需求:查询年龄在18与23之间的学生信息
SELECT * FROM student WHERE age BETWEEN 18 AND 23;

#in
#用来判断指定的字段的值是否属于指定的集合
#WHERE 字段名 in(值1,值2,值3....)
#效果:字段的值与in后面的集合中某一个值相等,则条件成立
#需求:查询student表中年龄为18岁以上25以下,并且年龄为奇数的学员信息
SELECT * FROM stu WHERE age BETWEEN 19 AND 24 AND age%2 = 1;
SELECT * FROM stu WHERE age in(19,21,23);

#模糊查询
#%表示不确定多少个字符
#_表示一个字符
#[]表示匹配[]中的任意一个字符
#[^]表示不匹配[]中的任意一个字符
#需求:查询姓名中带华字的数据
SELECT * FROM student WHERE name LIKE '%华%';
#需求:查询姓名中间带华字的数据
SELECT * FROM student WHERE name LIKE '_华_';
#需求:查询姓名中开头带华字的数据
SELECT * FROM student WHERE name LIKE '华%';
#需求:查询姓名中末尾带华字的数据
SELECT * FROM student WHERE name LIKE '%华';

#查询+排序
#ASC:表示升序(默认)
#DESC:表示降序
#需求:按照年龄排升序
SELECT * FROM student ORDER BY age;
SELECT * FROM student ORDER BY age ASC;
#需求:按照工资排降序
SELECT * FROM student ORDER BY salary DESC;

#多字段排序查找
#需求:年龄做升序,年龄相同工资做降序
SELECT * FROM student ORDER BY age ASC,salary DESC;

#限制查找
SELECT * FROM student LIMIT 3;

#分页
#分页公式:SELECT * FROM student LIMIT ((页数-1)*获取条数,获取条数)
#SELECT * FROM student LIMIT 偏移量,获取条数
#需求:分页查询,每一页展示3个信息
SELECT * FROM student LIMIT 0,3;#第1页
SELECT * FROM student LIMIT 3,3;#第2页
SELECT * FROM student LIMIT 6,3;#第3页

#需求:取这个班年龄最大的前三个人(思路:先排序再限制)
SELECT * FROM student ORDER BY age DESC LIMIT 3;
#聚合查询
#需求:工资总和
SELECT SUM(salary) FROM db_student;
#需求:求年龄的平均数
SELECT AVG(age) FROM db_student;
#需求:求最大年龄
SELECT MAX(age) FROM db_student;
#需求:求最小年龄
SELECT MIN(age) FROM db_student;
#需求:求学生的个数(count()如果值为null是不算进个数,所以字段一般选择主键即可)
SELECT COUNT(id) FROM db_student;

#子查询
#需求:查询最高工资的学生
SELECT * FROM db_student WHERE salary=(SELECT MAX(salary) FROM db_student);

#分组:分组过滤+条件
#需求:查询各个学科的平均工资,展示出>10000的学科
SELECT course,AVG(salary) FROM db_student GROUP BY course HAVING AVG(salary)>10000;

#多表联合查询
# 建立老师表(id、name)并添加数据
# 建立学生表(id、name、t_id)并添加数据
#内连接
SELECT s.name,t.name FROM student s,teacher t WHERE s.t_id=t.id;
SELECT s.name,t.name FROM student s INNER JOIN teacher t ON s.t_id=t.id;
#左连接
SELECT s.name,t.name FROM student s LEFT JOIN teacher t ON s.t_id=t.id;
#右链接
SELECT s.name,t.name FROM student s RIGHT JOIN teacher t ON s.t_id=t.id;
#查询合并
SELECT s.name,t.name FROM student s LEFT JOIN teacher t ON s.t_id=t.id
UNION ALL
SELECT s.name,t.name FROM student s RIGHT JOIN teacher t ON s.t_id=t.id;
# 全链接(查询到的重复结果给去掉)
SELECT s.name,t.name FROM student s LEFT JOIN teacher t ON s.t_id=t.id
UNION 
SELECT s.name,t.name FROM student s RIGHT JOIN teacher t ON s.t_id=t.id;

4.事务处理语言 - TPL(重点)

1.模拟转账

生活当中转账是转账方账户扣钱,收账方账户加钱。我们用数据库操作来模拟现实转账。

1.1 数据库模拟转账
#A 账户转账给 B 账户 1000 元。
#A 账户减1000 元
UPDATE account SET MONEY = MONEY-1000 WHERE id=1;
#B 账户加 1000 元
UPDATE account SET MONEY = MONEY+1000 WHERE id=2;

上述代码完成了两个账户之间转账的操作。

1.2 模拟转账错误
#A 账户转账给 B 账户 1000 元。
#A 账户减1000 元
UPDATE account SET MONEY = MONEY-1000 WHERE id=1;
#断电、异常、出错...
#B 账户加 1000 元
UPDATE account SET MONEY = MONEY+1000 WHERE id=2;

上述代码在减操作后过程中出现了异常或加钱语句出错,会发现,减钱仍旧是成功的,而加钱失败了!

注意:每条 SQL 语句都是一个独立的操作,一个操作执行完对数据库是永久性的影响。

2.事务的概念

​ 事务是一个原子操作。是一个最小执行单元。可以由一个或多个SQL语句组成,在同一个事务当中,所有的SQL语句都成功执行时,整个事务成功,有一个SQL语句执行失败,整个事务都执行失败。

3.事务的边界
  • 开始:连接到数据库,执行一条DML语句。 上一个事务结束后,又输入了一条DML语句,即 事务的开始
  • 结束:
    • 提交
      • 显示提交:commit;
      • 隐式提交:一条创建、删除的语句,正常退出(客户端退出连接);
    • 回滚
      • 显示回滚:rollbcak;
      • .隐式回滚:非正常退出(断电、宕机),执行了创建、删除的语句,但是失败了, 会为这个无效的语句执行回滚。
4.事务的原理

​ 数据库会为每一个客户端都维护一个空间独立的缓存区(回滚段),一个事务中所有的增删改语句的 执行结果都会缓存在回滚段中,只有当事务中所有SQL 语句均正常结束(commit),才会将回 滚段中的数据同步到数据库。否则无论因为哪种原因失败,整个事务将回滚(rollback)。

5.事务的特性
  • Atomicity(原子性):表示一个事务内的所有操作是一个整体,要么全部成功,要么全部失败。
  • Consistency(一致性):表示一个事务内有一个操作失败时,所有的更改过的数据都必须回滚到修改前状态
  • Isolation(隔离性):事务查看数据操作时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另 一事务修改它之后的状态,事务不会查看中间状态的数据。
  • Durability(持久性):持久性事务完成之后,它对于系统的影响是永久性的。
6.用事务完成转账
#A 账户给 B 账户转账。
#1.开启事务
START TRANSACTION;
setAutoCommit=0;#禁止自动提交 
setAutoCommit=1;#开启自动提交
#2.事务内数据操作语句
UPDATE ACCOUNT SET MONEY = MONEY-1000 WHERE ID = 1;
UPDATE ACCOUNT SET MONEY = MONEY+1000 WHERE ID = 2;
#3.事务内语句都成功了,执行 COMMIT;
COMMIT;
#4.事务内如果出现错误,执行 ROLLBACK;
ROLLBACK;

​ 注意:开启事务后,执行的语句均属于当前事务,成功再执行 COMIIT,失败要进行 ROLLBACK.

5.数据控制语言 - DCL

含义

权限管理。给子账户开辟权限。

语法格式
功能代码格式
开辟子账户CREATE USER ‘用户名’@‘localhost’ IDENTIFIED BY ‘密码’;
给定权限GRANT 权限 ON 库.表 TO ‘用户’@‘localhost’ IDENTIFIED BY ‘密码’;
删除权限REVOKE 权限 ON 库.表 FROM ‘用户’@‘localhost’;

注:权限:insert、delete、select、update

参数说明
符号说明
grant all在grant后接all说明给予所有权限
revoke all在revoke后接all说明删除所有权限
权限 on.. 指明给予所有库所有表的操作权限
‘用户’@‘主机’主机里面若为%。任意来源的主机均可以使用这个用户来访问
代码演示
#创建子账号并设置权限(前提是主账号登录后)
grant select,insert,updata,delete on 2104javaee.* to 'aaa'@'localhost' identified by '123';

#删除权限
revoke updata,delete on 2104javaee.* from 'aaa'@'localhost';

#解决编码问题(在黑窗口输入)
Set charset gbk;

三、数据类型

MySQL的数据类型主要分为四大类:

整数类型浮点类型字符串类型日期类型

1.整型

MySQL数据类型所占字节值范围
tinyint1字节-128~127
smallint2字节-32768~32767
mediumint3字节-8388608~8388607
int4字节-2147483648~2147483647
bigint8字节±9.22*10的18次方

​ 补充:UNSIGNED(无符号)主要用于整型和浮点类型,使用无符号,即,没有前面面的-(负号)。存储位数更长。tinyint整型的取值区间为,-128~127。而使用无符号unsigned修饰后可存储0-255个长度。

2.浮点型

MySQL数据类型所占字节值范围
float(m,d)4字节单精度浮点型,m总个数,d小数位
double(m,d)8字节双精度浮点型,m总个数,d小数位
decimal(m,d)decimal是存储为字符串的浮点数

​ 设一个字段定义为float(6,3),如果插入一个数123.45678,实际数据库里存的是123.457,但总个数还以实际为准,即6位。整数部分最大是3位,如果插入数12.123456,存储的是12.1234,如果插入12.12,存储的是12.1200.所以浮点型float和double都有可能失去精度。所以我们常用不会失精的decimal。

重点:定点数(decimal):浮点型在数据库中存放的是近似值,而定点数在数据库中存放的是精确值。decimal(m,d) 参数m<65 是总个数,d<30且 d<m 是小数位。

3.字符类型

MySQL数据类型所占字节值范围
char0-255字节定长字符串
varchar0-255字节变长字符串
tinyblob0-255字节不超过255个字符的二进制字符串
tinytext0-255字节短文本字符串
blob0-65535字节二进制形式的长文本数据
text0-65535字节长文本数据
mediumblob0-16 777 215字节二进制形式的中等长度文本数据
mediumtext0-16 777 215字节中等长度文本数据
longblob0-4 294 967 295字节二进制形式的极大文本数据
longtext0-4 294 967 295字节极大文本数据
varbinary(m)允许长度0-M个字节的定长字节符串值的长度+1个字节
binary(m)m允许长度0-M个字节的定长字节符串

char和varchar的区别

  1. char表示定长字符串。 指定长度后,占用的空间就一定是这个长度。适合用来存放固定长度的值;

    varchar表示可变长字符串。根据实际存到值,占用对应的空间大小,但是需要使用一个单独的空间来记录实际的长度。

    1. char(n) 若存入字符数小于n,则以空格补于其后,查询之时再将空格去掉。所以char类型存储的字符串末尾不能有空格,varchar不限于此。

    2. char(n) 固定长度,char(4)不管是存入几个字符,都将占用4个字节,varchar是存入的实际字符数+1个字节(n<=255)或2个字节(n>255),

    所以varchar(4),存入3个字符将占用4个字节。

    1. char类型的字符串检索速度要比varchar类型的快。

varchar和text的区别:

​ 1. varchar可指定n,text不能指定,内部存储varchar是存入的实际字符数+1个字节(n<=255)或2个字节(n>255),text是实际字符数+2个字节。

​ 2. text类型不能有默认值。

3. varchar可直接创建索引,text创建索引要指定前多少个字符。varchar查询速度快于text,在都创建索引的情况下,text的索引似乎不起作用。

blob和text的区别:

1. BLOB和TEXT存储方式不同,TEXT以文本方式存储,英文存储区分大小写,而Blob是以二进制方式存储,不分大小写。
2. BLOB存储的数据只能整体读出。
3. TEXT可以指定字符集,BLOB不用指定字符集。

4.日期类型

MySQL数据类型所占字节含义和格式
date3字节日期,格式:2020-05-31
time3字节时间,格式:13:14:52
datetime8字节日期时间,格式:2021-05-31 13:14:52
timestamp4字节自动存储记录修改的时间,格式:2021-05-31
year1字节年份,格式:2021

**注意:**时间类型在web系统中用的比较少,很多时候很多人喜欢使用int来存储时间。插入时插入的是unix时间戳,因为这种方式更方便计算。在前端业务中用date类型的函数,再将unix时间戳转成人们可识别的时间。

补充:常见数据类型的属性

MySQL关键字含义
null数据列可包含null值
not null数据列不允许包含null值
default默认值
primary key主键
auto_increment自动递增,适用于整数类型
unsigned无符号
character set name指定一个字符集

四、约束

1.含义

​ 约束(constraint)是一种限制,它通过对表的行或列的数据作出限制,来确保表的数据的完整性唯一性。约束其实就是给表的字段添加限制。

2.实体完整新约束

​ 表中的一行数据代表一个实体(entity),实体完整性的作用即是标识每一行数据不重复、实体唯 一。

1.主键约束:primary key

主键约束 = 唯一约束 + 非空约束

理解:数据库表对应Java类,表中的每一行记录对应Java对象;

​ 那么一个Java对象应该有一个唯一 标识;

​ 那没每一行记录应该有一个字段值,这个字段值不能为空,不能重复,这个字段就被成为主键;

一个表必须有主键

格式:

CREATE TABLE 表名(
	字段名 类型 PRIMARY KEY,
    ...
)
ALTER TABLE 表名 DROP PRIMARY KEY

示例:

#创建product产品表
CREATE TABLE product(
	pid INT PRIMARY KEY,
    pname VARCHAR(50)
);

#给表中插入数据
INSERT INTO product VALUES(NULL,"huaweip40");#会报错,因为主键不能为null
INSERT INTO product VALUES(1,"iphone12");
INSERT INTO product VALUES(1,"iphone13");#会报错,因为作为主键的pid不能重复

#删除主键
ALTER TABLE product DROP PRIMARY KEY;
2.主键自增长(自动增长列):auto_increment

当主键的类型是整数时,可以为主键添加自增长约束

我们如果没有为该主键赋值,主键不再是默认的NULL

而是默认从1开始自己赋值,每添加一条数据的主键值都是在上一条添加的数据的主键值基础上**+1**

格式:

CREATE TABLE 表名(
	字段名 类型 PRIMARY KEY AUTO_INCREMENT,
    ...
)

示例:

CREATE TABLE category(
	cid INT PRIMARY KEY AUTO_INCREMENT,
    cname VARCHAR(50)
);

INSERT INTO category VALUES(NULL, "手机");
INSERT INTO category VALUES(NULL, "电脑");

SELECT * FROM category;# 效果是:正常执行 并且 主键有值了
3.唯一约束:unique

顾名思义,添加了唯一约束的字段值不能重复

格式:

CREATE TABLE 表名(
	字段名 类型 UNIQUE,
    ...
)
ALTER TABLE 表名 ADD UNIQUE(字段名)
ALTER TABLE 表名 DROP INDEX 字段名

示例:

#添加唯一约束
ALTER TABLE product ADD UNIQUE(pname);
#删除唯一约束
ALTER TABLE product DROP INDEX pname;

3.域完整性约束

​ 限制列的单元格的数据正确性。

1.非空约束:not null

顾名思义,非空约束的字段值不能为空

格式:

CREATE TABLE 表名(
	字段名 类型 NOT NULL,
    ...
)

示例:

#添加非空约束 和 默认值
ALTER TABLE user MODIFY password VARCHAR(32) NOT NULL DEFAULT '000000';
#删除非空约束 和 默认值
ALTER TABLE user MODIFY password VARCHAR(32);
2.默认值约束:default

如果一个字段添加了默认值约束,则如果没有给该字段赋值,该字段就使用默认值。

格式:

CREATE TABLE 表名(
	字段名 类型 DEFAULT 值,
    ...
)

综合示例:

CREATE TABLE car(
	cid INT PRIMARY KEY AUTO_INCAREMENY,
    cname VARCHAR(50) NOT NULL,
    brand VARCHAR(50) UNIQUE,
    price DECIMAL(5,2) DEFAULT 20.50
);

#插入数据
# 会出错  因为cname字段有非空约束,不能为null
INSERT INTO car(cname, brand) VALUES(NULL, "BMW");
# 不会出错  price没有主动赋值,应该是默认值 20.5
INSERT INTO car(cname, brand) VALUES("m5", "BMW");
# 会出错  因为brend字段有唯一约束,不能重复
INSERT INTO car(cname, brand) VALUES("m5", "BMW");
3.外键约束(引用完整新约束):foreign key

本表跟外部表的关联约束。要想实现表与表之间的关联,就需要添加外键约束,为了避免bug,建议给主键添加外键约束,就可以避免重复导致的关联失效。一般不用外键,效率极低。

格式:

CREATE TABLE 表名(
	字段 类型,
    ...
    CONSTRAINT 外键名称 FOREIGN KEY(字段名称) REFERENCES 引用的表名(引用的主键名),
    ...
)
ALTER TABLE 表名 ADD FOREIGH KEY(字段名称) REFERENCES 引用的表名(引用的主键名)
ALTER TABLE 表名 DROP FOREIGH KEY 表名

示例:

#外键约束
#本表跟外部表的关联约束
# 注意:不用外键的原因时,修改数据时都要去外键所在的表中查询一遍,效率极低
#添加外键
ALTER TABLE student add FOREIGN KEY(t_id) REFERENCES teacher(id);
#查询外键名
SHOW CREATE TABLE student;
#删除外键
ALTER TABLE student DROP FOREIGN KEY student_ibfk_1;

五、深入扩展

1.索引

1.概述

​ 索引就相当于书的目录,可以优化查找速度。

优点提高该字段的查询效率

缺点:更新数据,索引的数据结构也会随之改变。

优化缺点:大量更新数据,先把索引删除掉,更新完数据后再添加索引。

2.索引类型
索引类型功能说明
普通索引最基本的索引,它没有任何限制。该列上的数据可以重复,可以为null
唯一索引某一行企用了唯一索引则不准许这一列的行数据中有重复的值。针对这一列的每一行数据都要求是唯一的
主键索引它是一种特殊的唯一索引,不允许有空值。一般是在建表的时候同时创建主键索引,常用于用户
全文索引对于需要全局搜索的数据,进行全文索引
1.普通索引

该列上的数据可以重复,可以为null

格式:

ALTER TABLE 表名 ADD INDEX(字段);
DROP INDEX 字段 ON 表名;

示例:

#为user表的username字段添加普通索引
ALTER TABLE user ADD INDEX(username);
#可以给两个字段同时添加普通索引,不过容易出现脏数据,索引容易失效
ALTER TABLE student add INDEX(name,age);
#删除普通索引
DROP INDEX username ON user;
2.唯一索引

唯一约束,该列上的数据必须相同,但可以为多个null

格式:

ALTER TABLE 表名 ADD UNIQUE(字段);
ALTER TABLE 表名 DROP INDEX(字段);

示例:

#为student表的name字段添加唯一索引
ALTER TABLE student ADD UNIQUE(name);
#删除唯一索引
ALTER TABLE db_student DROP INDEX name;
3.主键索引

主键约束,不允许重复,不允许为null

格式:

ALTER TABLE 表名 ADD PRIMARY KEY(字段);
ALTER TABLE 表名 DROP PRIMARY KEY(字段);

示例:

#创建主键索引(一般是随着建表而建索引)
ALTER TABLE db_student ADD PRIMARY KEY(id);
#删除索引
ALTER TABLE db_student DROP PRIMARY KEY;
4.全文索引

对于需要全局搜索的数据,进行全文索引

格式:

ALTER TABLE 表名 ADD FULLTEXT(字段);
DROP INDEX 字段 ON 表名;

示例:

#为student表的content字段添加全文约束
ALTER TABLE student ADD FULLTEXT(content);
#建表的时候也可以设置对应的索引
CREATE TABLE test (
	id INT NOT NULL , 
	username VARCHAR(20) NOT NULL , 
	password INT NOT NULL , 
	content INT NOT NULL , 
	PRIMARY KEY (id), 
	INDEX pw (password), 
	UNIQUE (username),
	FULLTEXT (content)
) ENGINE = InnoDB;
#删除索引
drop index index_name on table_name;

2、视图

1.含义

虚拟表view,mysql5.1版本出现的新特性,是通过表动态生成的数据。从一个表或多个表中查询出来的表,作用和真实表一样,包含一系列带有行和列的 数据。视图中,用户可以使用SELECT语句查询数据,也可以使用INSERT,UPDATE,DELETE修改 记录,视图可以使用户操作方便,并保障数据库系统安全。

2.视图的优缺点
  • 优点
    • 简单化,数据所见即所得
    • 安全性,用户只能查询或修改他们所能见到得到的数据。
    • 逻辑独立性,可以屏蔽真实表结构变化带来的影响。
  • 缺点
    • 性能相对较差,简单的查询也会变得稍显复杂。
    • 修改不方便,特变是复杂的聚合视图基本无法修改。
2.创建视图

格式:CREATE VIEW 视图名 AS 查询数据源表语句;

CREATE [OR REPLACE] VIEW 视图名 AS SELECT 字段 FROM 表名 WHERE 条件 [WITH CHECK OPTION];
#or replace:如果已有视图,则替换
#with check option:当修改值超过条件时,不允许修改

示例:

CREATE OR REPLACE VIEW view1 AS SELECT name,age FROM student WHERE age>20 WITH CHECK OPTION;
3.查询视图

格式:

SELECT * FROM 视图名;

示例:

SELECT * FROM view1;
4.修改视图

格式:

INSERT INTO 视图名(字段1,字段n) VALUES(值1,值n)
UPDATE 视图名 SET 字段=值 WHERE 字段=值;

示例:

#给视图插入数据
INSERT INTO view1(name,age) VALUES('ccc',25);
insert into view1(name,age) values('ddd',19);
insert into view1(name,age) values('xxx',25);
insert into view1(name,age) values('yyy',19);
#修改视图
UPDATE view1 SET age=33 WHERE name='aaa';
5.删除视图

格式:

DROP VIEW 视图名;

示例:

#删除视图
DROP VIEW view1;

注意:删除视图不会影响原表

6.视图注意事项
  • 视图不会独立存储数据,原表发生改变,视图也发生改变。没有优化任何查询性能。
  • 如果视图包含以下结构中的一种,则视图不可更新
    • 聚合函数的结果
    • DISTINCT 去重后的结果
    • GROUP BY 分组后的结果
    • HAVING 筛选过滤后的结果
    • UNION、UNION ALL 联合后的结果

3.触发器

1.含义

某个事件触发某个功能

2.创建触发器
CREATE TRIGGER 触发器名
3.代码练习
#触发器:某个事件触发某个功能
#new.字段:当前写法可以获得添加语句字段对应的值
#old.字段:当前写法可以获得删除语句字段对应的值
#delimiter xx :设置xx为一条sql语句的结束符

#业务场景
#student(id,name,class_id,course_id)
#class(id,name,sum)

# 需求:student表插入数据后,class表自动更新
# 当学生表发生了插入事件,就执行班级表的更新操作
CREATE TRIGGER trigger1 AFTER INSERT ON student FOR EACH ROW UPDATE class SET sum=sum+1 WHERE id= new.class_id;

INSERT INTO student(name,class_id) VALUES('aaa',1);
INSERT INTO student(name,class_id) VALUES('bbb',1);
INSERT INTO student(name,class_id) VALUES('ccc',1);
INSERT INTO student(name,class_id) VALUES('ddd',2);
INSERT INTO student(name,class_id) VALUES('eee',2);

# 需求:student表删除数据后,class表自动更新
# 当学生表发生了删除事件,就执行班级表的更新操作
CREATE TRIGGER trigger2 BEFORE DELETE ON student FOR EACH ROW UPDATE class SET sum=sum-1 WHERE id=old.class_id;
DELETE FROM student WHERE id=1;

DROP TRIGGER trigger1;
DROP TRIGGER trigger2;

#业务场景
#student(id,name,class_id,course_id)
#class(id,name,sum)
#course(id,name,sum)

# 需求:student表插入数据后,class表自动更新,course表自动更新
delimiter xx
CREATE TRIGGER trigger3 AFTER INSERT ON student FOR EACH ROW 
		BEGIN
					UPDATE class SET sum=sum+1 WHERE id=new.class_id;
					UPDATE course SET sum=sum+1 WHERE id=new.course_id;
		END xx
delimiter ;

INSERT INTO student(name,class_id,course_id) VALUES('aaa',1,1);
INSERT INTO student(name,class_id,course_id) VALUES('bbb',1,1);
INSERT INTO student(name,class_id,course_id) VALUES('ccc',2,1);
INSERT INTO student(name,class_id,course_id) VALUES('ddd',2,1);
INSERT INTO student(name,class_id,course_id) VALUES('eee',2,1);
INSERT INTO student(name,class_id,course_id) VALUES('fff',3,2);

# 需求:student表删除数据后,class表自动更新,course表自动更新
delimiter xx
CREATE TRIGGER trigger4 BEFORE DELETE ON student FOR EACH ROW
	BEGIN
			UPDATE class SET sum=sum-1 WHERE id=old.class_id;
			UPDATE course SET sum=sum-1 WHERE id=old.course_id;
delimiter ;

DELETE FROM student WHERE id=1;

4.函数和自定义函数

1.常见函数
#数学函数
SELECT ABS(-100); #获取绝对值
SELECT SQRT(9); #获取平方根
SELECT MOD(10,3); #求余数
SELECT RAND(); #获取随机值 0(包含)~1(不包含)
SELECT POW(10,3); #幂运算

#字符串函数
SELECT LENGTH('abc123456'); #获取长度
SELECT CONCAT('123','abc','木头人'); #拼接字符串
SELECT SUBSTRING('abcdefg',2,4); #(字符串,第一个字符(从1开始),获取字符的个数)

#日期时间函数
SELECT CURDATE(); #获取当前日期
SELECT CURTIME(); #获取当前时间
SELECT NOW(); #获取当前时间加日期
SELECT YEAR(NOW()); # 获取年
SELECT MONTH(NOW()); # 获取月
SELECT DAYOFMONTH(NOW());# 获取日
SELECT HOUR(NOW());# 获取小时
SELECT MINUTE(NOW()); # 获取分
SELECT SECOND(NOW());# 获取秒
SELECT DATE_FORMAT(NOW(),"%Y年%m月%d日 %H时%i分%s秒");
2.自定义函数
#函数:类似于java中的方法
#注意:函数必须有返回值

#最简单的函数
CREATE FUNCTION fun01() RETURNS INT(3) RETURN 666;
#调用
SELECT fun01();

#带有返回值的函数
#需求:返回id为4的学生年龄
delimiter xx
CREATE FUNCTION fun02() RETURNS INT(3)
	BEGIN
		DECLARE a INT(3);
		SELECT age INTO a FROM student WHERE id=4;
		RETURN a;
	END xx
delimiter ;
#调用
SELECT fun02();

#带返回值和参数的函数
#需求:传入学生姓名,查询出对应的年龄
delimiter xx
CREATE FUNCTION fun03(s_name VARCHAR(32)) RETURNS INT(3)
	BEGIN
			DECLARE a int(3);
			SELECT age INTO a FROM student WHERE name=s_name;
			RETURN a;
	END xx
delimiter ;
#调用
SELECT fun03('ccc');

#删除函数
DROP FUNCTION fun01;

5.存储过程

1.含义

​ 存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。

2.创建存储过程
CREATE PROCEDURE 存储过程名
3.参数
输入类型的参数 -- in;
输出类型的参数 -- out;
输入输出类型的参数 -- inout;
4.代码练习
#存储过程
#参数列表
#输入类型的参数 -- in;
#输出类型的参数 -- out;
#输入输出类型的参数 -- inout;

#案例1:最简单的的存储过程
#需求:查询学生信息和班级信息
delimiter xx
CREATE PROCEDURE myprocedure01()
		BEGIN
				SELECT * FROM student;
				SELECT * FROM class;
		END xx
delimiter ;
#调用存储过程
CALL myprocedure01();

# 案例2:输入一个学生的id,查询该学生的信息
delimiter xx
CREATE PROCEDURE myprocedure02(in s_id INT(3))
		BEGIN
				SELECT * FROM student WHERE id=s_id;
		END xx
delimiter ;
#调用存储过程
CALL myprocedure02(2);

# 案例3:输入一个学生的id,返回该id对应的学生姓名
delimiter xx
CREATE PROCEDURE myprocedure03(in s_id INT(3),out s_name VARCHAR(32))
		BEGIN
				SELECT name INTO s_name FROM student WHERE id=s_id;
		END xx
delimiter ;
#调用存储过程
CALL myprocedure03(2,@a);
SELECT @a;

# 案例4:输入一个学生的id,返回该id对应的学生年龄
delimiter xx
CREATE PROCEDURE myprocedure04(INOUT pram INT(3))
		BEGIN
				SELECT age INTO pram FROM student WHERE id=pram;
		END xx
delimiter ;
#调用存储过程
SET @pram=2;#设置局部变量
CALL myprocedure04(@pram);
SELECT @pram;

# 案例5:定义存储过程中的变量
# 需求:获取学生表中学生的人数
delimiter xx
CREATE PROCEDURE myprocedure05(out s_out int(3))
		BEGIN
				# 定义变量
				# declare 变量名 类型 [default 默认值];
				DECLARE a INT DEFAULT 0;
				# 给变量赋值(目的:告诉你们可以这样复制,在本案例里没有任何意义)
				SET a=100;
				SELECT COUNT(id) INTO a FROM student;
				SET s_out=a;
		END xx
delimiter ;
# 调用存储过程
call myprocedure05(@a);
select @a;

#删除存储过程
DROP PROCEDURE myprocedure05;

五、代码练习

1.导入数据

/*创建部门表*/
CREATE TABLE dept(
	deptno		INT 	PRIMARY KEY,
	dname		VARCHAR(50),
	loc 		VARCHAR(50)
);

/*创建雇员表*/
CREATE TABLE emp(
	empno		INT 	PRIMARY KEY,
	ename		VARCHAR(50),
	job		VARCHAR(50),
	mgr		INT,
	hiredate	DATE,
	sal		DECIMAL(7,2),
	COMM 		DECIMAL(7,2),
	deptno		INT,
	CONSTRAINT fk_emp FOREIGN KEY(mgr) REFERENCES emp(empno)
);

/*创建工资等级表*/
CREATE TABLE salgrade(
	grade		INT 	PRIMARY KEY,
	losal		INT,
	hisal		INT
);

/*创建学生表*/
CREATE TABLE stu(
	sid		INT 	PRIMARY KEY,
	sname		VARCHAR(50),
	age		INT,
	gander		VARCHAR(10),
	province	VARCHAR(50),
	tuition		INT
);


/*插入dept表数据*/
INSERT INTO dept VALUES (10, '教研部', '北京');
INSERT INTO dept VALUES (20, '学工部', '上海');
INSERT INTO dept VALUES (30, '销售部', '广州');
INSERT INTO dept VALUES (40, '财务部', '武汉');

/*插入emp表数据*/
INSERT INTO emp VALUES (1009, '曾阿牛', '董事长', NULL, '2001-11-17', 50000, NULL, 10);
INSERT INTO emp VALUES (1004, '刘备', '经理', 1009, '2001-04-02', 29750, NULL, 20);
INSERT INTO emp VALUES (1006, '关羽', '经理', 1009, '2001-05-01', 28500, NULL, 30);
INSERT INTO emp VALUES (1007, '张飞', '经理', 1009, '2001-09-01', 24500, NULL, 10);
INSERT INTO emp VALUES (1008, '诸葛亮', '分析师', 1004, '2007-04-19', 30000, NULL, 20);
INSERT INTO emp VALUES (1013, '庞统', '分析师', 1004, '2001-12-03', 30000, NULL, 20);
INSERT INTO emp VALUES (1002, '黛绮丝', '销售员', 1006, '2001-02-20', 16000, 3000, 30);
INSERT INTO emp VALUES (1003, '殷天正', '销售员', 1006, '2001-02-22', 12500, 5000, 30);
INSERT INTO emp VALUES (1005, '谢逊', '销售员', 1006, '2001-09-28', 12500, 14000, 30);
INSERT INTO emp VALUES (1010, '韦一笑', '销售员', 1006, '2001-09-08', 15000, 0, 30);
INSERT INTO emp VALUES (1012, '程普', '文员', 1006, '2001-12-03', 9500, NULL, 30);
INSERT INTO emp VALUES (1014, '黄盖', '文员', 1007, '2002-01-23', 13000, NULL, 10);
INSERT INTO emp VALUES (1011, '周泰', '文员', 1008, '2007-05-23', 11000, NULL, 20);


INSERT INTO emp VALUES (1001, '甘宁', '文员', 1013, '2000-12-17', 8000, NULL, 20);


/*插入salgrade表数据*/
INSERT INTO salgrade VALUES (1, 7000, 12000);
INSERT INTO salgrade VALUES (2, 12010, 14000);
INSERT INTO salgrade VALUES (3, 14010, 20000);
INSERT INTO salgrade VALUES (4, 20010, 30000);
INSERT INTO salgrade VALUES (5, 30010, 99990);

/*插入stu表数据*/
INSERT INTO `stu` VALUES ('1', '王永', '23', '男', '北京', '1500');
INSERT INTO `stu` VALUES ('2', '张雷', '25', '男', '辽宁', '2500');
INSERT INTO `stu` VALUES ('3', '李强', '22', '男', '北京', '3500');
INSERT INTO `stu` VALUES ('4', '宋永合', '25', '男', '北京', '1500');
INSERT INTO `stu` VALUES ('5', '叙美丽', '23', '女', '北京', '1000');
INSERT INTO `stu` VALUES ('6', '陈宁', '22', '女', '山东', '2500');
INSERT INTO `stu` VALUES ('7', '王丽', '21', '女', '北京', '1600');
INSERT INTO `stu` VALUES ('8', '李永', '23', '男', '北京', '3500');
INSERT INTO `stu` VALUES ('9', '张玲', '23', '女', '广州', '2500');
INSERT INTO `stu` VALUES ('10', '啊历', '18', '男', '山西', '3500');
INSERT INTO `stu` VALUES ('11', '王刚', '23', '男', '湖北', '4500');
INSERT INTO `stu` VALUES ('12', '陈永', '24', '男', '北京', '1500');
INSERT INTO `stu` VALUES ('13', '李雷', '24', '男', '辽宁', '2500');
INSERT INTO `stu` VALUES ('14', '李沿', '22', '男', '北京', '3500');
INSERT INTO `stu` VALUES ('15', '王小明', '25', '男', '北京', '1500');
INSERT INTO `stu` VALUES ('16', '王小丽', '23', '女', '北京', '1000');
INSERT INTO `stu` VALUES ('17', '唐宁', '22', '女', '山东', '2500');
INSERT INTO `stu` VALUES ('18', '唐丽', '21', '女', '北京', '1600');
INSERT INTO `stu` VALUES ('19', '啊永', '23', '男', '北京', '3500');
INSERT INTO `stu` VALUES ('20', '唐玲', '23', '女', '广州', '2500');
INSERT INTO `stu` VALUES ('21', '叙刚', '18', '男', '山西', '3500');
INSERT INTO `stu` VALUES ('22', '王累', '23', '男', '湖北', '4500');
INSERT INTO `stu` VALUES ('23', '赵安', '23', '男', '北京', '1500');
INSERT INTO `stu` VALUES ('24', '关雷', '25', '男', '辽宁', '2500');
INSERT INTO `stu` VALUES ('25', '李字', '22', '男', '北京', '3500');
INSERT INTO `stu` VALUES ('26', '叙安国', '25', '男', '北京', '1500');
INSERT INTO `stu` VALUES ('27', '陈浩难', '23', '女', '北京', '1000');
INSERT INTO `stu` VALUES ('28', '陈明', '22', '女', '山东', '2500');
INSERT INTO `stu` VALUES ('29', '孙丽', '21', '女', '北京', '1600');
INSERT INTO `stu` VALUES ('30', '李治国', '23', '男', '北京', '3500');
INSERT INTO `stu` VALUES ('31', '张娜', '23', '女', '广州', '2500');
INSERT INTO `stu` VALUES ('32', '安强', '18', '男', '山西', '3500');
INSERT INTO `stu` VALUES ('33', '王欢', '23', '男', '湖北', '4500');
INSERT INTO `stu` VALUES ('34', '周天乐', '23', '男', '北京', '1500');
INSERT INTO `stu` VALUES ('35', '关雷', '25', '男', '辽宁', '2500');
INSERT INTO `stu` VALUES ('36', '吴强', '22', '男', '北京', '3500');
INSERT INTO `stu` VALUES ('37', '吴合国', '25', '男', '北京', '1500');
INSERT INTO `stu` VALUES ('38', '正小和', '23', '女', '北京', '1000');
INSERT INTO `stu` VALUES ('39', '吴丽', '22', '女', '山东', '2500');
INSERT INTO `stu` VALUES ('40', '冯含', '21', '女', '北京', '1600');
INSERT INTO `stu` VALUES ('41', '陈冬', '23', '男', '北京', '3500');
INSERT INTO `stu` VALUES ('42', '关玲', '23', '女', '广州', '2500');
INSERT INTO `stu` VALUES ('43', '包利', '18', '男', '山西', '3500');
INSERT INTO `stu` VALUES ('44', '威刚', '23', '男', '湖北', '4500');
INSERT INTO `stu` VALUES ('45', '李永', '23', '男', '北京', '1500');
INSERT INTO `stu` VALUES ('46', '张关雷', '25', '男', '辽宁', '2500');
INSERT INTO `stu` VALUES ('47', '送小强', '22', '男', '北京', '3500');
INSERT INTO `stu` VALUES ('48', '关动林', '25', '男', '北京', '1500');
INSERT INTO `stu` VALUES ('49', '苏小哑', '23', '女', '北京', '1000');
INSERT INTO `stu` VALUES ('50', '赵宁', '22', '女', '山东', '2500');
INSERT INTO `stu` VALUES ('51', '陈丽', '21', '女', '北京', '1600');
INSERT INTO `stu` VALUES ('52', '钱小刚', '23', '男', '北京', '3500');
INSERT INTO `stu` VALUES ('53', '艾林', '23', '女', '广州', '2500');
INSERT INTO `stu` VALUES ('54', '郭林', '18', '男', '山西', '3500');
INSERT INTO `stu` VALUES ('55', '周制强', '23', '男', '湖北', '4500');

2.题目

  1. 查询出部门编号为30的所有员工

    SELECT * FROM emp WHERE deptno=30;
    
  2. 所有销售员的姓名、编号和部门编号。

    SELECT ename,empno,deptno FROM emp;
    
  3. 找出奖金高于工资的员工。

    SELECT * FROM emp WHERE COMM>sal;
    
  4. 找出奖金高于工资60%的员工。

    SELECT * FROM emp WHERE COMM>(sal*0.6);
    
  5. 找出部门编号为10中所有经理,和部门编号为20中所有销售员的详细资料。

    SELECT * FROM emp WHERE job='经理' AND deptno=10 OR job='销售员' AND deptno=20;
    
  6. 找出部门编号为10中所有经理,部门编号为20中所有销售员,还有即不是经理又不是销售员但其工资大或等于20000的所有员工详细资料。

    SELECT * FROM emp WHERE job='经理' AND deptno=10 OR job='销售员' AND deptno=20 OR job!='经理' AND job!='销售员' AND sal>=20000;
    
  7. 无奖金或奖金低于1000的员工。

    SELECT * FROM emp WHERE COMM<1000 OR COMM IS NULL;
    
  8. 查询名字由三个字组成的员工

    SELECT * FROM emp WHERE ename LIKE '___';
    
  9. 查询2000年入职的员工。

    SELECT * FROM emp WHERE hiredate LIKE '2000%';
    
  10. 查询所有员工详细信息,用编号升序排序

    SELECT * FROM emp ORDER BY empno;
    SELECT * FROM emp ORDER BY empno ASC;
    
  11. 查询所有员工详细信息,用工资降序排序,如果工资相同使用入职日期升序排序

SELECT * FROM emp ORDER BY sal DESC,hiredate

12.查询每个部门的平均工资

SELECT deptno,AVG(sal) FROM emp GROUP BY deptno;

13.查询每个部门的雇员数量

SELECT deptno,COUNT(deptno) FROM emp GROUP BY deptno;

14.查询每种工作的最高工资、最低工资、人数

SELECT deptno,MAX(sal),MIN(sal),COUNT(deptno) FROM emp GROUP BY deptno;

15.查出至少有一个员工的部门。显示部门编号、部门名称、部门位置、部门人数

SELECT e.deptno,COUNT(e.empno),d.dname,d.loc
FROM emp e,dept d
WHERE e.deptno=d.deptno
GROUP BY deptno
HAVING COUNT(empno)>=4;

16.列出所有员工的姓名及其直接上级的姓名

SELECT e1.ename,e2.ename
FROM emp e1,emp e2
WHERE e1.mgr=e2.empno;
SELECT e1.ename,e2.ename 
FROM emp e1 LEFT JOIN emp e2 
ON e1.mgr=e2.empno;

17.列出受雇日期早于直接上级的所有员工的编号、姓名、部门名称

SELECT e1.empno,e1.ename,d.dname
FROM emp e1,emp e2,dept d
WHERE e1.mgr=e2.empno AND e1.deptno=d.deptno AND
e1.hiredate<e2.hiredate;
SELECT e1.empno,e1.ename,d.dname
FROM emp e1 LEFT JOIN emp e2 
ON e1.mgr=e2.empno 
LEFT JOIN dept d 
ON e1.deptno=d.deptno 
WHERE e1.hiredate<e2.hiredate;

18.列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门

SELECT d.dname,e.*
FROM dept d LEFT JOIN emp e
ON d.deptno = e.deptno;

19.列出最低薪金大于15000的各种工作及从事此工作的员工人数

SELECT job,MIN(sal+IFNULL(COMM,0)),COUNT(empno)
FROM emp
GROUP BY job
HAVING MIN(sal+IFNULL(COMM,0))>15000;

20.列出在销售部工作的员工的姓名,假定不知道销售部的部门编号

SELECT emp.ename,dept.deptno FROM emp,dept WHERE emp.deptno=dept.deptno AND dname='销售部';

21.列出薪金高于公司平均薪金的所有员工信息,所在部门名称,上级领导,工资等级

SELECT
FROM emp e1,emp e2,dept d,salgrade s
WHERE (e1.sal+IFNULL(e1.COMM,0))>(SELECT AVG(sal+IFNULL(COMM,0)) FROM emp)
AND e1.mgr=e2.empno AND e1.deptno=d.deptno
AND e1.sal>s.losal AND e1.sal<=s.hisal;

22.列出与庞统从事相同工作的所有员工及部门名称

SELECT emp.*,dept.dname 
FROM emp,dept WHERE emp.deptno=dept.deptno 
AND emp.job=(SELECT job FROM emp WHERE ename='庞统');

23.列出薪金高于在部门30工作的所有员工的薪金的员工姓名和薪金、部门名称

SELECT e.ename,e.((sal + IFNULL(COMM,0)),d.dname 
FROM emp e,dept d
WHERE e.deptno=d.deptno 
AND (e.sal+IFNULL(e.COMM,0))>(SELECT MAX(sal+IFNULL(COMM,0)) FROM emp WHERE deptno=30);

24.列出每个部门的员工数量、平均工资

SELECT COUNT(*),AVG(sal) 
FROM emp 
WHERE deptno IN(SELECT deptno FROM dept) 
GROUP BY deptno;
建立环境实验和数据库/ 实验学时:2学时 实验类型:验证 实验要求:必修 一、实验目的 通过本实验的学习,使学生熟悉SQL Server 2014的集成环境,帮助学生掌握数据库的建立方法以及SQL Server的数据导入方法 二、实验内容    (一)、SQL Server 2014的安装 SQL Server2014的安装过程与 SQL Server 2008、SQL Server2012的安装过程类似,都提供了一个功能树以用来安装所有 SQL Server 组件,包括计划、安装、维护、工具、资源、高级、选项等功能。下面是各功能选项中所包含的内容,如图3-1所示。 图3-1 安装计划中的内容 (1)选择“安装”功能,因为要创建SQL Server 2014的全新安装,单击“全新SQL Server 2014独立安装或向现有安装添加功能”选项,如图3-2所示。 图3-2 “安装”功能中的内容 (2)在“产品密匙”页上,选择相应的单选按钮,这些按钮指示是安装免费版本的SQL Server还是具有产品密匙的产品版本,如果使指免费的评估版,只有180天的试用期限,如图3-3所示。 图3-3 “产品密钥”界面 (3)在“许可条款”页上阅读许可协议,然后选中相应的复选框以接受许可条款和条件。如图3-4所示。 图3-4 “许可条款”界面 (4)系统进行安装程序支持规则检查,以确定安装SQL Server安装程序支持文件时可能发生的问题。必须更正所有的失败,安装程序才能继续。如图3-5所示。 图3-5 “安装规则”界面 (5)在“设置角色”页上选择SQL Server功能安装,如图3-6所示。 图3-6 “设置”角色界面 (6)在“功能选择”页上选择要安装的组件。选择功能名称后,右侧窗体中会显示每个组件的说明。可以根据实际需要,选中一些功能,如图3-7所示。一般应用可选择“数据库引擎服务”、“客户端工具连接”、“SQL客户端连接”和“管理工具”等选项。 图3-7“功能选择”界面 (7)在“实例配置”页上制定是安装默认实例还是命名实例,对于默认实例,实例的名称和ID都是MSSQLSERVER,也可以自己“命名实例”安装实例,如图3-8所示。SQL Server支持多个实例,即支持在同一台计算机上同时运行多个SQL Server数据库引擎实例,每个SQL Server数据库引擎实例各有一套不为其它实例共享的系统及用户数据库。应用程序连接同一台计算机上的SQL Server数据库引擎实例的方式与连接其它计算机上运行的SQL Server数据库引擎的方式基本相同。 图3-8 “实例配置”界面 (8)在“服务器配置”页上指定SQL Server服务的登录帐户。SQL Server提供了多种服务,可以为所有SQL Server服务分配相同的登录账户,也可以分别配置每个服务账户。还可以指定服务是自动启动、手动启动还是禁用。Microsoft建议对各服务账户进行单独配置,以便为每项服务提供最低特权,即向SQL Server服务授予它们完成各自任务所需的最低权限,如图3-9所示。SQL Server中的每个服务代一个进程或一组进程,每个进程需要有访问SQL Server相关文件和系统注册的权限,为了能让SQL Server服务在操作系统中正常的启动和运行,就需要指定SQL Server的服务帐户,所以服务帐户指的是Windows操作系统中的帐户。 图3-9 “服务器配置”界面 (9)在“数据库引擎配置”的“服务器配置”页上指定身份验证模式、用户名、密码,如图3-10所示。这里的用户身份验证指的是登录到服务器使用的身份验证模式及用户名和密码。身份验证模式分为“Windows身份验证模式”和“混合模式(SQL Server身份验证和Windows身份验证)”。如果选择“Windows身份验证模式”示则只能使用Windows的帐号登录,即使用当前登录到操作系统的帐号进行登录,通过这种方式用户登录到SQL Server中时不再需要输入帐号和密码。如选择“混合模式(SQL Server身份验证和Windows身份验证)”示除了可以用使用登录到Windows的帐号作为登录的依据外,还可以使用SQL Server系统的帐号登录,这里必须为内置SQL Server系统管理员账户(SA)提供一个强密码。必须至少为SQL Server实例指定一个系统管理员。若要添加用以运行SQL Server安装程序账户,则要单击“添加当前用户”按钮。若要向系统管理员列中添加账户或从中删除账户,则单击“添加…”或“删除…”按钮,然后编辑将拥有SQL Server实例的管理员特权的用户、组或计算机列。 图3-10 设置身份验证模式和管理员 (10)在“准备安装”页显示安装过程中的安装选项的树视图,如图3-11所示。若要继续,单击“安装”按钮。在安装过程中,“安装进度”页会提供相应的状态,因此可以在安装过程中监视安装进度。 图3-121“准备安装”界面 (11)安装完成后,“完成”页提供指向安装日志文件摘要以及其他重要说明的链接。如图3-12所示。 图3-12 “安装完成”界面 (二)、建库建练习      1、利用语句建库和建: 创建学生数据库StuDB,文件名和位置自定,在此数据库中创建如下三张: 学生(student) (   学号(sno) 普通编码定长字符类型,长度9,主码,   姓名(sname) 普通编码定长字符类型,长度10,非空,   性别(ssex) 统一编码定长字符类型,长度2,   年龄(sage) 微整型,   所在系(sdept) 统一编码可变长字符类型,长度20 ) 课程(course) (   课程号(cno) ,通编码定长字符类型,长度4,主码,   课程名(cname) 统一编码定长字符类型,长度,40,非空,   开课学期(Semester) 短整数, 学分(credit) 短整数 ) 修课(sc)(   学号(sno) 普通编码定长字符类型,长度7,主码,外码   课程号(cno) 普通编码定长字符类型,长度6,主码,外码   成绩(grade) 小整型,   修课类别(ctype)普通编码定长字符类型,长度4 ) 2、建立“汽车”数据库,文件名和位置自定,在此数据库中创建如下三张: 汽车(CarT),结构如下:   汽车序号(CId) 整型 主关键字,   汽车名称(CName) 普通编码定长字符类型 长度为10  非空,   型号(CType)普通编码变长字符类型 长度为60  非空,   价格(CPrice) 整型,   车身眼色(Ccolor)普通编码变长字符类型 长度为20。 部门(DepartT),结构如下:   部门序号(DId)整型 主关键字,   部门名(DName)普通编码定长字符类型 长度为20   非空,   负责人名(DLead)普通编码定长字符类型 长度为10  非空,   人数(DAmount) 整型。 汽车出厂(FacT),结构如下:   汽车序号(CID) 整型 非空,   部门序号(DId) 整型 非空,   出厂日期(FDate)小日期时间型 非空,   出厂数量(FAmount) 整型,   出厂价格(FPrice) 整型。   其中:主关键字为(汽车序号,部门序号,出厂日期)   “汽车序号”为引用汽车的“汽车序号”的外部关键字; “部门序号”为引用部门的“部门序号”的外部关键字。 3、使用数据库的可视化工具建库建 建立银行贷款,具体要求同课堂教学的建库建一致。 银行(BankT)( 银行代码(Bno) 主键 银行名称(Bname) 非空 电话(Tel) ) 法人(LET)( 法人代码(Eno)主键 法人名称(Ename)取值唯一 经济性质(Enature) 注册资金(Ecapital) 法定代人(Erep) ) 贷款(LoanT)( 法人代码(Eno) 银行代码(Bno) 贷款日期(Ldata) 贷款金额(Lamount) 贷款期限(Lterm) )        (三)、数据导入练习 将“学生数据库数据.xls”中的数据导入到学生数据库的三张中。 将“银行贷款数据.xls”中的数据导入到银行贷款数据库的三张中。 三、实验报告 将实验结果反映在实验报告中,并对实验中遇到的问题及解决方案、进行整理、分析总结,提出实验结论或自己的看法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

釣餌锒鐺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值