Effective SQL-笔记

版权声明:本文为博主原创文章,未经博主允许不得转载。 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子句中的列添加索引,特别是当数据量比较大的时候。
    • 使用OUTER JOIN时避免获取错误的COUNT()
      • OUNT(*)用来统计所有记录的总数,也包括包含空值的记录
      • COUNT()仅仅统计列值不为NULL的记录的总数
    • 测试HAVING COUNT()<某值时包含0值记录
      • 过滤左连接的右侧,将获取相当于内连接的结果。将过滤器移入子查询或在ON条件中过滤右侧。
    • 使用DISTINCT获取不重复的记录
    • 了解如何使用窗口函数
    • 创建行号与排名
    • 创建可移动聚合函数
  • 子查询
    • 了解在何处使用子查询
      • 子查询是嵌套在括号内的拥有完整SELECT语句和名称的一种表达式。
      • 一般来说,在任何使用表名的地方都可以使用子查询。
      • 也可以在任何使用值集的地方使用子查询。
      • 也可以在使用某个列名、文本的位置使用返回单列、零个或一个值得子查询。
    • 了解关联子查询和非关联子查询
    • 使用连接而非子查询创建更高效的查询
  • 获取与分析元数据
    • 了解如何使用系统的查询分析器
      • MySQL使用EXPLAIN
    • 理解执行计划的工作原理

猜你喜欢

转载自blog.csdn.net/t1g2q3/article/details/85369529