数据库范式
1NF:属性不可再分割,字段只能是一个值,不能再分为多个其他字段。
2NF:非主键字段之间不能存在依赖关系,必须完全依赖于主键。
3NF:所有非主键字段必须直接依赖于主键,不能存在传递依赖。
【注意】阿里巴巴开发手册这样说到:不得使用外键与级联,一切外键概念必须在应用层解决。
说明: 以学生和成绩的关系为例,学生表中的 student_id 是主键,那么成绩表中的 student_id 则为外键。如果更新学生表中的 student_id,同时触发成绩表中的 student_id 更新,即为级联更新。外键与级联更新适用于单机低并发,不适合分布式、高并发集群;级联更新是强阻塞,存在数据库更新风暴的风险;外键影响数据库的插入速度
数据库设计通常分为哪几步?
-
需求分析 : 分析用户的需求,包括数据、功能和性能需求。
-
概念结构设计 : 主要采用 E-R 模型进行设计,包括画 E-R 图。
-
逻辑结构设计 : 通过将 E-R 图转换成表,实现从 E-R 模型到关系模型的转换。
-
物理结构设计 : 主要是为所设计的数据库选择合适的存储结构和存取路径。
-
数据库实施 : 包括编程、测试和试运行。
-
数据库的运行和维护 : 系统的运行与数据库的日常维护。
NoSQL
概念:非关系型数据库,主要针对键值、文档以及图形类型数据存储。
NoSQL数据库代表:HBase、MongoDB、Redis
SQL 数据库 | NoSQL 数据库 | |
---|---|---|
数据存储模型 | 结构化存储,具有固定行和列的表格 | 非结构化存储。文档:JSON 文档,键值:键值对,宽列:包含行和动态列的表,图:节点和边 |
发展历程 | 减少数据重复 | 提升可扩展性,减少大规模数据的存储成本 |
例子 | Oracle、MySQL、Microsoft SQL Server、PostgreSQL | 文档:MongoDB、CouchDB,键值:Redis、DynamoDB,宽列:Cassandra、 HBase,图表:Neo4j、 Amazon Neptune、Giraph |
ACID 属性 | 提供原子性、一致性、隔离性和持久性 (ACID) 属性 | 通常不支持 ACID 事务,为了可扩展、高性能进行了权衡,少部分支持比如 MongoDB 。不过,MongoDB 对 ACID 事务 的支持和 MySQL 还是有所区别的。 |
性能 | 性能通常取决于磁盘子系统。要获得最佳性能,通常需要优化查询、索引和表结构。 | 性能通常由底层硬件集群大小、网络延迟以及调用应用程序来决定。 |
扩展 | 垂直(使用性能更强大的服务器进行扩展)、读写分离、分库分表 | 横向(增加服务器的方式横向扩展,通常是基于分片机制) |
用途 | 普通企业级的项目的数据存储 | 用途广泛比如图数据库支持分析和遍历连接数据之间的关系、键值数据库可以处理大量数据扩展和极高的状态变化 |
游标
-
应用场景:批量更新/删除数据,逐行处理查询结果。
-
使用游标的几个明确步骤:
- 声明游标,这个过程世纪没有检索数据,它只是定义要使用的
SELECT
语句和游标选项。 - 一旦声明,就必须打开游标以供使用,这个过程用前面定义的
SELECT
语句把数据世纪检索出来。 - 对于填有用的游标,根据需要取出各行。
- 结束游标使用时,必须关闭 & 释放 游标。
- 声明游标,这个过程世纪没有检索数据,它只是定义要使用的
触发器
-
应用场景:
-
优点:
- 捕获数据库层中业务逻辑中的错误。
- 检查数据完整性。
-
说明:
-
trigger_name
:触发器名 -
trigger_time
: 触发器的触发时机。取值为BEFORE
或AFTER
。 -
trigger_event
: 触发器的监听事件。取值为INSERT
、UPDATE
或DELETE
。 -
table_name
: 触发器的监听目标。指定在哪张表上建立触发器。
-
FOR EACH ROW
: 行级监视,Mysql 固定写法,其他 DBMS 不同。 -
trigger_statements
: 触发器执行动作。是一条或多条 SQL 语句的列表,列表内的每条语句都必须用分号
;` 来结尾。
-
当触发器的触发条件满足时,将会执行 BEGIN
和 END
之间的触发器执行动作。
书写高质量SQL建议
- 查询最大/小记录,建议使用
limit 1
- 尽量避免在
where
子句中使用or
来连接条件(使用or可能会使索引失效,从而全表扫描) - like模糊查询
select userId,namefromuserwhere userId like'123%';
# 反例:%123 --> 导致索引失效
- Inner join 、left join、right join,优先使用Inner join,如果是left join,左边表结果尽量小
理由:
- 如果inner join是等值连接,或许返回的行数比较少,所以性能相对会好一点。
- 使用了左连接,左边表数据结果尽量小,条件尽量放到左边处理,意味着返回的行数可能比较少。
- 慎用distinct关键字,字段很多的请款下,会大大降低查询效率。