`

sql反模式分析2

 
阅读更多

第八章 多列属性

         目标:存储多值属性  为一个bug设置多个标签

         反模式:创建多个列,为bugs创建tag1,tag2,tag3几个列保存标签。标签必须放于其中一个。

                 1.查询数据,比如搜索这三列,可以使用in语句

                 2.添加和删除  update bugs set tag1=nullif(tag1,'perfor'),tag2=nullif(tag2,'perfor'),tag3=nullif(tag3,'perfor')这个能把值更新到其中为空的那一列,如果都不为空,则不作更新。            3.确保唯一性。无法确保三列的值不一样。

                4.处理不断增长的值集。三列可能不够用,如果在不断的增加列,性能开销将越来越大,而且sql查询更新将越来越复杂。

         解决方案:创建从属表  

         将具有同样意义的值存在同一列中。

   第九章:元数据分类  案例:为一个客户表增加每年的收入情况,每年的收入情况都存在单独的列中,导致每一年就需要新增一个列存储该年的收入。

           目标:支持可扩展性

           反模式: 克隆表与克隆列

                1.不断产生的新表 按照年份对bug表进行拆分,拆成bugs_2008,bugs_2009等多张表,然后按照需要需要修改对应的sql。

               2.管理数据完整性 如果有数据被误写到其他表中,则可能导致统计的一年的bugs数之类的数据不准确。没有任何办法自动对数据和相关表名做限制。但可以在每张表创建的时候使用check的约束。

               3.同步数据  如果发现某条记录原来是在2009这个表中,但时间弄错了,需要修改为2008的,这样订正数据就比较麻烦。需要好几条sql。

              4.确保唯一性。 如果需要做数据迁移,则需要保证记录的主键id值不会与目标表的主键记录冲突。而且对于那些只支持单表ID唯一的数据库产品,实现这样的功能还需要定义一张额外的表存储产品主键的值。

              5.跨表查询  如果需要查询所有的bugs数,则需要把每个表用union进行查询.

              6.同步元数据.如果值在某个表增加一列,其他表没有增加,则联合查询不用使用*,需要列出所有列名.

             7.管理引用完整性. 其他表就不能引用bugs的外键了,因为有多个bugs表.

             8.标识元数据分裂列 如果有其他表保护bugx_fiexd_2008,bugx_fixed_2009,则以后肯定需要增加bugx_fixed_2010.

          解决方案: 手工分割表的一个合理使用场景是归档数据。把没用的数据迁移到历史表中。

               1.使用水平分区。MYSQL5.1所支持的分区特性,在createtable时执行pritition by hash(year(date)reported)) partitions 4.

               2.使用垂直分区。根据列来对表进行拆分。将一些BLOB或者TEXT字段拆分到其他表存储。

               3.解决元数据分裂列。创建关联表。

          别让数据繁衍元数据。

 

   物理数据库设计反模式

       第10章:取整错误。

          目标:使用小数取代整数,运算结果必须准确。

          反模式:使用float类型

                  无限循环小数无法使用存储表示。

                  在SQL中使用FLOAT类型,放大查询结果差异比较大。无法使用比较操作,必须使用近似相等查询,但是阀值需要使用合适。

          解决方案:oracle的FLOAT类型表示的是精确值,而BINARY_FLOAT则是非精确值。

                   使用NUMERIC类型。SQL的NUMERIC或者DECIMAL类型来代替FLOAT存储小数。 NUMERIC(9,2) 精度,刻度 这样仍然无法存储无限精度的数据。

          尽可能不要使用浮点数。

     第11章:每日新花样  需要给称呼列加入约束指定这些候选值

          目标:限定列的有效值  希望数据库能够拒绝无效值的输入

          反模式:在列定义上指定可选值。很多数据库设计人员习惯在定义列的时候指定所有可选的有效数据。

                   create table bugs(status varchar(20) check(status in('new','in','fixed')).

                   mysql也支持用ENUM关键词来约束。但是mysql存储的是序数,而非字符串。

                  1.中间的是哪个  无法获得status列中值的枚举列表,如果使用distinct来查询bugs表,但是刚开始没数据,查询的结果为空。如果使用INFORMATION_SHEMA系统视图,则还需要解决解决格式。

                 2.添加新口味。添加或者删除一个候选值。没有什么语法支持从ENUM或者check约束中添加或者删除一个值。只能用一个新的集合重新定义这一列。一些数据库只有在表为空表是才能改变某一列的数据。那么就需要先将数据导出,改变之后再导入。

                 3.老的口味永不消失。旧的值无法删除。

                4.可一致性地下。check约束,域和UDT在各种数据库支持形式不同意。ENUM是mysql特有的特性。

        解决方案:在数据中指定值,通过创建一张检查表bug_status,定义status列中出现的候选值,然后定义一个外键约束。

                 1.查询候选值集合。直接查询检查表。

                 2.更新检查表中的数据。插入更新操作很方便。

                 3.支持废弃数据。可以通过在bug_status表增加一列来表示是否已经弃用。

                4.良好的可移植性。

        在验证固定集合的候选值时使用元数据。在验证可变集合的候选值时使用数据。

     第12章:幽灵文件  只保存数据库文件,没有保存数据库中保存的文件路径对应的数据库外的文件。

           目标:存储图片或其他多媒体大文件。

           反模式:假设必须使用文件系统,可以使用BLOB字段存储文件,或者只在数据库存储文件路径。

                  1.文件不支持DELETE  垃圾回收问题。如果图片在数据库之外,删除某条记录之后无法自动将对应文件删除。

                  2.文件不支持事务隔离。数据库事务在提交之前,所有改变对外都不可见。但是数据库之外的文件改变则立刻体现到外界。

                  3.文件不支持回滚操作。数据库可以回滚,但是文件系统无法回滚。

                 4.文件不支持数据库备份工具。

                 5.文件不支持SQL的访问权限设置。

                 6.文件不是SQL数据类型。无法验证文件路径是否正确。

          解决方案:在需要时使用BLOB类型。

                   MYSQL MEDIUMBLOB:16M oracle:LONGRAW 2GB

                   MYSQL有load_file()用来读取一个文件存储到BLOB列

          存储在数据库之外的数据不由数据库管理。

    第13章: 乱用索引

          目标:优化性能

          反模式:无规划的使用索引

                  1.无索引

                  2.索引过多  不需使用的索引无法获得任何好处,只有开销。

                  3.索引也无能为力 常犯的错误是进行一个无法使用索引的查询

          解决方案:所有不重复的值的记录和总计数条数之比越低,索引的效率就越低。

                 1.测量  ORACLE:TKProf mysql:慢查询日志

                 2.解释  查询执行计划

                 3.挑选   索引覆盖

                 4.测试 

                 5.优化  索引预载入:mysql使用 load index into cache语句。

                 6.重建:更新或者删除导致索引修改,需要定期对索引进行维护。mysql:analyze table or optimize table oracle:alter index rebuild

         了解你的数据,了解你的查询请求,然后MENTOR你的索引。

 

  查询反模式

     第14章:对未知的恐惧。

           目标:辨别悬空值 SQL支持一个特殊的空值,NULL。

              增加记录时使用NULL代替那些还不确定的值。

             一个给定的列如果没有合适的值,可以使用NULL代替。

             当传入参数无效时,一个函数的返回值也可以是NULL。

            在外联结查询中,NULL被用来当做未匹配的列的占位符。

         反模式:将NULL作为普通的值,反之亦然。

             1.在表达式中使用NULL。 如果某个字段为NULL,表达式结果也是NULL。

             2.搜索允许为空的列: select * from bugs where aggin_to=123 或者select * from bugs where not(assin_to=123)都不会返回这列为null的值。

                                  而且查询null或者非null是不能用where assin_to=NULL或者assin_to<>NULL。使用is null

             3.在查询参数中使用NULL 不能在查询参数assin_to=?传入NULL值

             4.避免上述问题:使用默认值来代替NULL,按时查询计算时仍然需要制定<>默认值

        解决方案:将NULL视为特殊值

               1.在标量表达式中使用NULL 表达式中一个值为NULL,则结果就为NULL。

               2.在布尔表达式中使用NULL。

              3.检索NULL值。SQL-99中额外定义了一个比较断言 IS DISTINCT FROM

              4.声明NOT NULL列。

             5.动态默认值。使用COALESCE()函数返回一个非NULL的参数。

         使用NULL来表示任意类型的悬空值。

   第15章:模棱两可的分组

       目标:获取每组的最大值

       反模式: 引用非分组列

               1.单值规则 一个分组只能返回单一的值 

               2.我想要的查询 如果分组后通过max获得的有两列的值是一样的,那么就无法返回哪条记录的其他列。不能使用max和min两个聚合函数定位到不同的记录。

       解决方案: 无歧义的使用列

               1.只查询功能依赖的列;

              2.使用关联子查询

              3.使用衍生表

              4.使用join 

              5.对额外的列使用聚合函数

             6.连接同组所有值 mysql使用GROUP_CONCAT()函数将这一组中所有的值连在一起。

        遵循单值规则,避免获得模棱两可的查询结果。

    第16章:随机选择  设计一个随机广告展示的查询

        目标:获得样坏死记录

       反模式:随机排序 select * from bugs order by rand() limit 1; 使用rand()简单,但是无法利用索引,因为没有索引会基于随机函数返回的值,导致一次全表排序。

       解决方案:没有具体的顺序。

                 1.从1到最大值之间随机选择  select b1.* from bugs as b1 join(select(ceil(rand() *(select max(bug_id) from bugs)) as rand_id) as b2 on(b1.bug_id=b2.bug_id);

                 2.选择下一个最大值。 select b1.* from bugs as b1 join(select(ceil(rand() *(select max(bug_id) from bugs)) as rand_id) as b2 where b1.bug_id>=b2.bug_id order by b1.bug_id limit 1;

                3.获得所有键值,随机选择一个。 程序选择一个,查询两次

                4.使用偏移量选择随机行。

                5.专有解决方案。SQL server 使用tablesample函数。 oracle使用sample函数。

        有些查询是无法优化的,换种方式试试看。

     第17章:可怜人的搜索引擎

         目标:全文检索

         反模式:模糊匹配断言 SQL提供了模式匹配断言来比较字符串,最常用的就是like语句。还有REGEXP正则表达式匹配。 不过缺点当然就是性能问题了。

         解决方案:使用正确的工具

                  1.数据库扩展 mysql能够对char,varchar,text定义一个全文索引,使用match进行全文查询.oracle使用context支持,然后通过contains()操作符搜索.sqlserver和postgreSQL也有对全文索引的支持.

                2.第三方搜索引擎:Sphinx search lucene

         你不必使用SQL来解决所有的问题.

      第18章:意大利苗条查询

          目标:减少sql查询数量

          反模式:使用一部操作解决复杂问题

                  1.副作用 查询多少bug已经修复,多少bug还打开。select p.product_id,count(f.bug_id) as count_fixed,count(o.bug_id) as count_open from bugsproduct p left outer join bugs f on(p.bug_id=f.bug_id and f.status='fixed') left outer join bugx o on(p.bug_id=o.bug_id and o.status='open') where p.product_id=1 group by p.product

                    这条sql查询出来count_fixed和count_open都是84,而实际上12个fixed,7个open,刚好84是12*7 这种查询是有问题。

         解决方案:分而治之

                 1.分两条sql来查询 。select p.product_id,count(f.bug_id) as count_fixe from bugsproduct p left outer join bugs f on(p.bug_id=f.bug_id and f.status='fixed') where p.product_id=1 group by p.product 。select p.product_id,count(o.bug_id) as count_open from bugsproduct p left outer join bugx o on(p.bug_id=o.bug_id and o.status='open') where p.product_id=1 group by p.product

                 2.寻找union标记  根据单个结果集再使用union all合并。

          尽管SQL支持用一行代码解决复杂的问题,但也别做不切实际的事情。

       第19章:隐式的列  联合查询如果两个表有列名一样的列,则会只取其中一个。

            目标:减少输入  可以使用*获取所有列

            反模式:捷径会让你迷失方向

                    1.破坏代码重构,比如增加一列之后,原来insert没有指定列名的则现在会报错,少一列的值了。 select也一样,如果删除一列后,应用代码获取列的可能也会出错。

                    2.隐藏的开销 获取一些没用的列,会增加网络开销和性能。

            解决方案:明确列出列名

           随便拿,但是拿了就必须吃掉。

 

    应用程序开发反模式

           第20章 明文密码

              目标:恢复和重置密码  现在一般都是使用邮箱让用户恢复和重置密码

              反模式:使用明文存储密码

                      1.存储密码 sql被劫持 

                      2.验证密码

                      3.在email中发送密码,email有可能被劫持

             解决方案:先哈希,后存储

                    mysql扩展支持SHA2()函数返回256位的哈希串

                    哈希暴力破解,可以先加密后再进行哈希。

                    在SQL中隐藏密码,在程序中生成哈希串之后,在sql中直接使用哈希串。

                   重置密码,而非恢复密码。

            如果密码对你可读,那么对于攻击者也是如此。

          第21章:SQL注入

              目标:编写SQL动态查询

              反模式:将未经验证的输入作为代码执行

              解决方案:不相信任何人

                    1.过滤输入内容。

                    2.参数化动态内容

                    3.给动态输入的值加引号

                    4.将用户与代码隔离

                   5.找个可靠的人来帮你审查代码

              让用户输入内容,但永远别让用户输入代码。

          第22章:伪键洁癖

                目标:整理数据

                反模式:填充角落

                     1.不按照顺序分配编号 

                    2.为现有行重新编号

                    3.制造数据差异 重新主键不是一个好习惯

               解决方案:1.定义行号。2.使用GUID 太长,随机的,需要16字节

               将伪键当做行的唯一性标识,但他们不是行号。

         第23章:非礼勿视

              目标:写更少的代码

              反模式:无米之炊 忽略数据库API的返回值,将程序代码跟SQL混在一起

                  1.没有诊断的诊断 在多条sql顺序执行过程中,最好对结果进行诊断,保证错误能够快速定位。

                  2.字里行间 花费大量时间调试生成sql字符串的代码

              解决方案:优雅的从错误中恢复

                 1.保持节奏 检查数据库API的返回状态和异常。

                 2.回溯你的脚步。sql语句记录,输出,调试。

          发现并解决代码中的问题已经很苦难了,就别再盲目的干了。

        第24章:外交豁免权

              目标:最佳实践 使用版本控制工具管理源代码,编写单元测试脚本;编写文档,代码注释。

              反模式:将SQL视为二等公民。

0
11
分享到:
评论

相关推荐

    《SQL反模式》PDF版本下载.txt

    根据提供的文件信息,我们可以推断出这是一篇关于获取《SQL反模式》这本书PDF版本的文章。下面将基于这个前提,详细展开与该书相关的知识点。 ### SQL反模式概述 SQL反模式是指在数据库设计、查询编写及维护过程中...

    SQL反模式.pdf

    ### SQL反模式详解 #### 一、引言 《SQL反模式》这本书旨在帮助数据库开发者和管理者识别并避免常见的SQL编程陷阱。通过一系列具体案例分析,本书深入浅出地讲解了如何避开那些容易忽视但可能导致严重后果的问题。...

    SQL反模式pdf

    2. **常见SQL反模式实例**: - **滥用存储过程**:过度依赖存储过程可能会降低系统的可维护性和可扩展性。 - **不正确的规范化**:过度规范化或规范化不足都会导致问题,如数据冗余、更新异常等。 - **不合适的...

    SQL反模式 源代码

    《SQL反模式 源代码》是一份宝贵的资源,它涵盖了数据库设计和SQL查询中常见的错误做法,也就是所谓的“反模式”。这些反模式是通过实际案例来展示的,旨在帮助数据库开发者和管理员避免在设计、优化和维护数据库时...

    SQL反模式 中文版

    《SQL反模式》是一本深入探讨SQL数据库设计与优化的经典之作。这本书中文版的高清PDF电子书,旨在帮助读者理解并避免在数据库设计过程中常见的错误和不良实践,从而提升数据库性能,确保数据的一致性和准确性。 SQL...

    SQL反模式PDF

    《SQL反模式》是一本深度探讨数据库设计问题的权威教材,尤其在数据库设计领域具有极高的价值。这本书通过揭示常见的SQL设计错误,也就是所谓的“反模式”,帮助读者避免在实际工作中踩坑,提升数据库设计的效率和...

    SQL反模式(中文完整版)

    《SQL反模式》是数据库设计和SQL编程领域中一本极具影响力的书籍,它深入探讨了在实践中容易出现的问题以及如何避免这些“反模式”。SQL反模式指的是在使用SQL进行数据库设计和查询时,可能导致性能低下、可维护性差...

    SQL 反模式

    了解并避免SQL反模式对于提升数据库性能、增强代码可维护性具有重要意义。 #### 二、SQL反模式概述 SQL反模式是指在SQL查询编写、数据库设计或管理过程中出现的一些不良实践或错误的做法,这些做法可能会导致性能...

    sql反射模式完整版

    SQL反射模式,是一种在数据库设计和使用中应避免...《SQL反模式(中文完整版)》这本书可能提供了深入的案例分析和解决方案,帮助读者识别并解决这些问题。阅读并应用书中的知识,可以提升数据库设计和管理的专业水平。

    binlog2sql-master.zip

    binlog2sql是一款能够将MySQL的binlog日志反解析为SQL插入语句的工具,对于数据恢复和数据迁移有着显著的优势。 ### MySQL Binlog介绍 MySQL的binlog是一种记录所有改变数据库状态的非归档日志。它记录了对数据库...

    sql2005性能sql 性能优化

    应根据查询模式分析表的访问频率和数据分布,创建合适的聚集索引和非聚集索引。同时,避免过度索引,因为索引维护也会增加写操作的开销。 2. **查询优化**:编写高效的SQL语句是性能优化的基础。避免全表扫描,使用...

    SQL 教案.rar

    本教程针对SQL Server 2000,旨在帮助学习者掌握其核心功能和应用技巧,从而能够有效地进行数据存储、管理和分析。 1. **SQL基础**:SQL(Structured Query Language)是用于管理和处理关系数据库的标准语言。在SQL...

    关于SQL优化的电子书

    1. **性能分析工具**:大多数现代数据库管理系统提供了内置的性能分析工具,如SQL Server Profiler、Oracle的SQL Trace和AWR报告、MySQL的slow query log等,帮助识别慢查询和瓶颈。 2. **在线资源**:O’Reilly...

    SQL.Antipatterns.zip_SQL Anti-patterns_SQL Antipatterns

    SQL反模式通常涉及到以下几个方面: 1. **数据冗余**:书中可能会提到过度依赖冗余数据,如在多个表中存储相同信息,这可能导致数据不一致性和维护难题。正确的做法是遵循数据库设计的第三范式(3NF)或更高的范式...

    基于SQL数据库的性能优化问题分析.rar

    本资料"基于SQL数据库的性能优化问题分析"深入探讨了如何通过一系列策略和技巧提升SQL数据库的运行效率。 一、SQL查询优化 SQL查询优化是性能优化的基础,主要涉及以下方面: 1. **查询语句重构**:避免全表扫描,...

    SQL Server 高级编程

    《SQL Server 高级编程》是一本专为SQL Server数据库管理员和开发人员设计的深入指南,旨在帮助读者提升在SQL Server平台上的技能和知识。这本书不仅涵盖了基础的SQL语法和查询,更深入到数据库设计、性能优化、安全...

    Microsoft SQL Server 2008技术内幕:T-SQL查询(第二卷)

    《Microsoft SQL Server 2008技术内幕:T-SQL查询》内容丰富、文字简洁明快,列举的实例具有一定的难度,而且实用性很强,可以把它们作为解决实际问题的标准模式。阅读《Microsoft SQL Server 2008技术内幕:T-SQL...

    sqlcheck:自动识别SQL查询中的反模式

    SQL反模式是指在数据库设计或SQL查询中常见的不良实践,可能导致性能下降、数据一致性问题或难以维护的情况。SQLcheck的工作原理是通过对SQL查询进行语法分析和执行计划评估,检测出潜在的反模式,如过度复杂的联接...

    SQL sever中文参考手册

    2. **SQL Server架构**:SQL Server由多个组件构成,包括数据库引擎、Analysis Services、Integration Services和Reporting Services等。了解这些组件的功能和相互作用对于有效管理数据库至关重要。 3. **安全性与...

Global site tag (gtag.js) - Google Analytics