本文已参与「新人创作礼」活动,一起开启掘金创作之路。
一、数据库概述
数据库(DataBase, DB):数据库是按照数据结构来组织、存储和管理数据的仓库。
数据库管理系统(Database Management System, DBMS):专门用于管理数据库的计算机系统软件
数据库应用系统(Database Application System, DBAS):由数据库系统、应用程序系统、用户组成的。
常见的关系数据库
| 数据库系统 | 特点 | 适用场景 | 所属公司 |
|---|---|---|---|
| Oracle | 运⾏稳定,可移植性⾼,功能⻬全,性能超群,但价格昂贵 | ⼤型企业领域 | Oracle |
| MySQL | 开源,体积⼩,速度快 | 中⼩型企业领域 | AB --> SUN --> Oracle |
| DB2 | 速度快、可靠性好,适于海量数据,恢复性极强,但价格昂贵 | ⼤中型企业领域 | IBM |
| SQL Server | 全⾯,效率⾼,界⾯友好,操作容易,但是不跨平台 | 中⼩型企业领域 | MS |
二、SQL 概述
-
结构化查询语言(Structured Query Language)是关系型数据库的标准语言
-
特点:简单、灵活、功能强大
-
分类
-
书写规则
- 大小写不敏感,一般关键字大写,其它小写
- 使用分号分辨语句是否结束
- 合理使用空格和缩进
三、表的概述
-
表是数据库的基本单元,所有数据都是以表格的形式组织,并存储在数据库中。
-
表与数据库的关系:一个数据库有多张表
-
表的特点
- 固定列,任意行
- 列(Field):字段,数据项
- 行:实体,记录
- 表是同类实体的各种属性的集合,每个实体对应表中的一行数据
- 固定列,任意行
-
表和对象的关系(ORM)
ORM思想:将表中的数据查询出来保存到内存中,或者把内存中的数据保存到数据库中,此时就需要将数据表的数据和Java中的对象进⾏映射关联起来
面向对象概念 面向关系概念 类 表 对象 表的行(记录) 属性 表的列(字段)
四、SQL 语法
1. DDL 操作
-- 创建表(最后一行没有逗号)
CREATE TABLE 表名 (列名1 类型1 [约束1], 列名2 类型2 [约束2]...);
-- 删除表
DROP TABLE 表名;
表约束
- not null: 不为空
- default:默认值
- unique:唯一
- primary key:主键,不为空且唯一
- auto_increment:自增长(从1开始,步长为1)
- foreign key:外键
常用类型
| MySQL | Java |
|---|---|
| INT | int/Integer |
| BIGINT | long/Long |
| DATE/DATETIME | java.util.date |
| DECIMAL | Bigdecimal |
| VARCHAR | String |
| BIT | boolean |
2. DML 操作
-- 插入
insert into 表名 (列名1, 列名2...) values (值1, 值2...);
-- 修改(注意加上where条件,否则修改全部)
update 表名 set 列名 = 值 [where 条件];
-- 删除(注意加上where条件,否则删除全部)
delete from 表名 [where 条件];
3. DQL 操作
单表查询
- 字符串和日期需要使用单引号括起来
- 字符串是大小写不敏感的,若要大小写敏感,则需要添加 BINARY 关键字
- 日期是格式大小写敏感的
select 列1, 列2...
from 表名
where 条件
order by 排序列 [升降序]
-- 消除重复数据:distinct
-- 算术运算符:+ - * /
-- 设置别名:as
-- 拼接字符串:concat()
-- 比较运算符:> < >= <= !=或<>
-- 逻辑运算符:and or not
-- 范围和集合:between...and... in ()
-- 判空:is null
-- 模糊匹配:like %匹配零个或多个 _匹配一个
-- 结果排序:order by 默认升序asc,降序desc
多表查询
- 内连接查询
-- 隐式内连接
SELECT [DISTINCT] * | 字段 [别名] [, 字段 [别名], …]
FROM 表名称 [别名], [表名称 [别名], …]
[WHERE 条件(S)/消除笛卡尔积连接]
[ORDER BY 排序字段 [ASC|DESC] [, 排序字段 [ASC|DESC], …]];
-- 显式内连接
SELECT table1.column, table2.column
FROM table1 [INNER] JOIN table2 ON table1.column1 = table2.column2
WHERE 条件
两者区别:
- 显式内连接可以看到 [INNER] JOIN
- 消除笛卡尔积条件使用的是 ON 子句
-
外连接查询
-
左外连接查询(LEFT JOIN):查询显示出左表所有数据,不匹配的使用 NULL 填充
-
右外连接查询(RIGHT JOIN):查询显示出右表所有数据,不匹配的使用 NULL 填充
-
分组查询
-
使用 GROUP BY 关键字
-
不能在 WHERE 子句中对分组限定,限制组需要使用 HAVING 关键字
-
不能在 WHERE 子句中使用统计函数,而在 HAVING 子句可使用统计函数
子查询
-
子查询一般出现在 FROM 或 WHERE 子句中
-
子查询需要使用圆括号括起来
-
将子查询放在比较运算符的右边(增强可读性)
-
子查询在主查询前执行一次,主查询使用子查询的结果;但不宜嵌套过多
-
分类:
-
单行多列,使用单行记录比较运算符:=、>、>=、<、<=、<>
-
多行单列,使用多行比较运算符:
运算符 含义 IN 与列表中的任意一个值相等 ANY 与子查询返回的任意一个值比较 = ANY 此时和 IN 操作符相同 > ANY 大于子查询中最小的数据 < ANY 小于子查询中最大的数据 ALL 与子查询返回的每一个值比较 > ALL 大于子查询中最大的数据 < ALL 小于子查询中最小的数据
-
五、函数
1. 单行函数
- NOW():获取当前时间
- DAY(date):获取date中的天数(1-31)
- HOUR(time):返回 time 中的小时(0-23)
- MINUTE(time):返回 time 中的分钟(0-59)
- MONTH(date):返回 date 中的月份(1-12)
- YEAR(date):返回 date中的年份(1000-9999)
- LAST_DAY(date):获取一个日期或日期时间值,返回该月最后一天对应的值
- DATE_FORMAT(date, format):把日期转换为字符串。
2.多行函数
- COUNT()
- AVG()
- SUM()
- MAX()
- MIN()
不能在 where 子句中使用分组函数,但可以在 having 中使用
五、数据库三范式
第一范式(1NF) :每一个字段都必须满足原子性,是不可再分的数据项。
第二范式(2NF) :在第一范式的基础上,要求非主键字段必须完全依赖主键,即每张表只描述一件事。
第三范式(3NF) :在第二范式的基础上,要求所有非主键字段直接依赖主键,不产生传递依赖。
三大范式其实只是理论上的,在实际开发中,并不一定会这样设计,因为范式越高,表就会越多,这样就会导致表的连接次数增加,从而降低执行速度,所以有时候会用数据冗余来换取执行速度,毕竟还是要满足客户的需求。