第1章 引言
1.1 谁需要这本书
1.2 本书内容
1.2.1 本书结构
1.2.2 反模式分解
1.3 本书未涉及的内容
1.4 规约
1.5 范例数据库
1.6 致谢
第一部分 逻辑型数据库设计反模式
第2章 乱穿马路
2.1 目标:存储多值属性
2.2 反模式:格式化的逗号分隔列表
2.2.1 查询指定账号的产品
2.2.2 查询指定产品的账号
2.2.3 执行聚合查询
2.2.4 更新指定产品的账号
2.2.5 验证产品ID
2.2.6 选择合适的分隔符
2.2.7 列表长度限制
2.3 如何识别反模式
2.4 合理使用反模式
2.5 解决方案:创建一张交叉表
2.5.1 通过账号查询产品和反过来查询
2.5.2 执行聚合查询
2.5.3 更新指定产品的相关联系人
2.5.4 验证产品ID
2.5.5 选择分隔符
2.5.6 列表长度限制
2.5.7 其他使用交叉表的好处
第3章 单纯的树
3.1 目标:分层存储与查询
3.2 反模式:总是依赖父节点
3.2.1 使用邻接表查询树
3.2.2 使用邻接表维护树
3.3 如何识别反模式
3.4 合理使用反模式
3.5 解决方案:使用其他树模型
3.5.1 路径枚举
3.5.2 嵌套集
3.5.3 闭包表
3.5.4 你该使用哪种设计
第4章 需要ID
4.1 目标:建立主键规范
4.2 反模式:以不变应万变
4.2.1 冗余键值
4.2.2 允许重复项
4.2.3 意义不明的关键字
4.2.4 使用USING关键字
4.2.5 使用组合键之难
4.3 如何识别反模式
4.4 合理使用反模式
4.5 解决方案:裁剪设计
4.5.1 直截了当地描述设计
4.5.2 打破传统
4.5.3 拥抱自然键和组合键
第5章 不用钥匙的入口
5.1 目标:简化数据库架构
5.2 反模式:无视约束
5.2.1 假设无瑕代码
5.2.2 检查错误
5.2.3 “那不是我的错!”
5.2.4 进退维谷
5.3 如何识别反模式
5.4 合理使用反模式
5.5 解决方案:声明约束
5.5.1 支持同步修改
5.5.2 系统开销过度?不见得
第6章 实体-属性-值
6.1 目标:支持可变的属性
6.2 反模式:使用泛型属性表
6.2.1 查询属性
6.2.2 支持数据完整性
6.2.3 无法声明强制属性
6.2.4 无法使用SQL的数据类型
6.2.5 无法确保引用完整性
6.2.6 无法配置属性名
6.2.7 重组列
6.3 如何识别反模式
6.4 合理使用反模式
6.5 解决方案:模型化子类型
6.5.1 单表继承
6.5.2 实体表继承
6.5.3 类表继承
6.5.4 半结构化数据模型
6.5.5 后处理
第7章 多态关联
7.1 目标:引用多个父表
7.2 反模式:使用双用途外键
7.2.1 定义多态关联
7.2.2 使用多态关联进行查询
7.2.3 非面向对象范例
7.3 如何识别反模式
7.4 合理使用反模式
7.5 解决方案:让关系变得简单
7.5.1 反向引用
7.5.2 创建交叉表
7.5.3 设立交通灯
7.5.4 双向查找
7.5.5 合并跑道
7.5.6 创建共用的超级表
第8章 多列属性
8.1 目标:存储多值属性
8.2 反模式:创建多个列
8.2.1 查询数据
8.2.2 添加及删除值
8.2.3 确保唯一性
8.2.4 处理不断增长的值集
8.3 如何识别反模式
8.4 合理使用反模式
8.5 解决方案:创建从属表
第9章 元数据分裂
9.1 目标:支持可扩展性
9.2 反模式:克隆表与克隆列
9.2.1 不断产生的新表
9.2.2 管理数据完整性
9.2.3 同步数据
9.2.4 确保唯一性
9.2.5 跨表查询
9.2.6 同步元数据
9.2.7 管理引用完整性
9.2.8 标识元数据分裂列
9.3 如何识别反模式
9.4 合理使用反模式
9.5 解决方案:分区及标准化
9.5.1 使用水平分区
9.5.2 使用垂直分区
9.5.3 解决元数据分裂列
第二部分 物理数据库设计反模式
第10章 取整错误
10.1 目标:使用小数取代整数
10.2 反模式:使用FLOAT类型
10.2.1 舍入的必要性
10.2.2 在SQL中使用FLOAT
10.3 如何识别反模式
10.4 合理使用反模式
10.5 解决方案:使用NUMERIC类型
第11章 每日新花样
11.1 目标:限定列的有效值
11.2 反模式:在列定义上指定可选值
11.2.1 中间的是哪个
11.2.2 添加新口味
11.2.3 老的口味永不消失
11.2.4 可移植性低下
11.3 如何识别反模式
11.4 合理使用反模式
11.5 解决方案:在数据中指定值
11.5.1 查询候选值集合
11.5.2 更新检查表中的值
11.5.3 支持废弃数据
11.5.4 良好的可移植性
第12章 幽灵文件
12.1 目标:存储图片或其他多媒体大文件
12.2 反模式:假设你必须使用文件系统
12.2.1 文件不支持DELETE
12.2.2 文件不支持事务隔离
12.2.3 文件不支持回滚操作
12.2.4 文件不支持数据库备份工具
12.2.5 文件不支持SQL的访问权限设置
12.2.6 文件不是SQL数据类型
12.3 如何识别反模式
12.4 合理使用反模式
12.5 解决方案:在需要时使用BLOB 类型
第13章 乱用索引
13.1 目标:优化性能
13.2 反模式:无规划地使用索引
13.2.1 无索引
13.2.2 索引过多
13.2.3 索引也无能为力
13.3 如何识别反模式
13.4 合理使用反模式
13.5 解决方案:MENTOR你的索引
13.5.1 测量
13.5.2 解释
13.5.3 挑选
13.5.4 测试
13.5.5 优化
13.5.6 重建
第三部分 查询反模式
第14章 对未知的恐惧
14.1 目标:辨别悬空值
14.2 反模式:将NULL作为普通的值,反之亦然
14.2.1 在表达式中使用NULL
14.2.2 搜索允许为空的列
14.2.3 在查询参数中使用NULL
14.2.4 避免上述问题
14.3 如何识别反模式
14.4 合理使用反模式
14.5 解决方案:将NULL视为特殊值
14.5.1 在标量表达式中使用NULL
14.5.2 在布尔表达式中使用NULL
14.5.3 检索NULL值
14.5.4 声明NOT NULL的列
14.5.5 动态默认值
第15章 模棱两可的分组
15.1 目标:获取每组的最大值
15.2 反模式:引用非分组列
15.2.1 单值规则
15.2.2 我想要的查询
15.3 如何识别反模式
15.4 合理使用反模式
15.5 解决方案:无歧义地使用列
15.5.1 只查询功能依赖的列
15.5.2 使用关联子查询
15.5.3 使用衍生表
15.5.4 使用JOIN
15.5.5 对额外的列使用聚合函数
15.5.6 连接同组所有值
第16章 随机选择
16.1 目标:获取样本记录
16.2 反模式:随机排序
16.3 如何识别反模式
16.4 合理使用反模式
16.5 解决方案:没有具体的顺序
16.5.1 从1到最大值之间随机选择
16.5.2 选择下一个最大值
16.5.3 获取所有的键值,随机选择一个
16.5.4 使用偏移量选择随机行
16.5.5 专有解决方案
第17章 可怜人的搜索引擎
17.1 目标:全文搜索
17.2 反模式:模式匹配断言
17.3 如何识别反模式
17.4 合理使用反模式
17.5 解决方案:使用正确的工具
17.5.1 数据库扩展
17.5.2 第三方搜索引擎
第18章 意大利面条式查询
18.1 目标:减少SQL查询数量
18.2 反模式:使用一步操作解决复杂问题
18.2.1 副作用
18.2.2 那好像还不够……
18.3 如何识别反模式
18.4 合理使用反模式
18.5 解决方案:分而治之
18.5.1 一步一个脚印
18.5.2 寻找UNION标记
18.5.3 解决老板的问题
18.5.4 使用SQL自动生成SQL
第19章 隐式的列
19.1 目标:减少输入
19.2 反模式:捷径会让你迷失方向
19.2.1 破坏代码重构
19.2.2 隐藏的开销
19.2.3 你请求,你获得
19.3 如何识别反模式
19.4 合理使用反模式
19.5 解决方案:明确列出列名
19.5.1 预防错误
19.5.2 你不需要它
19.5.3 无论如何你都需要放弃使用通配符
第四部分 应用程序开发反模式
第20章 明文密码
20.1 目标:恢复或重置密码
20.2 反模式:使用明文存储密码
20.2.1 存储密码
20.2.2 验证密码
20.2.3 在E-mail中发送密码
20.3 如何识别反模式
20.4 合理使用反模式
20.5 解决方案:先哈希,后存储
20.5.1 理解哈希函数
20.5.2 在SQL中使用哈希
20.5.3 给哈希加料
20.5.4 在SQL中隐藏密码
20.5.5 重置密码,而非恢复密码
第21章 SQL注入
21.1 目标:编写SQL动态查询
21.2 反模式:将未经验证的输入作为代码执行
21.2.1 意外无处不在
21.2.2 对Web安全的严重威胁
21.2.3 寻找治愈良方
21.3 如何识别反模式
21.4 合理使用反模式
21.5 解决方案:不信任任何人
21.5.1 过滤输入内容
21.5.2 参数化动态内容
21.5.3 给动态输入的值加引号
21.5.4 将用户与代码隔离
21.5.5 找个可靠的人来帮你审查代码
第22章 伪键洁癖
22.1 目标:整理数据
22.2 反模式:填充角落
22.2.1 不按照顺序分配编号
22.2.2 为现有行重新编号
22.2.3 制造数据差异
22.3 如何识别反模式
22.4 合理使用反模式
22.5 解决方案:克服心里障碍
22.5.1 定义行号
22.5.2 使用GUID
22.5.3 最主要的问题
第23章 非礼勿视
23.1 目标:写更少的代码
23.2 反模式:无米之炊
23.2.1 没有诊断的诊断
23.2.2 字里行间
23.3 如何识别反模式
23.4 合理使用反模式
23.5 解决方案:优雅地从错误中恢复
23.5.1 保持节奏
23.5.2 回溯你的脚步
第24章 外交豁免权
24.1 目标:采用最佳实践
24.2 反模式:将SQL视为二等公民
24.3 如何识别反模式
24.4 合理使用反模式
24.5 解决方案:建立一个质量至上的文化
24.5.1 陈列A:编写文档
24.5.2 寻找证据:源代码版本控制
24.5.3 举证:测试
24.5.4 例证:同时处理多个分支
第25章 魔豆
25.1 目标:简化MVC的模型
25.2 反模式:模型仅仅是活动记录
25.2.1 活动记录模式连接程序模型和数据库结构
25.2.2 活动记录模式暴露了CRUD系列函数
25.2.3 活动记录模式支持弱域模型
25.2.4 魔豆难以进行单元测试
25.3 如何识别反模式
25.4 合理使用反模式
25.5 解决方案:模型包含活动记录
25.5.1 领会模型的意义
25.5.2 将领域模型应用到实际工作中
25.5.3 测试简单对象
25.5.4 回到地球
第五部分 附录
附录A 规范化规则
附录B 参考书目