版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/t1g2q3/article/details/85369529
- 数据模型设计
- 确保所有表都有主键
- 建议不要使用复合主键
- 定义主键时,大多数数据库系统都会同时创建唯一索引,唯一索引创建在多列上会对数据库造成额外的负担。
- 使用主键做连接查询很常见,但是在具有多个列的主键上这样做会很复杂,效率也更低。
- 建议不要使用复合主键
- 避免存储冗余数据
- 数据库规范化的目标是消除冗余数据,并在处理数据时最小化资源消耗。
- 通过消除冗余数据,避免在插入、更新和删除时出现异常。
- 通过消除冗余数据,尽量减少数据的不一致性。
- 消除重复数据组
- 数据库规范化的目标是消除重复的数据组,并尽可能减少表结构的更改。
- 通过删除重复的数据组,可以使用唯一索引来防止意外的重复数据,并大大简化查询语句。
- 每列只存储一个属性
- 正确的表设计是为每个属性分配单独的列,当列包含多个属性时,搜索和分组就困难了。
- 针对不同的业务,比如有过滤列中的某部分数据,可能会决定列的粒度。
- 一般情况下不要存储计算列
- 因为在每次更新、插入或删除数据时,都必须确保其值被重新计算。
- 确保表间关系的合理性
- 业务是衡量数据建模是否正确的标准。
- 当第三范式不够用时,使用更多范式
- 大多数数据模型已经满足了较高的范式。因此,只需要注意某些明星违反高级范式的情况,例如包含复合键的表或者参与了多个多对多关系的表。
- 非规范化数据仓库
- 完全规范化的表有一个问题是:规范化后的数据意味着需要在表之间做连接。连接越多,查询优化器就越难找到最佳的查询执行计划。
- 非规范化的数据库在高复合读取操作下表现很好,因为数据集中在少数几张表里面,几乎很少甚至不需要做表连接,所以查询会很快。
- 确保所有表都有主键
- 可编程性与索引
- 创建索引时空置的影响
- MySQL的主键不允许包含空值,但是在创建索引时,会将空值视为不相等,因此可以在具有UNIQUE索引的列上存储包含多条包含空值得记录。一般情况下应该禁止使用NULL。
- 创建索引时谨慎考虑以最小化索引和数据扫描
- 聚簇索引是按照创建索引时列的顺序来物理地排列表的内容,所以每张表最多只能有一个聚簇索引。非聚簇索引可能与表的物理顺序不同。非聚簇索引的叶级别由索引键和指向数据块的标记组成,而不是直接包含数据。
- 索引提供索引数据的有序表示
- where子句中的列是否包含在索引中会对查询性能产生影响。
- select子句中的列是否包含在索引中会对查询性能产生影响。
- 连接查询中的列是否被索引可能会影响查询的效率。
- 索引也能对order by子句的性能产生影响。
- 多个索引的存在可能会对写入操作产生影响。
- 使用申明式约束替代编码校验
- 任何数据操作都会检查所有约束:
- NOT NULL
- UNIQUE
- PRIMARY KEY
- FOREIGN KEY
- CHECK
- DEFAULT:通常与NOT NULL约束组合。
- 任何数据操作都会检查所有约束:
- 了解数据库使用的方言
- 了解何时在索引中使用计算结果
- 创建索引时空置的影响
- 当你不能改变设计时
- 使用视图来简化不能更改的设计
- 使用Union和Union All实现非规范化数据的列转行
- 过滤与查找数据
- 使用关系代数
- 查找不匹配或缺失的记录
- 使用NOT EXISTS通常比使用NOT IN更快。
- 使用CASE
- 使用多条件查询
- 使用INNER JOIN或OUTER JOIN与IS NULL结合
- 使用IN或NOT IN与子查询
- 使用EXISTS或NOT EXISTS与子查询
- 使用除操作
- 书写可参数化检索的查询
- 以下运算符通常可以被认为是可参数化检索的:
- =
- >
- <
- >=
- <=
- BETWEEN
- LIKE(不包含前导通配符)
- IS (NOT) NULL
- 以下情况会导致非参数化搜索:
- 在Where子句条件中对一个或多个字段使用函数。
- 对WHERE子句中的字段执行算数计算。
- 使用如LIKE “%something%”通配符搜索查询
- 以下运算符通常可以被认为是可参数化检索的:
- 正确定义左连接的右侧
- 第一张表的过滤条件写在WHERE子句中
- 其余各张表的过滤条件写在ON子句中
- 聚合
- 理解GROUP BY的原理
- FROM子句生成数据集
- WHERE子句过滤由FROM子句生成的数据集
- GROUP子句聚合由WHERE子句过滤的数据集
- HAVING子句过滤由GROUP BY子句聚合的数据集
- SELECT子句转换过滤的聚合数据集
- ORDER BY子句对变换后的数据进行排序
- SELECT子句中没有使用聚合函数或计算的列必须出现在GROUP BY子句中
- 简化GROUP BY子句
- 仅在GROUP BY子句中包含真正需要的列是编写聚合查询的一种好习惯
- 如果需要其他列的详细信息,把他们放到外部查询而不是GROUP BY子句中
- 使用HAVING
- 在分组之前使用WHERE子句过滤记录,分组后使用HAVING过滤记录
- 避免使用GROUP BY来查找最大值和最小值
- 对于数据量的的情况要避免使用聚合和GROUP BY
- 主表连接到自身要使用LEFT JOIN
- 将GROUP BY中的每一列都变成ON子句的一部分并使用=连接
- MAX()或MIN()子句中的列将成为ON子句的一部分并且使用<或>连接。
- 应当为ON子句中的列添加索引,特别是当数据量比较大的时候。
- 对于数据量的的情况要避免使用聚合和GROUP BY
- 使用OUTER JOIN时避免获取错误的COUNT()
- OUNT(*)用来统计所有记录的总数,也包括包含空值的记录
- COUNT()仅仅统计列值不为NULL的记录的总数
- 测试HAVING COUNT()<某值时包含0值记录
- 过滤左连接的右侧,将获取相当于内连接的结果。将过滤器移入子查询或在ON条件中过滤右侧。
- 使用DISTINCT获取不重复的记录
- 了解如何使用窗口函数
- 创建行号与排名
- 创建可移动聚合函数
- 理解GROUP BY的原理
- 子查询
- 了解在何处使用子查询
- 子查询是嵌套在括号内的拥有完整SELECT语句和名称的一种表达式。
- 一般来说,在任何使用表名的地方都可以使用子查询。
- 也可以在任何使用值集的地方使用子查询。
- 也可以在使用某个列名、文本的位置使用返回单列、零个或一个值得子查询。
- 了解关联子查询和非关联子查询
- 使用连接而非子查询创建更高效的查询
- 了解在何处使用子查询
- 获取与分析元数据
- 了解如何使用系统的查询分析器
- MySQL使用EXPLAIN
- 理解执行计划的工作原理
- 了解如何使用系统的查询分析器