2021-数据库开发-Lec9-为性能而设计
Lec9-为性能而设计
1. 为性能而设计
1.1. 数据的关系视图
- 数据库只是对现实世界的有限描述。对特定的业务活动的描述不止一种
- "关系模型"中的"关系"的含义
- 关系模型的一致性
- 只要遵守关系理论,可以保证基于数据库的任何查询结果与原始数据具有同样的有效
- 关系理论包括
- 关系不包含重复数据
- 关系理论保证无限数据的正确性
- 记录之间没有顺序
1.2. 规范化(Normailization)
- 表结构没有规范化会面临很大的风险吗?
- 1NF 确保原子性(Atomicity)
- 2NF 检查对键的完全依赖
- 3NF 检查属性的独立性
- 过分精益求精会使精力分散
- 规范化的价值
- 合理规范化的模型可应对需求变更
- 规范化数据重复降至最少
1.3. 有值、无值、空值
- 表中的每一条记录都应该是特定"事物"的状态描述,如果大部分特征信息都显示"我们不知道",无疑大大降低了信息可信性
- 存在空值意味着关系模型存在严重的问题,动摇了查询优化的基础
- 空值对程序逻辑是危险的
- 必须使用空值的话,一定要清楚它在特定情况下的影响。
1.4. 限用Boolean型字段
- SQL中并不存在Boolean类型
- 实现flag表示标志位的Y/N或T/F
- 例如:order_completed
- 但是…往往增加信息字段能包含更多的信息量
- 例如:completion_date completion_by
- 或者增加order更多状态标示
- 极端的例子:四个属性取值都是T/F,可以用0-15这16个数值代表四个属性所有组合状态
- 技巧可能违反了原子性的原则
- 为数据而数据,是通向灾难之路
1.5. 理解子类型(SubType)
- 表过"宽"(有太多属性)的另一个原因,是对数据项之间的关系了解不够深入,窄表的效率相对比较高
- 一般情况下,给子类型表指定完全独立于父表主键的主键,是极其错误的
1.6. 约束应明确说明
- 数据中存在隐含约束是一种不良设计
- 字段的性质随着环境变化而变化时设计的错误和不稳定性
- 数据语义属于DBMS,别放到应用程序中
1 |
|
1.7. 过于灵活的危险性
- “真理向前跨一步就是谬误”
- 不可思议的四通用表设计
- Objects(oid, name), Attributes(attrid, attrname,type)
- Object_Attributes(oid,attrid,value)
- Link(oid1,oid2)
- 随意增加属性,避免NULL
- 成本急剧上升,性能令人失望
- 基于规则的优化器:笛卡尔积往往是最消耗性能的。
- 目前是基于成本的优化器,大量的性能消耗也使得关系数据库出现问题
1.8. 如何处理历史数据
- 历史数据:例如:商品在某一时刻的价格
- Price_history(article_id , effective_from_date , price)
- 缺点在于查询当前价格比较笨拙
- 设置为价格终止时间呢?
1 |
|
1 |
|
1.9. 处理流程
- 操作模式(operating mode)
- 异步模式处理(批处理)
- 同步模式处理(实时交易)
- 处理数据的方式会影响我们物理结构的设计
- 清算:部分锁表进行清算
- 任何一个系统要将批处理和实时处理分开
1.10. 数据集中化(Centralizing)
- 分布式数据系统复杂性大大增加
- 远程数据的透明引用访问代价很高
- 不同数据源数据结合极为困难
- Copy的数据传输开销
- 无法从数据规划中获益(物理结构,索引)
- 数据库该如何部署呢?中庸、分析、决策
- 离数据越近,访问速度越快
1.11. 系统复杂性
- 数据库的错误很多
- 硬件故障
- 错误操作…
- 数据恢复往往是RD和DBA争论焦点
- DBA,即便确保数据库本身工作正常,依然无法了解数据是否正确
- RD,在数据库恢复后进行所有的功能性的检查
- 高性能数据库一般不使用防御式编程,而做进攻性编程
2. 小结
- 错误的设计是导致灾难性后果的源泉
- 解决设计问题会浪费惊人的精力和智慧
- 性能问题非常普遍
- 打着"改善性能"的旗号进行非规范化处理,常常使性能问题变得更糟
- 成果的数据建模和数据操作应严格遵循基本的设计原则。
2021-数据库开发-Lec9-为性能而设计
https://spricoder.github.io/2021/05/02/2021-Database-Development/2021-Database-Development-Lec9-%E4%B8%BA%E6%80%A7%E8%83%BD%E8%80%8C%E8%AE%BE%E8%AE%A1/