章十二、数据库(1) —— 概述、MySQL数据库、SQL、DDL、DML、DQL、多表设计

为什么学习数据库:

        ● 实现数据持久化到本地;

        ● 使用完整的管理系统统一管理,可以实现结构化查询,方便管理;

一、 数据库概述


  数据库

        数据库(DataBase)为了方便数据的 存储 和 管理 ,它将数据按照特定的规则存储在磁盘上,就是一个存储数据的仓库

DB:数据库(DataBase

        存储数据的容器,它保存了一系列有组织的数据。

DBMS:数据库管理系统(DataBase Management System

        又称为数据库软件或数据库产品,用于创建或管理DB

  常见的数据库产品

        • 国外

MySQL:快捷、可靠 开源。免费

Oracle:功能强大收费

SQL Server(微软):只能安装在Windows操作系统

DB2 (IBM):适合处理海量数据收费

        • 国内

南大通用GBASE:天津南大通用数据技术股份有限公司

达梦武汉达梦数据库股份有限公司

人大金仓北京人大金仓信息技术股份有限公司

神通神舟通用公司

二、 Mysql数据库


        MySQL是一个 关系型数据库管理系统 (以数据表为单位,表与表之间存在关联)由瑞典MySQL AB 公司开发,目前属于 Oracle旗下产品。MySQL 流行的关系型数据库管理系统。(后面会讲非关系型数据库(key、value):Redis)

● MySql是一种关系数据库管理系统。

● MySql软件是一种开放源码软件,你可以修改源码来开发自己的 Mysql 系统。

● MySql数据库服务器具有快速、可靠和易于使用的特点。

● MySql使用标准的sql语言,并且支持多种操作系统,支持多种语言.

● mysql商业版与社区版

● MySQL商业版是由MySQL AB公司负责开发与维护,需要付费才能使用

● MySQL社区版是由分散在世界各地的MySQL开发者、爱好者一起开发与维护,可以免费使用

●  命令行方式连接mysql

登录:mysql [-hlocalhost -P3306](本机可省略) -uroot -p(直接跟写密码,不能有空格)

-h:主机名

-P:端口号

-u:用户名

-p:密码

退出:exit

  MySQL的常用命令

查看当前所有的数据库:show databases;

选择指定的库:use 库名

查看当前的所有表:show tables;

查看其他库的所有表:show tables from 库名;

查看mysql版本:select version();

安装可视化客户端工具 :SQLyog / Navicat

三、 SQL


        结构化查询语言(Structured Query Language) 简称SQL,是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。

优点:

        不是某个特定数据库供应商专有的语言,几乎所有DBMS都支持

        SQL简单易学,灵活使用可以进行非常复杂和高级的数据库操作

在SQL语言中,根据操作系统的不同,又分为不同类型的SQL语句(DDL、DML、DQL、DCL等等)

四、 DDL


        数据(结构)定义语言(Data Definition Language) 简称DDL,是用于创建和修改数据库表结构的语言。

常用的语句:create、alter、drop、rename

  创建删除数据库

        • 创建数据库并设置编码格式

CREATE DATABASE [if not exists] 数据库名 [CHARSET utf8];

        • 删除数据库

DROP DATABASE 数据库名 / [IF EXISTS数据库名];

        • 修改字符集

ALTER DATABASE 数据库名 CHARSET gbk;

-- 创建数据库并设置编码格式
-- CREATE DATABASE [if not exists] 数据库名 [ CHARSET utf8]
-- 注:数据库运行时是一行一行运行的,需要选中要运行的行然后执行

-- 创建数据库 test
CREATE DATABASE test;
-- 创建数据库 test 并设置编码 utf8
CREATE DATABASE test CHARSET utf8;
-- 如果数据库 test 不存在便创建
CREATE DATABASE IF NO EXISTS test CHARSET utf8;

-- 删除数据库
-- DROP DATABASE 数据库名 / [IF EXISTS数据库名];

DROP DATABASE test;

-- 数据库名一旦创建,不能修改数据库名,但可以修改字符集编码
-- 修改字符集编码
ALTER DATABASE test CHARSET utf8

  数据库表

        • 数据表

        表(table)是数据存储的最常见和最简单的形式,是构成关系型数据库的基本元素。表的最简单形式是由行和列组成,分别都包含着数据。 每个表都有一个表头和表体,表头定义表名和列名 .表中的行被看作是文件中的记录,表中的列被看作是这些记录的字段。

        • 字段(列)

        字段是表里的一列,用于保存每条记录的特定信息。如客户订单表的字段包括“订单ID”、“姓名”、“客户ID”、“职务”、“上级”、“地区”、“运货商”、“国家”等。数据表的一列包含了特定字段的全部信息。

        • 记录(行)

        记录也被称为一行数据,是表里的一行数据。

  设计表

对于具体的某一个表,在创建之前,需要确定表的下列特征:

        ● 表名(表信息)

        ● 表中的字段

        ● 字段的数据类型和长度

        ● 约束(列的规则)

  数据类型

charn):长度为 定长字符串(如果只存了2个字符进去,字符串的长度依然是n,会补空格补到n)最大长度255个字符(一般用来存储长度固定的数据)

varchar(n):最大长度为n可变长字符串

date: 日期,包含年月日

datetime: 日期,包含 年月日 时分秒

整型:

整型字节最大值最小值
TINYINT1-128127
SMALLINT2-3276832767
MEDIUMINT3-83886088388607
INT4-21474836482147483647
BIGINT8-92233720368547758089223372036854775807

signed        有符号        默认是有符号

unsigned        无符号

浮点型:decimal ( M , D )

TEXT(列字符、字符串):

        TINYTEXT:最大长度255个字符(2^8-1)

        TEXT:最大长度65535(2^16-1)

        MEDIUMTEXT:最大长度16777215(2^24-1)

        LONGTEXT:最大长度4294967295(2^32-1)

  创建表

语法:

CREATE TABLE 表名(列名 数据类型 [约束] [默认值] [ 注释] , ...... )
CREATE TABLE student(
    num INT,
    NAME VARCHAR(10),
    gender CHAR(1),
    birthday CHAR(11),
    address VARCHAR(30), 
    height DECIMAL(3,2),
    reg_time DATETIME
)

删除表:

DROP TABLE 表名

修改表名:

RENAME TABLE 旧表名 TO 新表名
-- 修改表名
RENAME TABLE student TO stu
RENAME TABLE stu TO student

复制表结构:

CREATE TABLE 新表名 LIKE 被复制表名; 

-- 复制表结构
CREATE TABLE stu LIKE student
DROP TABLE stu

  约束

设置主键:

        在一张表中代表唯一的一条记录,不能为空,不能重复

设置约束:

        PRIMARY KEY        -- 设置主键约束

        NOT NULL        -- 不能为空约束

        UNIQUE        -- 唯一性约束

        检查约束 设置条件

        外键约束

设置主键自动增长设置为自动增长时只能为整数类型)

        AUTO_INCREMENT

设置默认值:

        DEFAULT default_value

设置字段注释:

        comment '注释'

CREATE TABLE student(
num INT PRIMARY KEY AUTO_INCREMENT COMMENT '学号 主键',
NAME VARCHAR(10) NOT NULL COMMENT "姓名",
gender CHAR(1) NOT NULL DEFAULT '男' COMMENT '性别',
birthday DATE,
phone CHAR(11) NOT NULL UNIQUE,
address VARCHAR(30), 
height DECIMAL(3,2) CHECK(height<2.60),
reg_time DATETIME
)

五、 DML


数据操纵语言Data Manipulation Language),简称 DML

常用语句: insert,delete,update

  插入数据

方式1:INSERT INTO 表名(1,2……,n) VALUES(1,2…..,n);

方式2:INSERT INTO 表名 set 列名1=1,..列名n=n;

方式3:INSERT INTO 表名(1,2……,n) VALUES(1,2…..,n),(1,2…..,n);

方式4:INSERT INTO 表名(1,2……,n) 查询语句(查询的列数与插入列数匹配)

-- 插入数据
/*
方式1:INSERT INTO 表名(列1,列2……,列n) VALUES(值1,值2…..,值n);
方式2:INSERT INTO 表名 set 列名1=值1,..列名n=值n;
方式3:INSERT INTO 表名(列1,列2……,列n) VALUES(值1,值2…..,值n),(值1,值2…..,值n);
方式4:INSERT INTO 表名(列1,列2……,列n) 查询语句(查询的列数与插入列数匹配)
*/
-- 方式1
INSERT INTO student(NAME,gender,birthday,phone) VALUES('张三','男','2003-3-5','1532222222')
INSERT INTO student(NAME,gender,birthday,phone,address,height,reg_time) 
	VALUES('张三','男','2003-3-5','15333333333','汉中',1.75,NOW())
-- 方式3
INSERT INTO student(NAME,gender,birthday,phone,address,height,reg_time) 
	VALUES('李四','女','2003-4-6','15344444444','汉中',1.65,NOW()),
		('王五','男','2003-6-7','15355555555','汉中',1.85,NOW()),
		('赵六','男','2003-7-8','15366666666','汉中',1.70,NOW())
-- 方式2
INSERT INTO student SET NAME = '孙七',gender = '男',phone = '15377777777'
-- 方式4
CREATE TABLE stu LIKE student
INSERT INTO stu(NAME,gender,birthday,phone,address,height,reg_time) 
	SELECT NAME,gender,birthday,phone,address,height,reg_time FROM student

  修改数据

UPDATE 表名 SET 列名 = ‘新值’WHERE 条件

-- 修改数据
-- UPDATE 表名 SET 列名 = ‘新值’WHERE 条件
UPDATE student SET address = '西安',height = 1.66,reg_time = '2023-4-5 14:00:00' WHERE num = 1

  删除数据

DELETE FROM 表名 WHERE 条件

TRUNCATE TABLE 表名;        -- 清空整张表

-- 删除数据
-- DELETE FROM 表名 WHERE 条件
DELETE FROM student WHERE num = 7

-- 清空整张表
-- TRUNCATE TABLE 表名;  
DELETE FROM stu

六、 DQL


数据查询语言查询(Data Query Language),简称DQL,是使用频率最高的一个操作,可以从一个表中查询数据,也可以从多个表中查询数据。

基础查询

语法: select 查询列表 from 表名;

特点:

        查询列表可以是:表中的字段、常量、表达式、函数

        查询的结果是一个虚拟的表格

  查询结果

特定列查询select column1,column2 from table

全部列查询select * from table

算数运算符+ - * /

排除重复行select distinct column1,column2 from table

查询函数:select 函数; / 例如version()

-- 基础查询
-- select 查询列表 from 表名;
-- select 查询列表 from 表名 where 条件 排序 数量限制 分组 ...

/*
特定列查询:select column1,column2 from table
全部列查询: select * from table
算数运算符:+ - * /
排除重复行: select distinct column1,column2 from table
查询函数:select 函数; / 例如version()
*/

-- 特定类查询
SELECT num,NAME,gender FROM student

-- 全部列查询
SELECT * FROM student

-- 算术运算(不能作为字符串连接符)
SELECT num+100,NAME,gender FROM student
SELECT num,NAME+':'+gender FROM student
-- 字符串函数,连接多个字符串
SELECT num,CONCAT(NAME,':',gender) FROM student

-- 排除重复的行(所有的列都相同)
SELECT NAME,gender,birthday FROM student
SELECT DISTINCT NAME,gender,birthday FROM student

-- 查询函数
SELECT VERSION(); -- 产看数据库版本


  单行函数

        • 字符函数

length():获取参数值的字节个数

char_length():获取参数值的字符个数

concat(str1,str2,.....):拼接字符串

upper()/lower():将字符串变成大写/小写

substring(str,pos,length):截取字符串 位置从1开始

instr(str,指定字符):返回子串第一次出现的索引,如果找不到返回0

trim(str):去掉字符串前后的空格或子串,trim(指定子串 from 字符串)

lpad(str,length,填充字符):用指定的字符实现左填充将str填充为指定长度

rpad(str,length,填充字符):用指定的字符实现右填充将str填充为指定长度

replace(str,old,new):替换,替换所有的子串

-- 单行函数
/*
字符函数
length():获取参数值的字节个数
char_length()获取参数值的字符个数
concat(str1,str2,.....):拼接字符串
upper()/lower():将字符串变成大写/小写
substring(str,pos,length):截取字符串 位置从1开始
instr(str,指定字符):返回子串第一次出现的索引,如果找不到返回0
trim(str):去掉字符串前后的空格或子串,trim(指定子串 from 字符串)
lpad(str,length,填充字符):用指定的字符实现左填充将str填充为指定长度
rpad(str,length,填充字符):用指定的字符实现右填充将str填充为指定长度
replace(str,old,new):替换,替换所有的子串
*/

SELECT NAME,LENGTH(NAME) FROM student  -- 以字节为单位
SELECT NAME,CHAR_LENGTH(NAME) FROM student -- 以字符为单位
SELECT num,CONCAT(NAME,':',gender) FROM student -- 拼接字符串
SELECT NAME,UPPER(NAME),LOWER(NAME) FROM student -- 字符串变成大写、小写
SELECT SUBSTRING(NAME,2,3) FROM student -- 截取字符串
SELECT INSTR(NAME,'赵') FROM student -- 返回子串第一次出现的索引,如果找不到返回0
SELECT TRIM('张' FROM NAME) FROM student -- 删去指定字符串
SELECT LPAD(NAME,6,'*') FROM student -- 左填充
SELECT RPAD(NAME,6,'*') FROM student -- 右填充
SELECT REPLACE(NAME,'张','刘') FROM student -- 替换

        • 逻辑处理

case when 条件 then 结果1 else 结果2 end:条件判断

ifnull(被检测值,默认值):函数检测是否为null,如果为null,则返回指定的值,否则返回

原本的值

if(条件,结果1,结果2):if 函数:if else的 效果

/*
逻辑处理
case when 条件 then 结果1 else 结果2 end; 可以有多个when
ifnull(被检测值,默认值)函数检测是否为null,如果为null,则返回指定的值,否则返回
原本的值
if函数:if else的 效果 if(条件,结果1,结果2)
*/

-- 判断条件(可以多个条件)
SELECT NAME,
	(CASE WHEN height>=1.70 THEN '高个子' ELSE '正常身高' END) AS height,
	gender
	FROM student

SELECT NAME,
	(CASE WHEN height>=1.80 THEN '高个子'
	      WHEN height>=1.60 THEN '正常身高' 
	      ELSE '低个子' END) AS height,
	gender
	FROM student

-- 判断是否为空
SELECT NAME,IFNULL(address,'暂未录入')AS address FROM student

-- 条件函数(单个条件)
SELECT NAME,IF(height>=1.80,'高个子','正常身高')AS height FROM student

        • 数学函数

round(数值):四舍五入

ceil(数值):向上取整,返回>=该参数的最小整数

floor(数值):向下取整,返回<=该参数的最大整数

truncate(数值,保留小数的位数):截断,小数点后截断到几位

mod(被除数,除数):取余,被除数为正,则为正;被除数为负,则为负

rand():获取随机数,返回0-1之间的小数

/*
数学函数:
round(数值):四舍五入
ceil(数值):向上取整,返回>=该参数的最小整数
floor(数值):向下取整,返回<=该参数的最大整数
truncate(数值,保留小数的位数):截断,小数点后截断到几位
mod(被除数,除数):取余,被除数为正,则为正;被除数为负,则为负
rand():获取随机数,返回0-1之间的小数
*/

SELECT NAME,ROUND(height) FROM student -- 四舍五入
SELECT NAME,CEIL(height) FROM student -- 向上取整
SELECT NAME,FLOOR(height) FROM student -- 向下取整
SELECT NAME,TRUNCATE(height,1) FROM student -- 保留小数到第几位
SELECT num,NAME,MOD(num,3) FROM student -- 取余
SELECT NAME,RAND() FROM student -- 随机数(0~1)

        • 日期函数

now():返回当前系统日期+时间

curdate():返回当前系统日期,不包含时间

curtime():返回当前时间,不包含日期

可以获取指定的部分,年、月、日、小时、分钟、秒

YEAR(日期列) ,MONTH(日期) ,DAY(日期) ,HOUR(日期) ,MINUTE(日期) ,SECOND(日期)

str_to_date(字符串格式日期,格式):将日期格式的字符转换成指定格式的日期

date_format(日期列,格式):将日期转换成字符串

datediff(big,small):返回两个日期相差的天数

日期格式: 

/*
日期函数:
now():返回当前系统日期+时间
curdate():返回当前系统日期,不包含时间
curtime():返回当前时间,不包含日期
可以获取指定的部分,年、月、日、小时、分钟、秒
YEAR(日期列),MONTH(日期列),DAY(日期列),HOUR(日期列),MINUTE(日期列),SECOND(日期列)
str_to_date(字符串格式日期,格式):将日期格式的字符转换成指定格式的日期
date_format(日期列,格式):将日期转换成字符串
datediff(big,small):返回两个日期相差的天数
*/


SELECT NOW() FROM student -- 当前日期和时间
SELECT CURDATE() FROM student -- 当前日期
SELECT CURTIME() FROM student -- 当前时间
SELECT YEAR(reg_time),MONTH(reg_time),DAY(reg_time) FROM student

-- 将日期转化为指定格式
SELECT NAME,DATE_FORMAT(birthday,'%Y-%m') FROM student

-- 将字符串类日期转化为日期
SELECT STR_TO_DATE('2002-03-21','%Y-%m-%d') FROM student

-- 返回两个日期相差的天数
SELECT NAME,DATEDIFF(CURDATE(),birthday) FROM student
SELECT NAME,DATEDIFF(STR_TO_DATE('2022-01-01','%Y-%m-%d'),birthday) FROM student

        • 分组函数

功能:用作统计使用,又称为聚合函数或统计函数或组函数

sum 求和、avg 平均值、max 最大值、min 最小值、count 计数(非空)

1.sumavg一般用于处理数值型,max、min、count可以处理任何类型

2.以上分组函数都忽略null

3.count函数的一般使用count*)用作统计行数

4.和分组函数一同查询的字段要求是group by后的字段

/*
分组函数
功能:用作统计使用,又称为聚合函数或统计函数或组函数
分类:sum 求和、avg 平均值、max 最大值、min 最小值、count 计数(非空)
1.sum,avg一般用于处理数值型,max,min,count可以处理任何类型
2.以上分组函数都忽略null值
3.count函数的一般使用count(*)用作统计行数
4.和分组函数一同查询的字段要求是group by后的字段
*/

SELECT SUM(height) FROM student -- 求和
SELECT AVG(height) FROM student -- 求平均
SELECT MAX(height) FROM student -- 最大值
SELECT MIN(height) FROM student -- 最小值
SELECT COUNT(*) FROM student -- 统计行数
SELECT COUNT(1) FROM student 
SELECT COUNT(num) FROM student -- count(列名)

SELECT * FROM student WHERE height = (SELECT MAX(height) FROM student)

        • 条件查询

使用WHERE 子句,将不满足条件的行过滤掉,WHERE 子句紧随 FROM 子句。

语法:select <结果> from <表名> where <条件>

精准查询:

比较运算:= 、!= 或 <>、>、<、>=、<=

逻辑运算:and 与、or 或、not 非

模糊查询:

LIKE :是否匹配于一个模式 一般和通配符搭配使用,可以判断字符型数值或数值型

通配符:% 任意多个字符

between and:两者之间,包含临界值;

in:判断某字段的值是否属于in列表中的某一项

IS NULL(为空的)或 IS NOT NULL(不为空的)

/*
条件查询
功能:使用WHERE 子句,将不满足条件的行过滤掉,WHERE 子句紧随 FROM 子句。
精准查询:
语法:select <结果> from <表名> where <条件>
比较运算:= 、!= 或 <>、>、<、>=、<=
逻辑运算:and 与、or 或、not 非
模糊查询:
LIKE :是否匹配于一个模式 一般和通配符搭配使用,可以判断字符型数值或数值型. 
通配符:% 任意多个字符
between and 两者之间,包含临界值;
in 判断某字段的值是否属于in列表中的某一项
IS NULL(为空的)或 IS NOT NULL(不为空的)
*/
-- 精准查询
SELECT * FROM student WHERE num = 1 -- 值等于
SELECT * FROM student WHERE gender = '男'
SELECT * FROM student WHERE gender != '男' -- 值不等于
SELECT * FROM student WHERE gender <> '男' -- 也是值不等于
SELECT * FROM student WHERE gender = '男' AND height > 1.80
SELECT * FROM student WHERE gender = '男' OR height > 1.80
-- 模糊查询
SELECT * FROM student WHERE NAME = '张'
SELECT * FROM student WHERE NAME LIKE '张'
SELECT * FROM student WHERE NAME LIKE '张%' -- 以张开头,后面任意匹配

SELECT * FROM student WHERE height >= 1.70 AND height <=2.0 -- 精准查询
SELECT * FROM student WHERE height BETWEEN 1.70 AND 2.0 -- 范围查询(包含边界)

SELECT * FROM student WHERE height = 1.65 OR height = 1.75 OR height = 1.85
SELECT * FROM student WHERE height IN(1.65,1.75,1.85) -- 查询字段值属于in的内容
SELECT * FROM student WHERE height NOT IN(1.65,1.75,1.85)

SELECT * FROM student WHERE NAME = NULL -- 不能这样查
SELECT * FROM student WHERE NAME IS NULL -- 查询是为空的
SELECT * FROM student WHERE NAME IS NOT NULL -- 非空

        • UNION语句

1UNION 的语法如下:

[SQL 语句 1]

UNION

[SQL 语句 2]

2UNION ALL 的语法如下:

[SQL 语句 1]

UNION ALL

[SQL 语句 2]

        当使用union 时,mysql 会把结果集中重复的记录删掉,而使用union all ,mysql 会把所有的记录返回,且效率高于union 。

/*
union 语句:合并多个查询结果
1、UNION 的语法如下:
[SQL 语句 1]
UNION
[SQL 语句 2]
2、UNION ALL 的语法如下:
[SQL 语句 1]
UNION ALL
[SQL 语句 2]
当使用union 时,mysql 会把结果集中重复的记录删掉,而使用union all,
mysql 会把所有的记录返回,且效率高于union 。
*/

SELECT num,NAME,gender FROM student WHERE gender = '男'
UNION
SELECT num,NAME,gender FROM student WHERE gender = '女' -- 上下查询结果的列要相同

-- union会把重复数据删去
SELECT num,NAME,gender FROM student WHERE gender = '男'
UNION
SELECT num,NAME,gender FROM student WHERE height = 1.66
-- 而union会全部返回
SELECT num,NAME,gender FROM student WHERE gender = '男'
UNION ALL
SELECT num,NAME,gender FROM student WHERE height = 1.66

        • 排序函数

查询结果排序,使用 ORDER BY 子句排序

order by 排序列 ASC/DESC

其中:asc代表的是升序,desc代表的是降序,如果不写,默认是升序

order by 子句中可以支持单个字段、多个字段

/*
排序:使用 ORDER BY 子句排序:
order by 排序列 ASC/DESC
其中:
asc代表的是升序,desc代表的是降序,如果不写,默认是升序
order by子句中可以支持单个字段、多个字段
*/
SELECT * FROM student ORDER BY height ASC -- 升序
SELECT * FROM student ORDER BY height DESC -- 降序

SELECT * FROM student WHERE gender = '男' ORDER BY height -- 执行顺序

SELECT * FROM student ORDER BY birthday,height -- 先按生日排,当生日相同时按照身高排

        • 数量限制函数

limit子句:对查询的显示结果限制数目 (sql语句最末尾位置)

SELECT * FROM 表名 LIMIT offset rows;

offset 是起始位置,rows 是查询个数

/*
数量限制:
limit子句:对查询的显示结果限制数目 (sql语句最末尾位置)
SELECT * FROM table LIMIT offset rows;
SELECT * from table LIMIT 0,5;
*/
SELECT * FROM student LIMIT 0,2 -- 开始位置为0,查两条
SELECT * FROM student LIMIT 2,2 -- 每一次分页计算起始位置
SELECT * FROM student LIMIT 4,2 -- limit (),2

        • 分组查询函数

将某类数据分到一个组中进行处理

语法: select 分组函数,列(要求出现在group by的后面

from

[where 筛选条件]

group by 分组的列表

[having 分组后的筛选]

[order by 子句]

注意:查询列表比较特殊,要求是分组函数和group by后出现的字段

分组查询中的筛选条件分为两类:

数据源源位置关键字
分组前筛选原始表group by 子句后面where
分组后筛选分组后的结果集group by 的后面having
/*
分组查询
将某类数据分到一个组中进行处理
select 分组函数,列(要求出现在group by的后面)
from 表
[where 筛选条件]
group by 分组的列表
[having 分组后的筛选]
[order by 子句]
注意:查询列表比较特殊,要求是分组函数和group by后出现的字段
*/
SELECT COUNT(*),gender FROM student GROUP BY gender -- 按性别分组,然后每个组分别进行统计
-- 分组前筛选(在group by 前面)--- where
-- 分组后筛选(在group by 后面)--- having

-- 统计每一年出生的人数
SELECT COUNT(*),YEAR(birthday) FROM student GROUP BY YEAR(birthday)
-- 统计名字数量
SELECT COUNT(*),NAME FROM student GROUP BY NAME
-- 查询出是哪些名字重复了
SELECT COUNT(*),NAME FROM student GROUP BY NAME HAVING COUNT(*)>1

七、 多表设计_关联查询


  数据库设计范式

        • 第一范式(确保每列保持原子性)

        第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值(即不能有歧义),就说明该数据库表满足了第一范式。

例如:

 这里的联系方式就存在歧义,联系方式到底是电话?邮箱?还是QQ?因而需要将其拆分开来

        • 第二范式(要有主键,要求其他字段都依赖于主键)

        没有主键就没有唯一性,没有唯一性在集合中就定位不到这行记录,所以要主键。

        其他字段为什么要依赖于主键?因为不依赖于主键,就找不到他们。更重要的是,其他字段组成的这行记录和主键表示的是同一个东西,而主键是唯一的,它们只需要依赖于主键,也就成了唯一的。

        • 第三范式(确保每列都和主键列直接相关)

        确保每列都和主键列直接相关,而不是间接相关,要求一个数据库表中不包含已在其它表中包含的非主关键字信息。

  外键约束

引用另外一个数据表的某条记录。

外键列类型与主键列类型保持一致

数据表之间的关联/引用关系是依靠具体的主键(primary key)和外键(foreign key)建立起来的。

在建表初期:

CREATE TABLE student(

id INT not NULL auto_increment primary key,

num INT,

name varchar(10),

majorid INT,

CONSTRAINT 约束名 foreign key(majorid ) references major(id)

);

约束名规则:

例:FK_ForeignTable_PrimaryTable_On_ForeignColumn

1、当主表中没有对应的记录时,不能将记录添加到从表

2、不能更改主表中的值而导致从表中的记录孤立

3、从表存在与主表对应的记录,不能从主表中删除该行

4、删除主表前,先删从表

/*
专业信息 -- 专业表

学生关联专业

*/

CREATE TABLE major(
    id INT PRIMARY KEY AUTO_INCREMENT,
    NAME VARCHAR(20) NOT NULL

)

-- 给学生表中添加专业编号列
-- 修改表,添加列
ALTER TABLE student ADD majorid INT
-- majorid 称为外键,外键必须与另一个表的主键关联,且数据类型一致
--  通过学生表中的majorid列,把学生和专业关联起来
-- 在学生表中只需要添加专业编号,其他信息不需要添加到学生表

-- 表与表关系:多对一关系(也可以成为一对多)


-- 添加外键约束,数据与数据之间的关联,不能随意操作
-- 例如在学生与专业关联时,此时删除专业就不太好
-- CONSTRAINT 约束名 foreign key(majorid ) references major(id)
-- 约束名规则:FK_ForeignTable_PrimaryTable_On_ForeignColumn

ALTER TABLE student ADD CONSTRAINT fk_student_major_on_majorid FOREIGN KEY(majorid) REFERENCES major(id)
-- 修改表           添加约束                约束名               外键列(列名)        关联      表名

  关联查询

含义:又称多表查询,当查询的字段来自于多个表时,就会用到连接查询

注意:笛卡尔乘积现象:表1m行,表2n行,结果有 m*n 行

        发生原因:没有有效的连接条件

        如何避免:添加有效的连接条件

按功能分类:

        自连接

        内连接

        外连接 (左外连接、右外连接)

        • 内连接(inner join)

把满足了条件的两张表中的交集数据查询出来

语法:Select 结果 from 1 inner join 2 on 1.column1 = 2.column2

-- 内连接,只把满足条件的筛选出来
SELECT * FROM student,major WHERE majorid = id
SELECT * FROM student INNER JOIN major ON majorid = id

SELECT s.num,s.name,s.gender,s.birthday,m.name FROM student s INNER JOIN major m ON s.majorid = m.id

SELECT
*
FROM student s INNER JOIN major m ON s.majorid = m.id

        • 左外连接(left join)

select 结果 from 表1 left join 2 on 表1.column1 = 2.column2

        • 右外连接(right join)

select 结果 from
表1 right join 表2 on
表1.column1 = 表2.column2

-- 外连接
/*
左外连接
会把左边表中的所有数据查询出来
select 结果 from 表1 left join 表2 on 表1.column1 = 表2.column2

*/
SELECT * FROM student s LEFT JOIN major m ON s.majorid = m.id

/*
右外连接
同理,会把右边表中的所有数据查询出来
select 结果 from 表1 right join 表2 on 表1.column1 = 表2.column2

*/
SELECT * FROM student s RIGHT JOIN major m ON s.majorid = m.id

  子查询

        含义:出现在其他语句中的select语句,称为子查询或内查询;外部的查询语句,称为主查询或外查询

分类:

按子查询出现的位置:

        from后面:支持表子查询

        where:支持标量子查询,列子查询

按功能、结果集的行列数不同:

        标量子查询(结果集只有一行一列)

        列子查询(结果集只有一列多行)

        表子查询(结果集一般为多行多列)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/612894.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LLM记录:五一 Llama 3 超级课堂

LLM记录&#xff1a;五一 Llama 3 超级课堂 想玩大模型&#xff0c;自己又没那个环境&#xff0c;参加五一 Llama 3 超级课堂&#xff0c;简单记录一下llama3-8b的相关体验&#xff0c;实在是邀请不到人&#xff0c;还好后面开放了24G显存&#xff0c;好歹模型能跑起来了&…

TCP UDP

传输层 端口号 tcp udp 网络层 IP地址 IP TCP&#xff0c;UDP 1&#xff0c;TCP是面向链接的协议&#xff0c;而UDP是无连接的协议; 2&#xff0c;TCP协议的传输是可靠的&#xff0c;而UDP协议的传输“尽力而为” 3&#xff0c;TCP可以实现流控&#xff0c;但UDP不行;…

怎么找回回收站里删除的XLS文件?5个恢复方法

我们经常会使用到XLS文件来存储和整理数据。然而有时候由于误操作或不小心&#xff0c;我们可能会将重要的XLS文件删除&#xff0c;并且这些文件可能还被清空出了回收站。面对这种情况许多人会感到焦虑和无助。但是不必过于担心&#xff0c;因为有专门的软件可以帮助我们找回这…

如何使用 ArcGIS Pro 制作地震动画

在做某些汇报的时候&#xff0c;除了图文&#xff0c;如果有动画肯定会成为加分项&#xff0c;这里为大家介绍一下如何使用 ArcGIS Pro 制作地震动画&#xff0c;希望能对你有所帮助。 添加时间 在图层属性内&#xff0c;选择时间选项卡&#xff0c;图层时间选择每个要素具有…

技巧:无脑秒解“已知前序\后序与中序遍历序列,求后序\前序遍历序列”

目录 举例一 1、画坐标系&#xff1a; 2、填表&#xff1a; 3、连线 举例二 1、画坐标系 2、填表 3、连线 原理 这是一个笔试技巧&#xff0c;对代码能力没有什么提高。 可以用&#xff0c;但是代码也要会写&#xff0c;那才是根基。 相对于传统方法&#xff0c;此方法非常的快…

1725 ssm资产管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java ssm资产管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/…

六一儿童节活动方案策划怎么写?

六一儿童节活动方案策划不难&#xff0c;一般看前人策划的案例就可以仿写一篇充满创意的儿童节活动方案。 当然&#xff0c;你也可以照着下面的模版直接写&#xff1a; 成年人的时间是离弦的箭 向着目标,一往无前 孩子的时间是旋转木马 载着今天和明天转啊转啊圈圈 成年人…

公检法部门涉密网文件导出,哪种方案最安全适合?

公检法是我国政法机关的重要组成部分&#xff0c;由于公检法涉及重要案件信息和个人隐私数据&#xff0c;因此&#xff0c;在内部多采用网络隔离技术将网络隔离为两个及以上网络区域&#xff0c;如涉密网、办公网、外联区等。 公检法涉密网是指公安机关、检察机关和法院等执法机…

Mongodb中的索引

目录 索引的类型 单字段索引 符合索引 其他索引 索引的管理操作 查看索引 创建索引 移除索引 索引的使用 执行计划 覆盖的索引查询 索引支持在MongoDB中高效地执行查询。 如果没有索引&#xff0c;MongoDB必须执行全集合扫描&#xff0c;即扫描集合中的每个文档&a…

免费白嫖ChatGPT4(国内可用)

邀请链接 https://burn.hair/register?aff=2MdD网站首页 https://burn.hair使用github账号登录 登录完成之后记得进行签到,签到的token是大家能够聊天的基础,每天进行签到然后就可以免费白嫖ChatGPT4了,一般每天签到,聊天应该是够了的。

小红书搞钱美学课-6.0升级版,账号搭建/爆款创作/工具实战/账号变现篇

让我们用视觉撬动流量 课程体系 334253课程权益(5周服务期) 3节账号运营基础课3节自媒体笔记创作课。4节封面设计实操课2次实操加餐分享5次作业指导(一对一)3次答疑直播 课程大纲 一、账号搭建篇 变现模板、精准定位 二、爆款创作篇爆款选题、首图、文案与脚本、快速涨粉…

自动驾驶TPM技术杂谈 ———— 汽车信息安全通用技术要求

文章目录 介绍术语&缩略语保护对象车内系统车外通信 技术要求原期性要求系统性防御策略要求总则纵深防御要求主动防御要求韧性防御要求 保护维度要求车内系统的保护要求软件系统的保护要求真实性保密性完整性可用性访问可控性抗抵赖可核查性可预防性 电子电气硬件保护要求完…

GPT+Python近红外光谱数据分析

原文链接&#xff1a;GPTPython近红外光谱数据分析https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247603913&idx1&sn6eb8fd6f1abcdd8160815997a13eb03d&chksmfa82172ecdf59e389a860547a238bb86c7f38ae3baa14e97c7490a52ef2a2c206f88d503a5eb&token…

14:java基础-Tomcat-Web容器

文章目录 面试题Web 容器是什么&#xff1f;HTTP 的本质 面试题 Web 容器是什么&#xff1f; 让我们先来简单回顾一下 Web 技术的发展历史&#xff0c;可以帮助你理解 Web 容器的由来。早期的 Web 应用主要用于浏览新闻等静态页面&#xff0c;HTTP 服务器&#xff08;比如Apa…

AMEYA360:太阳诱电叠层压电震动片介绍

触觉感应功能中振动片的定位&#xff0c;“触感”方面&#xff0c; 驱动频带宽、响应速度快的叠层压电振动片则将变得不可或缺。触觉感应功能运用了多种多样的振动片。 “通知”运用了偏心转子马达、线性谐振振动片等电磁式振动片&#xff0c;“力反馈”则在上述电磁式振动片的…

闭散列哈希表

一、什么是 哈希 &#xff1f; 1.1 哈希概念 与 哈希冲突 在正式介绍闭散列哈希之前&#xff0c;我们需要明确 哈希 的概念。 哈希 &#xff1a;构造一种数据存储结构&#xff0c;通过函数 HashFunc() &#xff0c;使 元素的存储位置 与 其对应的键值 建立一一映射关系&…

【Spring】Spring 整合 Junit、MyBatis

一、 Spring 整合 Junit <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache…

云端地球联动大疆机场,支撑矿山高效巡检与智能监测

矿产资源是我国的重要战略性资源。近年来&#xff0c;随着矿山开采深度的逐渐增加&#xff0c;露天矿山边坡滑落等灾害频繁发生&#xff0c;威胁人民群众生命与财产安全。因此&#xff0c;对露天矿边坡进行快速、实时、有效的形变监测和预警已成为当前我国矿山防灾与安全生产的…

【CCF-CSP】202403-4 十滴水

题目描述 十滴水是一个非常经典的小游戏。 小 C 正在玩一个一维版本的十滴水游戏。我们通过一个例子描述游戏的基本规则。 游戏在一个 1c 的网格上进行&#xff0c;格子用整数x(1≤x≤c) 编号&#xff0c;编号从左往右依次递增。网格内 m 个格子里有 1∼41∼4 滴水&#xff0…

Python:如何将嵌套列表展平成单层列表

在Python中&#xff0c;我们经常会遇到需要处理列表的情况&#xff0c;尤其是嵌套列表。嵌套列表就是一个列表中包含另一个或多个列表。有时&#xff0c;我们需要将这些嵌套的列表展平成一个单层的列表&#xff0c;以便于进一步的处理和分析。本文将介绍如何使用Python将嵌套列…