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

2024-05-11 15:20

本文主要是介绍章十二、数据库(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,genderFROM studentSELECT NAME,(CASE WHEN height>=1.80 THEN '高个子'WHEN height>=1.60 THEN '正常身高' ELSE '低个子' END) AS height,genderFROM 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_ForeignColumnALTER 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 = idSELECT s.num,s.name,s.gender,s.birthday,m.name FROM student s INNER JOIN major m ON s.majorid = m.idSELECT
*
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:支持标量子查询,列子查询

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

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

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

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

这篇关于章十二、数据库(1) —— 概述、MySQL数据库、SQL、DDL、DML、DQL、多表设计的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/979910

相关文章

mysql索引四(组合索引)

单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引;组合索引,即一个索引包含多个列。 因为有事,下面内容全部转自:https://www.cnblogs.com/farmer-cabbage/p/5793589.html 为了形象地对比单列索引和组合索引,为表添加多个字段:    CREATE TABLE mytable( ID INT NOT NULL, use

mysql索引三(全文索引)

前面分别介绍了mysql索引一(普通索引)、mysql索引二(唯一索引)。 本文学习mysql全文索引。 全文索引(也称全文检索)是目前搜索引擎使用的一种关键技术。它能够利用【分词技术】等多种算法智能分析出文本文字中关键词的频率和重要性,然后按照一定的算法规则智能地筛选出我们想要的搜索结果。 在MySql中,创建全文索引相对比较简单。例如:我们有一个文章表(article),其中有主键ID(

mysql索引二(唯一索引)

前文中介绍了MySQL中普通索引用法,和没有索引的区别。mysql索引一(普通索引) 下面学习一下唯一索引。 创建唯一索引的目的不是为了提高访问速度,而只是为了避免数据出现重复。唯一索引可以有多个但索引列的值必须唯一,索引列的值允许有空值。如果能确定某个数据列将只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该使用关键字UNIQUE,把它定义为一个唯一索引。 添加数据库唯一索引的几种

mysql索引一(普通索引)

mysql的索引分为两大类,聚簇索引、非聚簇索引。聚簇索引是按照数据存放的物理位置为顺序的,而非聚簇索引则不同。聚簇索引能够提高多行检索的速度、非聚簇索引则对单行检索的速度很快。         在这两大类的索引类型下,还可以降索引分为4个小类型:         1,普通索引:最基本的索引,没有任何限制,是我们经常使用到的索引。         2,唯一索引:与普通索引

在线装修管理系统的设计

管理员账户功能包括:系统首页,个人中心,管理员管理,装修队管理,用户管理,装修管理,基础数据管理,论坛管理 前台账户功能包括:系统首页,个人中心,公告信息,论坛,装修,装修队 开发系统:Windows 架构模式:B/S JDK版本:Java JDK1.8 开发工具:IDEA(推荐) 数据库版本: mysql5.7 数据库可视化工具: navicat 服务器:SpringBoot自带 ap

《计算机英语》Unit 1 Computer Overview 计算机概述

期末试卷组成 1、选择20道 2、判断20道 3、词汇翻译(单词+词组,参照课后习题) 4、翻译2道(一道原题,参照作业) SectionA About Computer 关于计算机 algorithm          n.  算法  operate          v.  操作  digital           adj. 数字的  integrated circuit

关于如何更好管理好数据库的一点思考

本文尝试从数据库设计理论、ER图简介、性能优化、避免过度设计及权限管理方面进行思考阐述。 一、数据库范式 以下通过详细的示例说明数据库范式的概念,将逐步规范化一个例子,逐级说明每个范式的要求和变换过程。 示例:学生课程登记系统 初始表格如下: 学生ID学生姓名课程ID课程名称教师教师办公室1张三101数学王老师101室2李四102英语李老师102室3王五101数学王老师101室4赵六103物理陈

数据库期末复习知识点

A卷 1. 选择题(30') 2. 判断范式(10') 判断到第三范式 3. 程序填空(20') 4. 分析填空(15') 5. 写SQL(25') 5'一题 恶性 B卷 1. 单选(30') 2. 填空 (20') 3. 程序填空(20') 4. 写SQL(30') 知识点 第一章 数据库管理系统(DBMS)  主要功能 数据定义功能 (DDL, 数据定义语

【服务器运维】MySQL数据存储至数据盘

查看磁盘及分区 [root@MySQL tmp]# fdisk -lDisk /dev/sda: 21.5 GB, 21474836480 bytes255 heads, 63 sectors/track, 2610 cylindersUnits = cylinders of 16065 * 512 = 8225280 bytesSector size (logical/physical)

给数据库的表添加字段

周五有一个需求是这样的: 原来数据库有一个表B,现在需要添加一个字段C,我把代码中增删改查部分进行了修改, 比如insert中也添入了字段C。 但没有考虑到一个问题,数据库的兼容性。因为之前的版本已经投入使用了,再升级的话,需要进行兼容处理,当时脑子都蒙了,转不过来,后来同事解决了这个问题。 现在想想,思路就是,把数据库的表结构存入文件中,如xxx.sql 实时更新该文件: CREAT