数据库1, 数据库的安装和配置1.1 数据库的概念数据库的定义: 了解数据库的历史: 了解1.2 数据库的分类数据库分类一些数据库: 了解1.3 数据库的安装1.4 数据库构成客户端和服务器MySQL的内部数据组织方式2, SQL语法2.1 SQL语言2.2 SQL的基本操作2.2.1 登录数据库2.2.2 库操作查看数据库创建数据库删除数据库修改数据库选择数据库2.2.3 表操作常见的数据类型(1) 整数(2) 浮点数(3) 日期(4) 字符串查看表创建表主键和自增问题修改表删除表2.2.4 数据操作添加数据查询数据修改数据删除数据2.3 特殊关键字2.3.1 Where2.3.2 Distinct2.3.3 Limit 2.3.4 As2.3.5 Order By2.3.6 Group By2.3.7 聚合函数2.4 SQL执行顺序2.5 数据完整性2.5.1 实体完整性2.5.2 域完整性2.5.3 参照完整性3, SQL和多表问题3.1 多表设计/多表理论3.1.1 一对一3.1.2 一对多3.1.3 多对多 3.1.4 数据库设计范式第一范式: 原子性第二范式: 唯一性第三范式: 不冗余3.2 多表查询3.2.1 链接/连接查询交叉链接自然连接内连接外连接: 左右外连接自连接3.2.2 子查询3.2.3 联合查询4, 数据库备份和恢复4.1 命令行操4.2 图形化界面5, 上课sql5.1 523号上午sql5.1 523号下午sql
1, Database:A database is an organized collection of data,stored and accessed electronically.
2, 数据库(Database)是按照数据结构来组织、存储和管理数据的仓库。
3, 数据库(Database)是一种结构化信息或数据的有组织的集合。
4, 在现实中,
数据以及[数据库管理系统 (DBMS)](Database Management System)一起被称为数据库系统,通常简称为数据库。
自 20 世纪 60 年代初诞生至今,数据库已经发生了翻天覆地的变化。最初,人们使用分层数据库(树形模型/一对多)和网络数据库(图模型/多对多)这样的导航数据库来存储和操作数据。这些早期系统是很简单的,同时也缺乏灵活性。
20 世纪 80 年代,关系数据库开始兴起.
20 世纪 90 年代,面向对象的数据库开始成为主流。
最近,随着互联网的快速发展,为了更快速地处理非结构化数据,NoSQL 数据库应运而生。


关系型数据库:关系数据库在 20 世纪 80 年代成为主流。关系数据库中的
数据项被组织为一系列具有列和行的表。关系数据库为访问结构化信息提供了有效和灵活的方法.非关系型数据库:又被称为NoSQL数据库,它支持存储和操作
非结构化及半结构化数据。而且随着 Web 应用的日益普及和复杂化,NoSQL 数据库得到了越来越广泛的应用.等...
注: 区别 注意
SQL标准/SQL语言: 1986年定义了一个SQL标准: SQL标准语言 (SQL语言操作数据, 是以数据和数据之前的关系去操作数据的)
SQL语句: select * from user; 从user表中查出所有信息
关系型数据库和非关系型数据库, 虽然区别很多, 但是
最本质的区别是: 关系型数据库以数据和数据之间存在的关系维护数据, 而非关系型数据库是指存储数据的时候数据和数据之前没有什么特定关系.大家要注意的是, 虽然数据库有种类的区别,但是这是一个无关孰优孰劣的问题(没有谁好谁差之分),主要取决于企业希望如何使用数据.从本质上讲, 他们都是用来存储数据的. (而对于我们一个Java后端开发来讲, 我们在实际工作中基本上是以关系型数据库为主, 非关系型数据库为辅的用法)
注: 关于NoSQL的SQL解释
SQL:结构化查询语言(Structured Query Language)简称SQL,是一种专门用来和数据库通信的标准语言,用于向数据库存取数据以及查询、更新和管理关系数据库系统. 每个
关系型数据库都支持SQL语言/SQL标准.
MySQL
是一个由瑞典MySQLAB公司开发,属于Oracle旗下产品。MySQL是最流行的关系型数据库管理系统之一
Oracle
又名Oracle RDBMS,或简称Oracle。是甲骨文公司的一款关系数据库管理系统。它是在数据库领域一直处于领先地位的产品。可以说Oracle数据库系统是世界上流行的关系数据库管理系统,系统可移植性好、使用方便、功能强,适用于各类大、中、小微机环境。它是一种高效率的、可靠性好的、适应高吞吐量的数据库方案.
SQLServer
SQLServer是由
微软公司开发的一种关系型据库管理系统,它已广泛用于电子商务、银行、保险、电力等行业。SQLServer提供了对XML和Internet标准的支持,具有强大的、灵活的、基于Web的应用程序管理功能。而且界面友好、易于操作,深受广大用户的喜爱,但它只能在Windows平台上运行(2017年开始支持Linux系统),并对操作系统的稳定性要求较高,因此很难处理日益增长的用户数量。
DB2数据库
DB2数据库是由IBM公司研制的一种关系型数据库管理系统,主要应用于OS/2、Windows等平台下,具有较好的可伸缩性,可支持从大型计算机到单用户环境。
DB2支持标准的SQL,并且提供了高层次的数据利用性、完整性、安全性和可恢复性,以及从小规模到大规模应用程序的执行能力,适合于海量数据的存储,但相对于其他数据库管理系统而言,DB2的操作比较复杂。
MariaDB
MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品。在存储引擎方面,使用XtraDB来代替MySQL的InnoDB。 MariaDB由MySQL的创始人Michael Widenius主导开发,他早前曾以10亿美元的价格,将自己创建的公司MySQL AB卖给了SUN,此后,随着SUN被甲骨文收购,MySQL的所有权也落入Oracle的手中。MariaDB名称来自Michael Widenius的女儿Maria的名字。
MariaDB基于事务的Maria存储引擎,替换了MySQL的MyISAM存储引擎,它使用了Percona的 XtraDB,InnoDB的变体,分支的开发者希望提供访问即将到来的MySQL 5.4 InnoDB性能。这个版本还包括了 PrimeBase XT (PBXT) 和 FederatedX存储引擎。
PostgreSQL
是以加州大学伯克利分校计算机系开发的 Postgres 版本 4.2 为基础的对象关系型数据库管理系统(ORDBMS)。和MySQL一样是开源数据库。POSTGRES 领先的许多概念只是在非常迟的时候才出现在商业数据库中。
MongoDB数据库
MongoDB是由10gen公司开发的一个
介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似JSON的bjson格式,因此可以存储比较复杂的数据类型。Mongo数据库管理系统最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。不仅如此,它还是一个开源数据库,并且具有高性能、易部署、易使用、存储数据非常方便等特点。对于大数据量、高并发、弱事务的互联网应用,MongoDB完全可以满足Web2.0和移动互联网的数据存储需求。
Redis
Remote Dictionary Server(Redis) 是一个由 Salvatore Sanfilippo 写的 key-value 存储系统,是跨平台的非关系型数据库。 Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库,并提供多种语言的 API。
1.数据库安装
安装数据库: 安装的是一个具有监听端口/分析SQL语句/存储数据/组织数据/响应数据为一体的数据库服务器
xxxxxxxxxx331// 更新包列表2sudo apt update3// 安装mysql4sudo apt install mysql-server mysql-client5// 安装客户端依赖包(编程需要)6sudo apt install libmysqlclient-dev7// 查看mysql状态8netstat -tap | grep mysql910// 设置账号密码相关的信息 (选项选Y)(密码级别选0)11sudo mysql_secure_installation1213// 查看mysql状态14systemctl status mysql.service15// 也可用于查看mysql状态16sudo service mysql status1718// 访问mysql19sudo mysql -u root -p2021// 设置密码长度 (SHOW VARIABLES LIKE 'validate_password%';)22set global validate_password.length=6;23// 修改用户的认证方式和密码24alter user 'root'@'localhost' identified with mysql_native_password by '123456';25// 刷新26flush privileges;27// 退出mysql客户端28exit;2930// 重启mysql31service mysql restart32//或者33systemctl restart mysql
2.客户端连接数据库
3.Navicat连接数据库
在互联网的网络交互和数据访问中,一般常见两种网络架构模式: B/S结构或者C/S结构.
B/S: Browser-Server即浏览器和服务器, 即通过浏览器和服务器发起网络交互的数据请求.
C/S: Client-Server即客户端和服务器, 即通过客户端和服务器发起网络交互的数据请求.
而我们上面安装的Navicat以及MySQL, 这两者的关系是一个标准的C/S结构.

在MySQL中, 我们对数据的组织逻辑上是按照
库/表/数据这种三级结构组织的.数据库: 表示一份完整的数据仓库, 在这个数据仓库中分为多张不同的表.
表: 表示某种特定类型数据的的结构化清单, 里面包含多条数据.
数据: 表中数据的基本单元.

SQL语言
SQL:结构化查询语言(Structured Query Language)简称SQL,是一种专门用来和关系型数据库通信的标准语言,用于向数据库存取数据以及查询、更新和管理关系数据库系统。
与其他语言(Java, C++...)不同的是, SQL由很少的词构成, 这是希望从数据库读写数据时能以更简单有效的方法进行.
SQL有如下优点
SQL语言不是某个特定的数据库提供的语言, 它是一种数据库标准语言.(最初由美国国家标准局 ANSI于1986年完成第一版SQL标准的定义,即SQL-86).这也就意味着每个关系型数据库都支持SQL语言.
SQL简单易学, 是由多个描述性很强的单词构成, 并且这些单词数量不多.
SQL尽管看上去很简单, 但是非常强有力; 灵活的使用SQL, 可以进行比较复杂的和高级的数据库操作.
SQL不区分大小写(除非在某些数据库使用的时候做了特殊设置-不建议这种行为).
mysql -u root -p [回车]
输入密码

注1 : 注释
xxxxxxxxxx51-- <注释>; # 注释语句2# <注释>; # 注释语句3/*4<注释> # 注释语句5*/注意:
在数据库语句中如果我们需要注释某些内容, 一般有三种方式
--注释符(要注意的是--之后要有一个空格再接着书写注释内容)
#注释符 (之后不需要空格)
/* */注释符 (一般用于多行注释)
注2: 分号
SQL语句应该要以分号作为结束
show databases; # 查看所有数据库
show databases like '%数据库名%'; # 查看和期望命名相匹配的数据库
show create database 数据库名; # 查看数据库创建信息
xxxxxxxxxx21// show databases like '%数据库名%';2// %代表是一个通配符: 通配0-n个字符
xxxxxxxxxx51 show databases like 'test'; -- 指明就找test2 show databases like '%n'; -- 一个以n字符结束的数据库3 show databases like '%n%'; -- 数据库名字中, 有一个n字符 4
5show create database test; -- 查看之前怎么创建的test数据库(sql语句是什么)
注: 了解(不需要专门记忆)
information_schema:主要存储了系统中的一些
数据库对象信息,比如用户表信息、列信息、权限信息、字符集信息和分区信息等。mysql:MySQL 的核心数据库,主要负责存储数据库
用户、用户访问权限等 MySQL 自己需要使用的控制和管理信息。常用的比如在 mysql 数据库的 user 表中修改 root 用户密码。update mysql.user set authentication_string=password('123456') where user='root';
flush privileges;
performance_schema:主要用于
收集数据库服务器性能参数。sys:sys 数据库主要提供了一些视图,数据都来自于 performation_schema,主要是让开发者和使用者更
方便地查看性能问题。
xxxxxxxxxx141CREATE DATABASE [IF NOT EXISTS] <数据库名>2[[DEFAULT] CHARACTER SET <字符集名>]3[[DEFAULT] COLLATE <校对规则名>];45eg:67-- 创建一个db47的数据库, 有可能创建失败直接报错(假如数据库服务里面已经有一个db47的数据库了)8create database db47;9-- 创建一个叫test数据库, 并且要求编码格式是utf8, 还要求排序规则utf8_bin10create database test character set utf8 collate utf8_bin;11-- 如果不存在名字为db47的数据库, 就创建db47, 如果已经存在了db47的数据库, 就不创建(也不报错)12create database if not exists db47;13-- 创建一个指定字符编码格式的和指定排序规则的数据库14create database if not exists test character set utf8 collate utf8_bin;
[ ]可选。<数据库名>:创建数据库的名称。
IF NOT EXISTS:在创建数据库之前进行判断,只有该数据库目前尚不存在时才能执行操作; 如果这个数据库存在, 就不创建/不执行这个sql。
[DEFAULT] CHARACTER SET:指定数据库的字符集。
[DEFAULT] COLLATE:指定字符集的默认校对规则。
注:一些注意事项
注意我们MySQL创建数据库的时候, 如果没有指明编码格式, 那么创建出了数据库在存储字符串的时候, 很多系统默认使用latin1的编码格式 (latin1存储一个字符的时候一个字符占用1个字节, 并且不能存储中文, 中文没有办法用一个字节表示: 所以在实际工作的时候, 我们更应该使用utf8 or utf8mb4)
MySQL中字符集: UTF8 和UTF8MB4的区别
xxxxxxxxxx41// (1) 5.5.3 版本以后的才支持UTF8MB42// (2) UTF8MB4是 UTF8 的超集并完全兼容UTF8。3// (3) UTF8(也称UTF8MB3),1字符使用3字节存储。4// (4) UTF8MB4,1字符使用4字节存储。(专门用来兼容4字节的UNICODE编码-平面设计-Emoji问题)。
MySQL中几个了解的校对规则: 了解(不用记具体的排序规则, 只需要知道排序规则是干什么,是对谁起效果的)
xxxxxxxxxx81校对规则/排序规则也可以称为排序规则,是指在字符与字符之间的比较规则。一个字符集有多种校对规则,每个字符集都有一个默认的校对规则。23eg: UTF8MB4: 下面只是用来举例说明, 不用记4// (1) UTF8MB4_GENERAL_CI: (默认规则),字符之间逐个比较,不区分大小写,在排序和比较效率更高。5// 一些特殊字符不能做到精准排序。6// 其实就是没有实现Unicode排序规则, 影响上实际并无所谓。7// (2) UTF8MB4_UNICODE_CI: 基于标准的Unicode来排序和比较,精确排序, 不区分大小写。8// (3) UTF8MB4_BIN: 字符直接用二进制数据编译存储,区分大小写,而且可以存二进制的内容。

在工作中不要删除数据库, 哪怕这个数据库已经没有任何用处了 ( 任何数据都是有价值的, 哪怕是错的数据)
xxxxxxxxxx31DROP DATABASE [IF EXISTS] <数据库名>; # 删除数据库23eg: drop database test; # 删除test数据库

在工作中不要修改数据库, 因为没有任何意义
xxxxxxxxxx51ALTER DATABASE [数据库名]2{ [ DEFAULT ] CHARACTER SET <字符集名> | [ DEFAULT ] COLLATE <校对规则名> }345eg: alter database test character set utf8 collate utf8_bin; # 把test数据库的编码改成utf8, 校对规则改为utf8_bin数据库中只提供了对数据库使用的字符集和校对规则修改操作。
xxxxxxxxxx81假设一种场景: 举个例子2// 第一步: 先创建了一个数据库: create database th54 character set utf8;3// 编码格式是utf84// 第二步: 在这个数据库th54中创建一个表: studnets->utf8. (如果在创建表的时候没有指明编码格式, 默认跟随数据库的编码格式)5// 第三步: 修改了th54的编码格式: alter database th54 character set utf8mb4;6// th54的编码格式已经修改为utf8mb47// studnets编码格式会不会跟着变? 默认不会, 还是utf88// 第四步: 创建一个全新的User表 : User -> utf8mb4

xxxxxxxxxx41USE <数据库名>; # 选择数据库23eg:4use test; # 选择test数据库一个MySQL系统中, 管理多个数据库。 我们只有进入对应的数据库中, 才能进一步操作数据库中的表和数据。

数据类型(DATA_TYPE)是指数据库所允许的数据的类型。
MySQL是一个数据存储容器, 数据类型定义了可以存储什么类型数据的规则。
数据库是由多张表构成。其中每个表中对应的数据列, 都应该有适当的数据类型,用于限制或允许该列中存储的数据。
| MySQL的整数类型 | 占用字节 | 有符号 | 无符号 | 说明 |
|---|---|---|---|---|
| TINYINT(M) | 1 | -128 ~ 127 | 0 ~ 255 | 很小的整数 |
| INT/INTEGER(M) | 4 | -231 ~ 231-1 | 0 ~ 232-1 | 普通整数 |
| BIGINT(M) | 8 | -263 ~ 263-1 | 0 ~ 264-1 | 大整数 |
注意1:
INT和INTEGER在MySQL中并无区别, 仅是缩略写法.link。
注意2: 关于
整数设置'长度/宽度'问题。第一原则:无论给整数设置什么长度都不违背上述'有/无符号'表示的存储范围(上述范围表示是一切基本标准)。
第二原则: 设置长度之后, 如果存储的整数长度小于指定长度, 会默认在数字位前自动补空格, 以满足指定长度(但是补的空格这是不可见的), 也可以选择经过设置使用0填充; 设置长度之后, 如果存储的整数长度大于指定长度, 如果在表示范围内, 不做切割/不做处理(不补0, 也不补空格), 直接存储。
xxxxxxxxxx61CREATE TABLE `tb_test` (2`id` int NOT NULL,3`age` int ZEROFILL NULL, -- zerofill: 填充04`height` int(3) unsigned NOT NULL,5PRIMARY KEY (`id`)6);
| MySQL的浮点数 | 占用字节 | 说明 |
|---|---|---|
| FLOAT(M, D) | 4 | 单精度 |
| DOUBLE(M, D) | 8 | 双精度 |
M: 精度, 表示总数据位数。 取值范围为(1~255)。
D: 标度, 表示小数位的位数。 取值范围为(1~30,且不能大于 M-2)。
需要注意的是: int类型设置宽度只是要不要填充空格和0的问题, 在float double中这个设置参数超过总位数会报错, 超过小数位限制舍弃
FLOAT 和 DOUBLE 在不指定精度时,默认会按照实际的精度(由计算机硬件和操作系统决定)。
xxxxxxxxxx71-- FLOAT 类型的取值范围如下:2有符号的取值范围:-3.402823466E+38~-1.175494351E-38。3无符号的取值范围:0 和 -1.175494351E-38~-3.402823466E+38。45-- DOUBLE 类型的取值范围如下:6有符号的取值范围:-1.7976931348623157E+308~-2.2250738585072014E-308。7无符号的取值范围:0 和 -2.2250738585072014E-308~-1.7976931348623157E+308。
| MySQL日期 | 字节 | 日期格式 | 表示范围 |
|---|---|---|---|
| YEAR | 1 | YYYY | 1901 ~ 2155 |
| TIME | 3 | HH:MM:SS | -838:59:59 ~ 838:59:59 |
| DATE | 3 | YYYY-MM-DD | 1000-01-01 ~ 9999-12-31 |
| DATETIME | 8 | YYYY-MM-DD HH:MM:SS | 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 |
| TIMESTAMP | 4 | YYYY-MM-DD HH:MM:SS | 1970-01-01 00:00:01 ~ 2038-01-19 03:14:07 |
year/YEAR范围: 1901~ 2155包含255个年份, 对应一个字节表示范围。
time/TIME范围: 11111111111111111111111(23位剩余一位符号位)--> 8388607(十进制)
8388607: 838(小时位) xx(描述分钟) xx(描述秒)。 (计算方式不用记)
timestamp/TIMESTAMP范围: (时间戳) (一般用于一些计时, 倒计时, 数据传输 ......) (秒数1)
1970年1月1日作为UNIX TIME的纪元时间(开始时间)。
xxxxxxxxxx111--2create table user(3id int,4name varchar(5),5height float(5, 2),6birthday datatime,7tag_time timestamp8)9--10insert into user4 values(1, 'zs', 188.01, '2000-11-12 55:30:12', '2000-01-01 00:00:00');11insert into user4 values(1, 'zs', 188.01, '2000-11-12 10:30:12', now());
| MySQL字符串 | 内存占用 | 说明 |
|---|---|---|
| CHAR(M) | (M * 单个字符占用字节) | 固定长度字符串 |
| VARCHAR(M) | L+1字节 or L+2字节 。 | 变长字符串 |
| TEXT(M) | L+2字节 。 L: 0~216 | 变长文本字符串 |
| LONGTEXT(M) | L+4字节 。 L: 0~232 | 变长大文本字符串 |
L: 存储字符的实际长度。
M: 列的指定长度。
CHAR (M不设置默认为1) 范围可以设置最大255 。
VARCHAR(M不设置会报错) 最大长度为 65,535字节
TEXT 最大长度为 65535字符
LONGTEXT 最大长度长度为 4294967295 字符。
1, 数据库中的char可以正常存储字符串: eg: "zs", "我爱学习" ....; (但是一般我们用到的char的时候, 更多是为了存储性别)
2, 创建表的时候, 如果使用char类型, 不加宽度/长度, 长度默认为1; 如果使用varchar不加长度/宽度, 创建的时候会报错, text/longtext同样建议指明长度(有些版本中不指明会报错)
3, 在数据库中, 只要是字符串, 都有长度限制, 在字符串列存储数据的时候, 不能超出既定的长度限制 (字符串的长度限制是一个严格限定).
4, 如果使用char类型(
定长字符串), 它是一个固定长度字符串: 如果我们常见char的时候指明的宽度为m, 每一个这个char列的数据, 最终开辟的内存空间为: 单个字符占用空间 * M; 和实际存储了几个字符无关5, 我们使用varchar这种
变长字符串存储数据的的时候, 字符串实际占用的内存空间和我们给varchar设置的宽度/长度没有任何关系, 只和这个varchar列实际存储的字符个数有关.
xxxxxxxxxx41SHOW TABLES; # 查看该数据库中所有表2SHOW CREATE TABLE <表名>; # 查看表的创建语句3DESCRIBE <表名>; # 查看表结构4DESC <表名>; # 查看表结构

xxxxxxxxxx291CREATE TABLE <表名> (2<列名1> <类型1> ,3[…] ,4<列名n> <类型n>5) [表选项] [分区选项];67eg1:8create table employee(9id int ,10name varchar(20),11gender char,12birthday date,13job varchar(20),14salary double(10,2)15)character set utf8 collate utf8_bin;16-- 不推荐专门给一个表设置编码格式(没什么用, 只会让一个数据库编码格式不统一)(建议不设编码格式: 表的编码格式遵从数据库设置的编码格式)1718eg2: 仅仅是个完善的写法示例, 一些写法完全没有必要(比如重复设置字符编码格式), 比如注释19CREATE TABLE employee1 (20id int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',21name varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '姓名',22gender varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '男' COMMENT '性别',23graduate_year year NULL DEFAULT NULL COMMENT '毕业时间',24birthday date NOT NULL COMMENT '生日',25job varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '职位名称',26salary double(10, 2) NULL DEFAULT 0.00 COMMENT '薪资',27create_time datetime NULL DEFAULT NULL COMMENT '信息创建时间',28PRIMARY KEY (id) USING BTREE29) ;

主键(PRIMARY KEY)又被称为''主键约束'',是 MySQL中使用非常频繁的约束。它有诸多作用(唯一标识, 查找效率...)。
注意1:
xxxxxxxxxx61-- 主键: 如果一个表中给某一列设置了主键, 那么这一列强制不能重复, 如果存储重复的主键会自动报错2-- 主键: 不允许是null, 存储null主键, 报错3-- 每个表只能定义一个主键。4-- 主键值必须唯一标识表中的每一行,且不能为 NULL,即表中不可能存在有相同主键值的两行数据。56ps: 如果用户没有定义主键,也没有定义索引,那么InnoDB引擎会在创建表的时候, 自动生成一个不可见的ROW_ID的列名的聚簇索引,该列是一个6字节的自增数值,随着插入而自增, 来起到主键的作用。主键分类:
xxxxxxxxxx281主键分为单字段主键和多字段联合主键2-- 单字段主键: 既将表中的一个字段设置主键; 通过 PRIMARY KEY 关键字来指定主键.3CREATE TABLE table_primary1(4id INT(11) PRIMARY KEY , -- 主键5name VARCHAR(25),6job VARCHAR(25),,7salary FLOAT8);9CREATE TABLE table_primary2(10id INT(11),11name VARCHAR(25),12job VARCHAR(25),13salary FLOAT,14PRIMARY KEY(id)15);1617-- 如果一个表表在创建的时候没有主键, 增加主键的sql18-- alter table 表名 add primary key (主键列);19alter table user add primary key (id);2021-- 联合主键: 复合主键(不建议)。这意味着id和name的组合在table_primary3表中表示主键。22CREATE TABLE table_primary3(23id INT(11),24name VARCHAR(25),25job VARCHAR(25),26salary FLOAT,27PRIMARY KEY(id, name)28);注意2: 唯一键: 仅了解
xxxxxxxxxx131// 唯一键(Unique Key)是数据库中的一个约束,用于确保表中的所有记录在指定的一列或列组合上是唯一的。即:组合唯一。2// 与主键不同的是,唯一键允许有空值(NULL)。3// 表中可以有多个唯一键约束。4// 在某些情况下,唯一键也可以作为主键的一部分。56CREATE TABLE table_primary3(7id INT(11),8name VARCHAR(25),9job VARCHAR(25),10salary FLOAT,11primary KEY(id),12unique key (job, salary)13);注意3: 自增问题 AUTO_INCREMENT
xxxxxxxxxx171CREATE TABLE table_primary1(2id INT(11) PRIMARY KEY AUTO_INCREMENT , -- 主键3name VARCHAR(25),4job VARCHAR(25),,5salary FLOAT6);7-- AUTO_INCREMENT 的初始值是 1,数据增加一条,该字段值自动加 1。8-- 建议: 一个表中应该只有一个字段使用 AUTO_INCREMENT 约束,且该字段一般位为作为索引/主键的id字段。9-- AUTO_INCREMENT 字段应该要设置 NOT NULL 属性。10-- AUTO_INCREMENT 约束的字段只能是整数类型。11-- AUTO_INCREMENT 上限为所约束的类型的数值上限。1213-- 如果一个表表在创建的时候某些列没有自增, 设置自增14-- alter table 表名 modify 列名 int auto_increment;15alter table user modify id int auto_increment;1617
表的修改操作:不允许在工作直接修改表
xxxxxxxxxx321ALTER TABLE <表名> ADD COLUMN <列名> <类型>; # 添加列2ALTER TABLE <表名> ADD <新字段名> <数据类型> FIRST; # 头位置添加列3ALTER TABLE <表名> ADD <新字段名> <数据类型> AFTER <已经存在的字段名>; # 指定位置添加列4ALTER TABLE <表名> MODIFY COLUMN <列名> <类型>; # 修改某列类型5ALTER TABLE <表名> CHANGE COLUMN <旧列名> <新列名> <新列类型>; # 修改列及类型6ALTER TABLE <表名> ALTER COLUMN <列名> SET DEFAULT <默认值>; # 修改某列默认值7ALTER TABLE <表名> ALTER COLUMN <列名> DROP DEFAULT; # 删除某列默认值8ALTER TABLE <表名> DROP COLUMN <列名>; # 删除某列9ALTER TABLE <表名> RENAME TO <新表名>; # 修改表名10ALTER TABLE <表名> RENAME AS <新表名>; # 修改表名11ALTER TABLE <表名> RENAME <新表名>; # 修改表名12RENAME TABLE <表名> TO <新表名>; # 修改表名13ALTER TABLE <表名> CHARACTER SET <字符集名>; # 修改表字符集14ALTER TABLE <表名> COLLATE <校对规则名>; # 修改表排序规则15ALTER TABLE <表名> [DEFAULT] CHARACTER SET <字符集名> [DEFAULT] COLLATE <校对规则名>;1617eg:18alter table employee add column height float(5,2);19alter table employee add column height float(5,2) first;20alter table employee add column height float(5,2) after name;21alter table employee modify column age float(5, 0);22alter table employee change column age age1 float(5, 0);23alter table employee alter column age set default 20;24alter table employee alter column age drop default;25alter table employee drop column height;26alter table employee rename to aaa;27alter table aaa rename as employee;28alter table employee rename aaa;29rename table aaa to employee;30alter table employee character set utf8mb4;31alter table employee collate utf8mb4_unicode_ci;32alter table employee character set gbk collate gbk_bin;

不允许在工作直接删除表
更不建议: 任何数据都是有意义的
xxxxxxxxxx41DROP TABLE [IF EXISTS] 表名1 [ ,表名2, 表名3 ...]23eg:4drop table if exists table_a, table_b, table_c;

xxxxxxxxxx91INSERT INTO <表名> [ (<列名1>, … <列名n> )] VALUES (值1, … 值n), … (值1, … 值n);2INSERT INTO <表名> SET <列名1>=<值1>, … <列名n>=<值n>;34eg:5insert into employee1 (id, name, gender, graduate_year, birthday, job, salary, create_time) values(1, 'zs', '男', 2022, '1999-01-01', '程序员', 100.2, '2022-09-09 16:51:49');67insert into employee1 (id, name, gender, graduate_year, birthday, job, salary, create_time) values(1, 'zs', '男', 2022, '1999-01-01', '程序员', 100.2, '2022-09-09 16:51:49'),(2, 'ls', '男', 2020, '1997-01-01', '程序员', 10000.2, '2022-09-09 16:51:50');89insert into employee1 set id=4, name='ls', gender='男', graduate_year=2022, birthday='1999-01-01', job='程序员', salary=220.05, create_time='2022-09-09 16:55:49';
如果values中包含数据和表列数据一一对应(无省略), 那么在插入语句中可以省略表名之后表列的一一列举。eg: insert into 表名 values (值1, … 值n);
values中的内容应该要与对应插入字段对应。
数据中字符串和日期应该包含在引号中。


xxxxxxxxxx81SELECT * FROM <表名字> [ WHERE <条件> ];2SELECT <列名1>, …<列名n> FROM <表名字> [ WHERE <条件> ];34eg:5select * from employee1;6select * from employee1 where id<20;7select name from employee1 where id>1;8select name, job, salary from employee1 where salary> 200;
查询的结果是一个新的临时表。
在MySQL中
select * from 表名 where 1;表示查询所有数据。

xxxxxxxxxx41UPDATE <表名> SET 列1=值1 [, 列2=值2 … ] [WHERE <条件> ]23eg:4update employee1 set job='老程序员' where salary >10000;
注意如果没有where子句指明条件, 那么修改就是对所有行的修改。
修改一行数据的多个列值时,SET 子句的每个值用逗号分开即可。

在工作中删除数据, 一般是逻辑删除
xxxxxxxxxx51DELETE FROM <表名> [WHERE <条件>]23ag:4delete from employee;5delete from employee where id=4;
如果没有where以及条件, 默认删除是表中所有数据。
delete不能单独只删除某一列数据, delete删除数据的最小单元为行。
delete语句仅删除数据记录, 删除的不是表, 如果要删除表需要使用drop table语句。

数据基础
xxxxxxxxxx81CREATE TABLE `students` (2`id` int(11) PRIMARY KEY AUTO_INCREMENT,3`name` varchar(255) ,4`class` varchar(255) ,5`chinese` float ,6`english` float ,7`math` float8) ;xxxxxxxxxx131INSERT INTO students (id, name, class, chinese, english, math) VALUES (1, '武松', '一班', 70, 90, 60);2INSERT INTO students VALUES (2, '林冲', '一班', 70, 90, 90);3INSERT INTO students VALUES (3, '松江', '一班', 90, 90, 20);4INSERT INTO students VALUES (4, '贾琏', '二班', 60, 60, 60);5INSERT INTO students VALUES (5, '贾宝玉', '二班', 95, 80, 5);6INSERT INTO students VALUES (6, '贾环', '二班', 25, 25, 5);7INSERT INTO students VALUES (7, '曹操', '三班', 90, 90, 90);8INSERT INTO students VALUES (8, '曹丕', '三班', 90, 80, 80);9INSERT INTO students VALUES (9, '曹植', '三班', 98, 90, 80);10INSERT INTO students VALUES (10, '刘备', '三班', 95, 90, 80);11INSERT INTO students VALUES (11, '诸葛亮', '三班', 98, 95, 95);12INSERT INTO students VALUES (12, '孙权', '三班', 80, 90, 80);13INSERT INTO students (id) VALUES (13);
xxxxxxxxxx41SELECT <查询内容|列等> FROM <表名字> WHERE <查询条件|表达式>23eg:4select id, name from students where id > 10;使用 WHERE 关键字并指定
查询/删除/修改的条件, 让操作在满足条件的情况下执行 数据操作.
在构建Where的
条件的过程中, 我们可能需要了解到一些重要的SQL运算符1, 算术运算符: 可以用在条件中, 也可以用在结果集中
运算符 作用 + 加 - 减 * 乘 / 除 % 取余 xxxxxxxxxx71eg:2select * from students where (chinese + english + math) < 180;3select * from students where (chinese - math) > 30;4select *, (chinese*0.5 + english*0.1 + math *0.4) from students;5select *, (chinese*0.5 + english*0.1 + math *0.4) from students where (chinese*0.5 + english*0.1 + math *0.4) <= 60 ;6select *, (chinese + english + math) /180 from students ;7select *, (chinese + english + math) /180 from students where (chinese + english + math) /180 < 1.2;2, 比较和逻辑运算符
运算符 作用 运算符 作用 = 等于 <=> 等于(可比较null) != 不等于 <> 不等于 < 小于 > 大于 <= 小于等于 >= 大于等于 is null 是否为null is not null 是否不为null between and 在闭区间内 in 是否在列表内 not in 不在列表内 like 通配符匹配(%:通配, _占位) and 与 && 与 or 或 || 或 xxxxxxxxxx201select * from students where chinese = 60;2select * from students where chinese <=> 60;3select * from students where chinese != 60;4select * from students where chinese <=> 60;5select * from students where chinese < 60;6select * from students where chinese > 90;7select * from students where chinese <= 60;8select * from students where chinese >= 90;9select * from students where chinese is null;10select * from students where chinese is not null;11select * from students where chinese between 60 and 90;12select * from students where chinese in (60 , 90);13select * from students where chinese not in (60 , 90);14select * from students where name = '曹操';15select * from students where name like '曹操';16select * from students where name like '曹%';17select * from students where name like '曹%' and chinese = 90;18select * from students where name like '曹%' && chinese = 90;19select * from students where name like '曹%' or chinese = 90;20select * from students where name like '曹%' || chinese = 90;
使用
DISTINCT对数据表中一个或多个字段重复的数据进行过滤,重复的数据只返回其一条数据给用户.xxxxxxxxxx51SELECT DISTINCT <字段名> FROM <表名>;23eg:4select distinct chinese from students;5select distinct chinese, english from students;注意:
xxxxxxxxxx31-- DISTINCT 只能在SELECT语句中使用。 (对结果进行去重)2-- 当对一个或多个字段去重时,DISTINCT 要写在所有字段的最前面。3-- 如果 DISTINCT 对多个字段去重时,只有多个字段组合起来完全是一样的情况下才会被去重。
使用
LIMIT对数据表查询结果集大小进行限定.xxxxxxxxxx81SELECT <查询内容|列等> FROM <表名字> LIMIT 记录数目2SELECT <查询内容|列等> FROM <表名字> LIMIT 初始位置,记录数目;3SELECT <查询内容|列等> FROM <表名字> LIMIT 记录数目 OFFSET 初始位置;45eg:6select * from students limit 3;7select * from students limit 4, 3;8select * from students limit 3 offset 4;LIMIT 记录数目: 从第一条开始, 限定记录数目
LIMIT 初始位置,记录数目: 从起始位置开始, 限定记录数目
LIMIT 记录数目 OFFSET 初始位置: 从起始位置开始, 限定记录数目
注意: 数据(默认下标从0开始)
AS关键字用来为表和字段指定别名.xxxxxxxxxx111<内容> AS <别名>23eg:4select name from students;5select * from students as s where s.chinese < 60;6select s.name from students as s ;7select s.name from students as s where s.chinese < 60;8select name as username from students;9select * from students;10select *, (chinese + english + math) from students;11select *, (chinese + english + math) as sum from students;
ORDER BY对查询数据结果集进行排序.xxxxxxxxxx81SELECT <查询内容|列等> FROM <表名字> ORDER BY <字段名> [ASC|DESC];23eg:4select * from students order by chinese;5select * from students order by chinese asc;6select * from students order by chinese desc;7select * from students order by chinese, english;8select * from students order by chinese desc, english desc, math desc;不加排序模式: 升序排序.
ASC: 升序排序.
DESC: 降序排序.
注意: 如上查询, 当我们进行多字段排序的时候, 会先满足第一个列的排序要求, 如果第一列一致的话, 再按照第二列进行排序, 以此类推.
使用 GROUP BY 关键字,对数据进行分组
xxxxxxxxxx91SELECT <查询内容|列等> FROM <表名字> GROUP BY <字段名...>23eg:4select class, group_concat(name), group_concat(chinese) from students group by class;5select class, group_concat(name) from students where chinese > 90 group by class;67select class, group_concat(name), avg(chinese) from students group by class;8select class, group_concat(name) from students group by class having count(*) > 3;9select class, group_concat(name), avg(chinese) from students group by class having avg(chinese) > 60;GROUP_CONCAT()函数会把每个分组的字段值都显示出来.
HAVING 可以让我们对分组后的各组数据过滤。(一般和分组+聚合函数配合使用)
聚合函数一般用来计算列相关的指定值.
通常和分组一起使用
函数 作用 函数 作用 COUNT 计数 SUM 和 AVG 平均值 MAX 最大值 MIN 最小值
COUNT: 计数
xxxxxxxxxx71SELECT <查询内容|列等> , COUNT <列|*> FROM <表名字> GROUP BY HAVING COUNT <表达式|条件>23eg:4select count(*) from students5select count(name) from students6select class, group_concat(name), count(*) from students group by class;7select class, group_concat(name), count(*) from students group by class having count(*) > 2;COUNT(*): 表示表中总行数
COUNT(列): 计算除了列值为NULL以外的总行数
SUM: 求和
xxxxxxxxxx101SELECT <查询内容|列等> , SUM<列> FROM <表名字> GROUP BY HAVING SUM<表达式|条件>23eg:4select sum(chinese) from students;5select sum(chinese), sum(english), sum(math) from students;6select class, group_concat(name), sum(chinese) from students group by class;7select class, group_concat(name), sum(chinese) from students group by class having sum(chinese)>200;8select class, group_concat(name), sum(chinese), sum(math) from students group by class;9select class, group_concat(name), sum(chinese), sum(math) from students group by class having sum(chinese)>200 and sum(math) > 200;10
AVG: 平均值
xxxxxxxxxx91SELECT <查询内容|列等> , AVG<列> FROM <表名字> GROUP BY HAVING AVG<表达式|条件>23eg:4select avg(chinese) from students;5select avg(chinese), avg(english), avg(math) from students;6select class, group_concat(name), avg(chinese) from students group by class;7select class, group_concat(name), avg(chinese) from students group by class having avg(chinese)>=60;8select class, group_concat(name), avg(chinese), avg(math) from students group by class;9select class, group_concat(name), avg(chinese), avg(math) from students group by class having avg(chinese)>=60 and avg(math) >=60;
MAX: 最大值
xxxxxxxxxx91SELECT <查询内容|列等> , MAX<列> FROM <表名字> GROUP BY HAVING MAX<表达式|条件>23eg:4select max(chinese) from students;5select max(chinese), max(english), max(math) from students;6select class, group_concat(name), max(chinese) from students group by class;7select class, group_concat(name), max(chinese) from students group by class having max(chinese)>90;8select class, group_concat(name), max(chinese), max(math) from students group by class;9select class, group_concat(name), max(chinese), max(math) from students group by class having max(chinese)>=90 and max(math) >=70;
MIN: 最小值
xxxxxxxxxx91SELECT <查询内容|列等> , MIN<列> FROM <表名字> GROUP BY HAVING MIN<表达式|条件>23eg:4select min(chinese) from students;5select min(chinese), min(english), max(math) from students;6select class, group_concat(name), min(chinese) from students group by class;7select class, group_concat(name), min(chinese) from students group by class having min(chinese)>60;8select class, group_concat(name), min(chinese), min(math) from students group by class;9select class, group_concat(name), min(chinese), min(math) from students group by class having min(chinese)>=60 and min(math) >=60;
xxxxxxxxxx111(5) SELECT column_name, ...2(1) FROM table_name, ...3(2) [WHERE ...]4(3) [GROUP BY ...]5(4) [HAVING ...]6(6) [ORDER BY ...];7(7) [Limit ...]89-- 计算每个班级中语文成绩大于60的同学的平均数学成绩, 获得平均数学成绩大于等于40的班级中平均语文成绩最高的那个班级的平均语文和数学成绩10eg:11select class, group_concat(name), avg(chinese) as chineseA, avg(math) from students where chinese >= 60 group by class having avg(math)>=40 order by chineseA desc limit 0, 1;
小括号中的数字代表执行顺序
having和select的执行顺序收到优化器的影响,可能会改变执行顺序
为了在
实际工程环境中更好的使用和维护数据库数据, 在我们设计和使用数据库的库/表/数据的时候, 一般要遵循数据完整性规则;数据完整保证在数据库设计和数据存储过程中, 对数据的存储/处理是做到尽可能正确; 做到降低用户在实际使用的时候出错的可能性, 尽可能提高数据库的使用效率.
ps: 所谓数据完整性: 是在数据库中表和数据的设计的时候定制的一些约定俗成的参考规范. 是站在组织数据的角度, 目的是希望在数据库中数据存储更规整,以及希望操作数据的时候效率更高
而
数据完整性又包含: 实体完整性; 域完整性; 参照完整性
保证
表中的每一行数据都是表中唯一的实体.(即:一个表中每一条数据都应该是唯一的)实体完整性是为了保证表中
数据唯一, 实体完全可由主键实现(通过一个主键的设置, 保证一个表中每一条信息都是唯一的).xxxxxxxxxx81CREATE TABLE `students` (2`id` int(11) PRIMARY KEY AUTO_INCREMENT,3`name` varchar(255) ,4`class` varchar(255) ,5`chinese` float ,6`english` float ,7`math` float8) ;
域完整性表示保证表中数据的字段的取值在有效范围之内或者符合特定的数据类型约束1, 含义: 某一列的数据存储的类型要设计合适 (
float,varchar,NULL,NOT NULL...)2, 在某一列存储数据的时候, 存储的数据的内容, 应该要符合对这个列的类型以及大小限定
xxxxxxxxxx81CREATE TABLE `students` (2`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,3`name` varchar(10) NOT NULL DEFAULT "张飞",4`class` varchar(5) NULL DEFAULT NULL,5`chinese` float NOT NULL,6`english` float NOT NULL,7`math` float NOT NULL8);
参照完整性用于确保相关联的表间的数据应该要保持一致.避免因为一个表的数据/记录修改, 造成另一个表的内容变为无效的值. 一般来讲, 参照完整性是通过外键和主键来维护的.
外键是参照完整性的一种强有力的维护手段.
参照完整性 != 外键
主键的设置和取消: (了解)
xxxxxxxxxx381--方式一: 在创建表的时候设置外键2CREATE TABLE `class` (3`id` int NOT NULL PRIMARY KEY,4`name` varchar(255) NULL5);6CREATE TABLE `student` (7`id` int NOT NULL PRIMARY KEY,8`name` varchar(255) NULL,9`class_id` int ,10CONSTRAINT `foreign_key_name` FOREIGN KEY (class_id) REFERENCES `class`(`id`)11);12--方式二: 表创建完毕, 对表设置外键13CREATE TABLE `class` (14`id` int NOT NULL PRIMARY KEY,15`name` varchar(255) NULL16);17CREATE TABLE `student` (18`id` int NOT NULL PRIMARY KEY,19`name` varchar(255) NULL,20`class_id` int21);2223ALTER TABLE `student` ADD CONSTRAINT `foreign_key_name` FOREIGN KEY (`class_id`) REFERENCES `class` (`id`);2425--方式三: 表创建完毕, 添加新的字段列, 并且设置为外键26CREATE TABLE `class` (27`id` int NOT NULL PRIMARY KEY,28`name` varchar(255) NULL29);30CREATE TABLE `student` (31`id` int NOT NULL PRIMARY KEY,32`name` varchar(255) NULL33);34alter table `student` add column `class_id` int null after `name`,35add constraint `foreign_key_name` foreign key (`class_id`) references `class` (`id`);3637-- 删除外键38ALTER TABLE `student` DROP FOREIGN KEY `foreign_key_name`;外键优缺点: 重要
xxxxxxxxxx71优点:2// 能够限制数据的增加、删除或者是修改操作,来保证数据的一致性。3缺点:4// 在插入/修改子表(student)的数据的时候,需要去父表(class)中找对应的数据5// 在删除/修改父表(class)的数据的时候,需要去检查子表(student)中是否有对应的数据6// 有了外键之后,影响了增加、删除、修改的性能7// 使用起来也不方便在公司中是否使用外键呢: 重要
xxxxxxxxxx51看具体公司内部的情况是否使用外键2// 假如公司表中的数据量不大(外键对效率的影响比较小,甚至可以忽略),可以考虑使用外键3// 假如公司数据库表中的数据很多,(外键对于效率的影响就会很大),不应该使用外键4// 人为使用习惯(内心OS)5// ...
数据基础
xxxxxxxxxx401-- 班级2CREATE TABLE `class` (3`id` int(11) NOT NULL,4`class_name` varchar(255) ,5PRIMARY KEY (`id`)6);7-- 成绩8CREATE TABLE `score` (9`id` int(11) NOT NULL AUTO_INCREMENT,10`student_id` int(11) ,11`class_id` int(11),12`chinese` float ,13`english` float ,14`math` float ,15PRIMARY KEY (`id`)16);17-- 学生信息18CREATE TABLE `student` (19`id` int(11) NOT NULL,20`student_name` varchar(255),21`nick_name` varchar(255) ,22`mobile` varchar(255) ,23`era` varchar(255) ,24`motto` varchar(255),25PRIMARY KEY (`id`)26);27-- 剧本28CREATE TABLE `script` (29`id` int(11) NOT NULL,30`play_name` varchar(255),31`play_ location` varchar(255) ,32PRIMARY KEY (`id`)33);34-- 演出表35CREATE TABLE `show` (36`id` int(11) NOT NULL,37`student_id` int(11),38`script_id` int(11),39PRIMARY KEY (`id`)40);xxxxxxxxxx591-- ----------------------------2INSERT INTO `class` VALUES (1, '一班');3INSERT INTO `class` VALUES (2, '二班');4INSERT INTO `class` VALUES (3, '三班');5INSERT INTO `class` VALUES (4, '四班');6INSERT INTO `class` VALUES (5, '五班');7-- ----------------------------8INSERT INTO `score` VALUES (1, 1, 1, 70, 90, 60);9INSERT INTO `score` VALUES (2, 2, 1, 70, 90, 90);10INSERT INTO `score` VALUES (3, 3, 1, 90, 90, 20);11INSERT INTO `score` VALUES (4, 4, 2, 60, 60, 60);12INSERT INTO `score` VALUES (5, 5, 2, 95, 80, 5);13INSERT INTO `score` VALUES (6, 6, 2, 25, 25, 5);14INSERT INTO `score` VALUES (7, 7, 3, 90, 90, 90);15INSERT INTO `score` VALUES (8, 8, 3, 90, 80, 80);16INSERT INTO `score` VALUES (9, 9, 3, 98, 90, 80);17INSERT INTO `score` VALUES (10, 10, 3, 95, 90, 80);18INSERT INTO `score` VALUES (11, 11, 3, 98, 95, 95);19INSERT INTO `score` VALUES (12, 12, 3, 80, 90, 80);20-- ----------------------------21INSERT INTO `script` VALUES (1, '三打祝家庄', '祝家庄');22INSERT INTO `script` VALUES (2, '梁山聚义', '梁山');23INSERT INTO `script` VALUES (3, '壮士落幕', '六和寺');24INSERT INTO `script` VALUES (4, '赤壁之战', '赤壁');25INSERT INTO `script` VALUES (5, '七步诗事件', '洛阳');26INSERT INTO `script` VALUES (6, '白帝城托孤', '白帝城');27INSERT INTO `script` VALUES (7, '煮酒论英雄', '许昌');28-- ----------------------------29INSERT INTO `show` VALUES (1, 1, 1);30INSERT INTO `show` VALUES (2, 2, 1);31INSERT INTO `show` VALUES (3, 3, 1);32INSERT INTO `show` VALUES (4, 1, 2);33INSERT INTO `show` VALUES (5, 2, 2);34INSERT INTO `show` VALUES (6, 3, 2);35INSERT INTO `show` VALUES (7, 1, 3);36INSERT INTO `show` VALUES (8, 2, 3);37INSERT INTO `show` VALUES (9, 7, 4);38INSERT INTO `show` VALUES (10, 10, 4);39INSERT INTO `show` VALUES (11, 11, 4);40INSERT INTO `show` VALUES (12, 12, 4);41INSERT INTO `show` VALUES (13, 8, 5);42INSERT INTO `show` VALUES (14, 9, 5);43INSERT INTO `show` VALUES (15, 11, 6);44INSERT INTO `show` VALUES (16, 12, 6);45INSERT INTO `show` VALUES (17, 7, 7);46INSERT INTO `show` VALUES (18, 11, 7);47-- ----------------------------48INSERT INTO `student` VALUES (1, '武松', '行者', '13440996665', '宋朝', '别胡说!难道不付你钱!再筛三碗来!');49INSERT INTO `student` VALUES (2, '林冲', '豹子头', '17383945041', '宋朝', '无');50INSERT INTO `student` VALUES (3, '宋江', '及时雨', '15671722818', '宋朝', '他日若遂凌云志,敢笑黄巢不丈夫');51INSERT INTO `student` VALUES (4, '贾琏', '琏二爷', '19931477852', '清朝', '无');52INSERT INTO `student` VALUES (5, '贾宝玉', '怡红公子', '13456229050', '清朝', '我要这玉又何用');53INSERT INTO `student` VALUES (6, '贾环', '孽障', '18900141462', '清朝', '无');54INSERT INTO `student` VALUES (7, '曹操', '阿满', '17273083171', '三国', '宁我负人,毋人负我');55INSERT INTO `student` VALUES (8, '曹丕', '子桓', '17180453185', '三国', '无');56INSERT INTO `student` VALUES (9, '曹植', '陈思王', '19818008917', '三国', '无');57INSERT INTO `student` VALUES (10, '孙权', '孙十万', '15638204123', '三国', '无');58INSERT INTO `student` VALUES (11, '刘备', '刘皇叔', '15638204378', '三国', '惟贤惟德,能服行人');59INSERT INTO `student` VALUES (12, '诸葛亮', '诸葛武侯,卧龙', '15119511196', '三国', '非淡泊无以明志,非宁静无以致远');
指两个表(或多个表之间)的数据存在一一对应的关系。
xxxxxxxxxx31eg:2// 用户和用户详情3// 商品和商品详情
指两个表(或多个表之间)的数据,存在表A中的一条数据对应表B中的多条数据,表B中的一条数据对应表A中的一条数据.
xxxxxxxxxx31eg:2// 用户和订单3// 班级和学生
存在两个表表A和表B,存在表A中的一条数据对应表B中的多条数据,表B中的一条数据对应表A中的多条数据。
xxxxxxxxxx51eg:2// 订单和商品3一个产品中可能有多个订单, 一个订单中可能买了多个商品4// 剧本和演员5一个演员可能出演了多个剧本, 一个剧本中可能包含多个演员
面试有可能问道
和数据完整性不同: 数据库的设计范式更偏向于表设计的维度来看待数据的存储. 其存在的目的也是为了, 在维护或者操作数据库中数据: 1, 希望在数据库中数据存储更规整 2, 希望操作数据的时候效率更高
在设计表的时候, 应该每列保持原子性。 如果数据库中的所有字段都是不可分割的原子值,则说明该数据库满足第一范式,比如:地址。
第一范式:我们在设计表的时候,应该考虑之后业务的变化,来
尽量让每一列的数据保持原子性。
数据的唯一性。 要求表中数据有唯一标识,不存在部分依赖
eg: 通过主键来唯一标识一个用户(满足唯一性)
注意: 通过name+nickname+province+city+county组合标识一个用户(不满足唯一性)
字段不要冗余。(消除表中非主键字段间的依赖: 即:要求每个非主键字段只依赖于主键,而不依赖于其他非主键字段)
如: 如下昵称
students表中存储了昵称
students_detail表中也存储了昵称
查询的结果是一个新的临时表。
数据基础
xxxxxxxxxx61-- 装备表2CREATE TABLE `equip` (3`id` int(11) NOT NULL PRIMARY KEY,4`student_id` int(11) NULL DEFAULT NULL,5`equip_name` varchar(255) NULL DEFAULT NULL6) ;xxxxxxxxxx101INSERT INTO `equip` VALUES (1, 1, '行者套账');2INSERT INTO `equip` VALUES (2, 2, '丈八蛇矛');3INSERT INTO `equip` VALUES (3, 5, '通灵宝玉');4INSERT INTO `equip` VALUES (4, 7, '七星刀');5INSERT INTO `equip` VALUES (5, 7, '绝影马');6INSERT INTO `equip` VALUES (6, 7, '爪黄飞电马');7INSERT INTO `equip` VALUES (7, 7, '倚天剑');8INSERT INTO `equip` VALUES (8, 7, '青釭剑');9INSERT INTO `equip` VALUES (9, 11, '的卢马');10INSERT INTO `equip` VALUES (10, 11, '双股剑');
xxxxxxxxxx81select2sd.student_name, c.class_name, s.chinese , group_concat(e.equip_name)3from student sd4inner join score s on sd.id = s.student_id5inner join class c on c.id = s.class_id6inner join equip e on e.student_id = sd.id7where sd.student_name = "曹操"8group by sd.student_name, c.class_name, s.chinese ;
交叉连接其实就是求多个表的笛卡尔积。xxxxxxxxxx81SELECT <字段名> FROM <表1> CROSS JOIN <表2> [WHERE子句]234eg:5select * from student cross join equip;6select * from student cross join equip where student.id = equip.student_id;7-- 两个表的笛卡尔积,返回结果数量就是两个表的数据行相乘。8-- 如果每个表有1000行,那么返回结果的数量就有1000×1000=1000000行。仅
交叉连接的结果没有太多实际的使用意义。
自然连接: 没什么用xxxxxxxxxx51-- 自然连接是基于两个表之间的共同列来自动匹配并组合数据。2-- 自然连接将结果集限制为只包括两个表中`具有相同值`的列(并且在结果集中把重复的列去掉)。在使用自然连接时,不需要指定连接条件,而是根据两个表中具有相同名称和数据类型的列进行匹配。 (注意: 有些数据库不支持自然连接, 比如SQLServer )34eg:5select * from student natural join class
内连接: 比较常用xxxxxxxxxx71SELECT <字段名> FROM <表1> INNER JOIN <表2> [ON子句]23eg:4-- 显示内连接5select * from student inner join equip on student.id = equip.student_id;6-- 隐式内连接: 不建议这样写(这是早期的sql语法中内连接的一种写法)7select * from student , equip where student.id = equip.student_id;
外连接xxxxxxxxxx111SELECT <字段名> FROM <表1> LEFT OUTER JOIN <表2> <ON子句>2SELECT <字段名> FROM <表1> RIGHT OUTER JOIN <表2> <ON子句>34eg:5select * from student left outer join equip on student.id = equip.student_id;6select * from student right outer join equip on student.id = equip.student_id;7select * from equip right outer join student on student.id = equip.student_id;8select * from equip left outer join student on student.id = equip.student_id;9-- outer可省略: 工作中多数人省略了outer10select * from student left join equip on student.id = equip.student_id;11select * from student right join equip on student.id = equip.student_id;
注: 主副表的问题
假设A和B表进行连接,AB两张表一个表示主表,另一个是副表; 查询数据的时候, 以主表中的数据为基准,匹配副表对应的数据; 当副表中的数据没有能和主表对应数据相互匹配的数据,副表匹配位置自动填充null。
自连接xxxxxxxxxx41-- 自连接是指在同一个表中,使用不同的别名将它们连接到一起。23eg:4select t1.* from score t1,score t2 where t2.id = 1 and t1.chinese < t2.chinese
子查询也叫嵌套查询.( 在某个操作中(删除/修改/查找), 用到了另外一个查询的结果. )
是指在WHERE子句或FROM子句中又嵌入SELECT查询语句.
xxxxxxxxxx101SELECT <字段名> FROM <表|子查询> WHERE <IN| NOT IN | EXISTS | NOT EXISTS > <子查询>23eg:4select * from student where id in (select student_id from equip);5select * from student where id not in (select student_id from equip where student_id != "");67select * from student where exists (select * from equip where student_id = 11);8select * from student where not exists (select * from equip where student_id = 11);9select * from student where exists (select * from equip where student_id = 11) and id = 5;10-- 在MySQL每次查询数据的结果集都是一个新的临时表。
联合查询合并两条查询语句的查询结果.
联合查询去掉两条查询语句中的重复数据行,然后返合并后没有重复数据行的查询结果。xxxxxxxxxx41SELECT <字段名> FROM <表> UNION SELECT <字段名> FROM <表>23eg:4select * from score where chinese >= 90 union select * from score where math >= 90;
通过命令行操作
xxxxxxxxxx101-- 数据库备份:cmd命令下2mysqldump -u root -p 数据库名称>文件名.sql34-- 数据库恢复:5-- 1. 创建数据库并选择该数据库6create database dbName;7use dbName;8-- 2. 恢复数据9source 文件名.sql10备份:
恢复:
以Navicat为例
备份:
导入:
xxxxxxxxxx2831/*2create table user2(3id int,4name varchar(10),5age int,6height float(5, 2)7);8*/9select * from user2;1011select * from user3;1213select * from user1;1415insert into user1 values(2, "zs", "男", "2000-10-01", 177.55);1617delete from user1 ;1819update user1 set delete_tag = 1 where id = 1;2021select * from user1 where delete_tag = 0;222324CREATE TABLE `students` (25`id` int(11) PRIMARY KEY AUTO_INCREMENT,26`name` varchar(255) ,27`class` varchar(255) ,28`chinese` float ,29`english` float ,30`math` float31) ;3233INSERT INTO students (id, name, class, chinese, english, math) VALUES (1, '武松', '一班', 70, 90, 60);34INSERT INTO students VALUES (2, '林冲', '一班', 70, 90, 90);35INSERT INTO students VALUES (3, '松江', '一班', 90, 90, 20);36INSERT INTO students VALUES (4, '贾琏', '二班', 60, 60, 60);37INSERT INTO students VALUES (5, '贾宝玉', '二班', 95, 80, 5);38INSERT INTO students VALUES (6, '贾环', '二班', 25, 25, 5);39INSERT INTO students VALUES (7, '曹操', '三班', 90, 90, 90);40INSERT INTO students VALUES (8, '曹丕', '三班', 90, 80, 80);41INSERT INTO students VALUES (9, '曹植', '三班', 98, 90, 80);42INSERT INTO students VALUES (10, '刘备', '三班', 95, 90, 80);43INSERT INTO students VALUES (11, '诸葛亮', '三班', 98, 95, 95);44INSERT INTO students VALUES (12, '孙权', '三班', 80, 90, 80);45INSERT INTO students (id) VALUES (13);4647select * from students;4849-- 查询一班的同学50select * from students where class = "一班" ;5152-- 我们可以把算数运算符用在条件中53-- 我们可以把算数运算符用在查询结果中5455-- 查找班级所有同学的, 姓名和总成绩56select name, chinese, english, math from students;57select name, chinese + english + math from students;5859-- 数学的偏科情况60select name, math - chinese from students;6162-- 每个人的总绩点:63select name, (math-60)/10 +(english-60)/10 + (math-60)/10 from students;64select name, (math-60)*0.1 +(english-60)*0.1 + (math-60)*0.1 from students;6566-- 数学成绩及格的同学67select * from students where math >= 60;68-- 总成绩及格的同学69select * from students where math+english+chinese >= 180;7071update students set name="宋江" where id =3;7273select * from students where id = 10;74select * from students where id <=> 10;7576select * from students where name = NULL;77select * from students where name <=> NULL;78select * from students where name is null;79select * from students where name is not null;8081-- 查询除了一班同学以外的同学82select * from students where class = "一班";83select * from students where class != "一班";8485-- 查询数学成绩不及格的同学信息86select * from students where math < 60;87-- 查询数学成绩大于90分的同学信息88select * from students where math >= 90;8990-- 查询数学成绩小于等于60分同学的信息91select * from students where math <= 60;9293select * from students where name is null;9495delete from students where name is null;9697-- 查询数学成绩在 60 到 90 分的同学98select * from students where math between 60 and 90;99100-- 查询数学成绩 是 5分 和 90分 以及 95分 的同学101select * from students where math in (5, 90, 95);102103-- 查询数学成绩 不是 5分 和 不是90分 以及 不是95分 的同学104select * from students where math not in (5, 90, 95);105106-- 查询学生信息: 数学成绩 不及格 并且 英语也不及格107select * from students where math <60 and english < 60;108select * from students where math <60 && english < 60;109110-- 查询学生信息: 数学成绩 不及格 或者 语文成绩高于90111select * from students where math <60 or chinese > 90;112113-- like114select * from students where class = "一班";115select * from students where class like "一班";116117-- like : 可以使用通配符: %118-- 查询姓曹的同学的信息: 模糊查询119select * from students where name like "%曹%";120select * from students where name like "曹__";121122123-- 查询所有同学的数学成绩124select math from students;125-- 查询所有同学中, 有哪些数学成绩126select distinct math from students;127128129-- 查询所有同学的数学成绩 和 英语成绩130select math, english from students;131132select distinct math, english from students;133134135-- 得到按照数学成绩排序的: 姓名, 数学成绩136select name, math from students;137select name, math from students order by math;138139select name, math from students order by math desc;140141-- 把三班同学, 按照数学成绩排序142select * from students where class="三班" order by math desc143144145-- 查询数学成绩最高的3个同学的信息146select name, math from students order by math desc;147148select name, math from students order by math desc limit 3;149150-- 查询数学成绩最高的3名-5名同学的信息151select name, math from students order by math desc limit 2, 3;152select name, math from students order by math desc limit 3 offset 2;153154-- limit也允许单独使用 (一般是配合排序使用)155select name, math from students limit 3 offset 2;156157158-- 查询所有同学姓名, 班级, 总成绩159select name, class, chinese+math+english from students;160161-- 查询所有同学姓名, 班级, 总成绩, 并且以总成绩排序162select163name as y, class as z, chinese+math+english as x164from students165order by chinese+math+english desc166167-- 一个查询语句, 一个查询结果, 是一张临时表168169-- 聚合函数一般都是和分组一起使用170-- 聚合函数, 也可以单独使用171172-- 查询整个表中, 有多少用户173select * from students;174select count(*) from students;175select name from students;176select count(name) from students;177select id from students;178select count(id) from students;179select math from students;180select count(math) from students;181182-- 二班的数学老师: 整个班级同学数学成绩的总和183select math from students where class = "二班";184select count(math) from students where class = "二班";185select sum(math) from students where class = "二班";186187-- 二班的数学老师: 整个班级同学数学平均成绩188select avg(math) from students where class = "二班";189190-- 二班的数学老师: 整个班级同学数学成绩最高多少191select max(math) from students where class = "二班";192193-- 二班的数学老师: 整个班级同学数学成绩最少多少194select min(math) from students where class = "二班";195196197-- 聚合函数更多是和分组一起使用198-- 分组: 把数据按照组进行分开199200-- 以班级进行分组201select class from students group by class;202203-- 以班级进行分组, 统计每个班级中有几个人204select class, count(id) from students group by class;205206-- 以班级进行分组, 知道每个班级的人数, 以及平均数学成绩207select class, count(id), avg(math) from students group by class;208209-- 以班级进行分组, 知道每个班级的人数, 以及平均数学成绩, 按照数学成绩排序210select211class, count(id), avg(math)212from students213group by class214order by avg(math) desc;215216217-- 按照班级分组, 获得每个班级平均总成绩, 每个班级最高总成绩, 每个班级最低的从成绩218select219class,220avg(chinese+math+english),221max(chinese+math+english),222min(chinese+math+english)223from students224group by class;225226-- 语法上: 下面这句话不对227select228class, name229from students230group by class;231232-- 想class分组, 又想得到组内的所有人的人名233select234class, group_concat(name) as allname235from students236group by class;237238-- 如果根据A字段分组,239-- 查询结果中:240-- 只能得到A字段,241-- 根据A字段分组的聚合结果242-- group_concat对分组内数据的连接结果243244245246-- 查询班级中每个班级的平均数学成绩247select class, avg(math) from students group by class;248249-- 查询班级中每个班级的平均数学成绩: 只要数学成绩及格的班级250-- 报错: 不允许先group 再 where; 只能先where 再 group251select252class, avg(math)253from students254group by class255where avg(math)>=60256257-- 报错: where想想用聚合结果作为判断, 但是where又要先执行258select259class, avg(math)260from students261where avg(math)>=60262group by class263264265266-- 统计班级中数学成绩及格的同学, 按照这些及格同学计算班级的平均数学成绩267select268class, avg(math)269from students270where math >=60271group by class272273274275-- 查询班级中每个班级的平均数学成绩: 只要数学成绩及格的班级276-- HAVING 可以让我们对分组后的各组数据过滤277-- (取代group 之后不可以使用where 的问题)278-- (having存在的目的, 就是在分组之后, 对分组的结果进行条件判断)279select280class, avg(math)281from students282group by class283having avg(math)>=60
xxxxxxxxxx751select * from students;23-- 排除只要不及格科目的同学,4-- 对及格的同学进行分组, 获得每个组是平均数学成绩5select6class, avg(math)7from students8where chinese >=60 and english>=60 and math>=609group by class;1011-- 排除只要不及格科目的同学,12-- 对及格的同学进行分组, 获得每个组是平均数学成绩13-- 获得班级数学平均成绩小于80的班级中, 平均数学成绩最高的那个班级14select15class, avg(math)16from students17where chinese >=60 and english>=60 and math>=6018group by class19having avg(math) <8020order by avg(math) desc21limit 12223(5) SELECT column_name, ...24(1) FROM table_name, ...25(2) [WHERE ...]26(3) [GROUP BY ...]27(4) [HAVING ...]28(6) [ORDER BY ...];29(7) [Limit ...]3031--32select * from students where 1=1;3334-- 较真:35-- 现实: 20-30行36-- 写sql, 设计表, 存数据: 考虑性能问题, 方便性的问题3738-- english: int -> varchar39-- 生日40-- int41-- height float(5, 2); 1100.0042-- name varchar(10) : 20字符434445--46drop table user1, user2, user3;474849select * from students;5051create table class (52id int primary key,53class_name varchar(10)54);5556select * from class;57insert into class values(1, "一班"),(2, "二班"),(3, "三班");58select * from students;59select * from class;6061--62update students set class_id =8 where class_id = 3;63update students set class_id =3 where class_id = 8;6465-- 外键: 给一个表的一个字段, 强制 关联上另外一张表的一个字段66update students set class_id =8 where class_id = 3;6768-- 保证数据一致性: 外键很好69-- 性能角度: 外键很差, 操作其中一个表, 一定导致关联的外键表的遍历70-- 使用角度: 外键极其不方便7172SELECT * FROM `students` order by math desc;7374-- 按照人名排序75SELECT * FROM `students` order by name desc;xxxxxxxxxx4231-- 班级2CREATE TABLE `class` (3`id` int(11) NOT NULL,4`class_name` varchar(255) ,5PRIMARY KEY (`id`)6);7-- 成绩8CREATE TABLE `score` (9`id` int(11) NOT NULL AUTO_INCREMENT,10`student_id` int(11) ,11`class_id` int(11),12`chinese` float ,13`english` float ,14`math` float ,15PRIMARY KEY (`id`)16);17-- 学生信息18CREATE TABLE `student` (19`id` int(11) NOT NULL,20`student_name` varchar(255),21`nick_name` varchar(255) ,22`mobile` varchar(255) ,23`era` varchar(255) ,24`motto` varchar(255),25PRIMARY KEY (`id`)26);27-- 剧本28CREATE TABLE `script` (29`id` int(11) NOT NULL,30`play_name` varchar(255),31`play_ location` varchar(255) ,32PRIMARY KEY (`id`)33);34-- 演出表35CREATE TABLE `show` (36`id` int(11) NOT NULL,37`student_id` int(11),38`script_id` int(11),39PRIMARY KEY (`id`)40);414243-- ----------------------------44INSERT INTO `class` VALUES (1, '一班');45INSERT INTO `class` VALUES (2, '二班');46INSERT INTO `class` VALUES (3, '三班');47INSERT INTO `class` VALUES (4, '四班');48INSERT INTO `class` VALUES (5, '五班');49-- ----------------------------50INSERT INTO `score` VALUES (1, 1, 1, 70, 90, 60);51INSERT INTO `score` VALUES (2, 2, 1, 70, 90, 90);52INSERT INTO `score` VALUES (3, 3, 1, 90, 90, 20);53INSERT INTO `score` VALUES (4, 4, 2, 60, 60, 60);54INSERT INTO `score` VALUES (5, 5, 2, 95, 80, 5);55INSERT INTO `score` VALUES (6, 6, 2, 25, 25, 5);56INSERT INTO `score` VALUES (7, 7, 3, 90, 90, 90);57INSERT INTO `score` VALUES (8, 8, 3, 90, 80, 80);58INSERT INTO `score` VALUES (9, 9, 3, 98, 90, 80);59INSERT INTO `score` VALUES (10, 10, 3, 95, 90, 80);60INSERT INTO `score` VALUES (11, 11, 3, 98, 95, 95);61INSERT INTO `score` VALUES (12, 12, 3, 80, 90, 80);62-- ----------------------------63INSERT INTO `script` VALUES (1, '三打祝家庄', '祝家庄');64INSERT INTO `script` VALUES (2, '梁山聚义', '梁山');65INSERT INTO `script` VALUES (3, '壮士落幕', '六和寺');66INSERT INTO `script` VALUES (4, '赤壁之战', '赤壁');67INSERT INTO `script` VALUES (5, '七步诗事件', '洛阳');68INSERT INTO `script` VALUES (6, '白帝城托孤', '白帝城');69INSERT INTO `script` VALUES (7, '煮酒论英雄', '许昌');70-- ----------------------------71INSERT INTO `show` VALUES (1, 1, 1);72INSERT INTO `show` VALUES (2, 2, 1);73INSERT INTO `show` VALUES (3, 3, 1);74INSERT INTO `show` VALUES (4, 1, 2);75INSERT INTO `show` VALUES (5, 2, 2);76INSERT INTO `show` VALUES (6, 3, 2);77INSERT INTO `show` VALUES (7, 1, 3);78INSERT INTO `show` VALUES (8, 2, 3);79INSERT INTO `show` VALUES (9, 7, 4);80INSERT INTO `show` VALUES (10, 10, 4);81INSERT INTO `show` VALUES (11, 11, 4);82INSERT INTO `show` VALUES (12, 12, 4);83INSERT INTO `show` VALUES (13, 8, 5);84INSERT INTO `show` VALUES (14, 9, 5);85INSERT INTO `show` VALUES (15, 11, 6);86INSERT INTO `show` VALUES (16, 12, 6);87INSERT INTO `show` VALUES (17, 7, 7);88INSERT INTO `show` VALUES (18, 11, 7);89-- ----------------------------90INSERT INTO `student` VALUES (1, '武松', '行者', '13440996665', '宋朝', '别胡说!难道不付你钱!再筛三碗来!');91INSERT INTO `student` VALUES (2, '林冲', '豹子头', '17383945041', '宋朝', '无');92INSERT INTO `student` VALUES (3, '宋江', '及时雨', '15671722818', '宋朝', '他日若遂凌云志,敢笑黄巢不丈夫');93INSERT INTO `student` VALUES (4, '贾琏', '琏二爷', '19931477852', '清朝', '无');94INSERT INTO `student` VALUES (5, '贾宝玉', '怡红公子', '13456229050', '清朝', '我要这玉又何用');95INSERT INTO `student` VALUES (6, '贾环', '孽障', '18900141462', '清朝', '无');96INSERT INTO `student` VALUES (7, '曹操', '阿满', '17273083171', '三国', '宁我负人,毋人负我');97INSERT INTO `student` VALUES (8, '曹丕', '子桓', '17180453185', '三国', '无');98INSERT INTO `student` VALUES (9, '曹植', '陈思王', '19818008917', '三国', '无');99INSERT INTO `student` VALUES (10, '孙权', '孙十万', '15638204123', '三国', '无');100INSERT INTO `student` VALUES (11, '刘备', '刘皇叔', '15638204378', '三国', '惟贤惟德,能服行人');101INSERT INTO `student` VALUES (12, '诸葛亮', '诸葛武侯,卧龙', '15119511196', '三国', '非淡泊无以明志,非宁静无以致远');102103104select * from class;105select * from student;106select * from score;107select * from script;108select * from `show`;109110-- 装备表111CREATE TABLE `equip` (112`id` int(11) NOT NULL PRIMARY KEY,113`student_id` int(11) NULL DEFAULT NULL,114`equip_name` varchar(255) NULL DEFAULT NULL115) ;116117118INSERT INTO `equip` VALUES (1, 1, '行者套账');119INSERT INTO `equip` VALUES (2, 2, '丈八蛇矛');120INSERT INTO `equip` VALUES (3, 5, '通灵宝玉');121INSERT INTO `equip` VALUES (4, 7, '七星刀');122INSERT INTO `equip` VALUES (5, 7, '绝影马');123INSERT INTO `equip` VALUES (6, 7, '爪黄飞电马');124INSERT INTO `equip` VALUES (7, 7, '倚天剑');125INSERT INTO `equip` VALUES (8, 7, '青釭剑');126INSERT INTO `equip` VALUES (9, 11, '的卢马');127INSERT INTO `equip` VALUES (10, 11, '双股剑');128129130131-- 获得三班同学, 姓名, 语文成绩, 班级名, 参加了哪些剧目132select id from class where class_name = '三班'; -- 3133select chinese , student_id from score where class_id = 3;134...135136-- 获得三班同学, 姓名, 语文成绩, 班级名, 参加了哪些剧目137select138st.student_name, sc.chinese, c.class_name, scr.play_name139from class c140inner join score sc on sc.class_id = c.id141inner join student st on st.id = sc.student_id142inner join `show` sh on st.id = sh.student_id143inner join script scr on scr.id = sh.script_id144where c.class_name = "三班"145146147148-- 交叉链接: 让两个表进行链接: 按照笛卡尔积149select * from class cross join score150151select * from class;152select * from student;153select * from score;154select * from script;155select * from `show`;156select * from equip;157158159-- 交叉链接: 让两个表进行链接: 按照笛卡尔积160select * from class cross join score where class.id = score.class_id161162--163select * from class cross join score where class.id = class_id164165-- 班级名, 语文成绩, 英语成绩, 数学成绩166select167class.class_name, score.chinese, score.english, score.math168from class169cross join score170where class.id = class_id171172-- 给表起别名173select174c.class_name, s.chinese, s.english, s.math175from class as c176cross join score as s177where c.id = s.class_id178179-- 省略 as180select181c.class_name, s.chinese, s.english, s.math182from class c183cross join score s184where c.id = s.class_id185186187188select * from class;189select * from student;190select * from score;191select * from script;192select * from `show`;193select * from equip;194195196-- 自然连接197select198*199from class200natural join equip;201202203-- 内连接: 表1 inner join 表2 on 表1和表2的链接条件204select205*206from class c207inner join score s on c.id = s.class_id208209-- 内连接210select211*212from class c213inner join score s on c.id = s.class_id214where s.math > 60;215216-- 隐式内连接: 不建议这么写217select * from class c , score s where c.id = s.class_id218select * from class c , score s where c.id = s.class_id and s.math>60;219220221222-- 连接班级和分数表: 外连接223-- 左外连接224-- 右外连接225-- 主表 副表226227228-- class主表, score副表229select230*231from class c232left outer join score s on c.id = s.class_id233234-- score主表, class副表235select236*237from class c238right outer join score s on c.id = s.class_id239240-- class主表, score副表241select242*243from score s244right outer join class c on c.id = s.class_id245246select247*248from class c249left outer join score s on c.id = s.class_id250where s.chinese is not null251252253254select255*256from class c257left join score s on c.id = s.class_id258where s.chinese is not null259260261-- 查询数学成绩低于林冲的数学成绩的人的信息262select263t1.*264from score t1, score t2265where t2.id = 1 and t1.math < t2.math266267select268*269from score t1 where t1.math < 60270271272-- 查询: 那些同学有装备273select274*275from student st276inner join equip e on st.id = e.student_id277278-- 查询: 有哪些同学没有装备279select280st.*281from student st282left join equip e on st.id = e.student_id283where e.id is null284285286-- 查询: 有哪些同学没有装备287select288st.*289from student st290where st.id not in ( 1, 2, 5, 7, 11)291292-- 查询: 那些同学有装备293select294st.*295from student st296where st.id in ( 1, 2, 5, 7, 11)297298299select300e.student_id301from equip e;302303304select305st.*306from student st307where st.id in (308select309e.student_id310from equip e311)312313314-- 查询: 有哪些同学没有装备315select316st.*317from student st318where st.id not in (319select320e.student_id321from equip e322)323324-- 修改 数学成绩小于武松的数学成绩的同学的数学成绩为60325update score set math = 60 where math < 武松的数学成绩326327328select329sc.math330from student st331inner join score sc on st.id = sc.student_id332where st.student_name = "武松"333334335select * from (336select337sc.math338from student st339inner join score sc on st.id = sc.student_id340where st.student_name = "武松"341) as temp342343344update score set math = 60 where math < (345select * from (346select347sc.math348from student st349inner join score sc on st.id = sc.student_id350where st.student_name = "武松"351) as temp352)353354-- 查询每个班级中, 数学成绩最高的那个人的班级, 姓名, 数学, 语文, 英语成绩355356select357c.class_name, st.student_name, sc.chinese, sc.english, sc.math358from class c359inner join score sc on c.id = sc.class_id360inner join student st on sc.student_id = st.id361362363-- 班级id, 最高的数学成绩364select365c.id, max(sc.math)366from class c367inner join score sc on c.id = sc.class_id368group by c.id369370--371(372select373c.id, max(sc.math)374from class c375inner join score sc on c.id = sc.class_id376group by c.id377) temp378379380select381c.class_name, st.student_name, sc.chinese, sc.english, sc.math382from class c383inner join score sc on c.id = sc.class_id384inner join student st on sc.student_id = st.id385inner join (386select387c.id, max(sc.math) as mmath388from class c389inner join score sc on c.id = sc.class_id390group by c.id391) temp on temp.id = c.id and sc.math = temp.mmath392393-- 查询每个班级中, 数学成绩最高的那个人的班级, 姓名, 数学, 语文, 英语成绩394select395c.class_name, st.student_name, sc.chinese, sc.english, sc.math396from class c397inner join score sc on c.id = sc.class_id398inner join student st on sc.student_id = st.id399where sc.math = (当前所在班级的最大数学成绩)400401402select403*404from score sc2405where sc2.class_id = A班级id406407--408select409c.class_name, st.student_name, sc.chinese, sc.english, sc.math410from class c411inner join score sc on c.id = sc.class_id412inner join student st on sc.student_id = st.id413where sc.math = (414415select416sc2.math417from score sc2418where sc2.class_id = sc.class_id419order by sc2.math desc420limit 1421422)423