---恢复内容开始---
1.乱穿马路 ---- > 目标 : 存储多值属性。
1) 错误方法: 使用格式化的逗号分割列表。
1-> 不适合查询,定位数据,无法运用聚合函数进行分组,不利于更行指定产品的账号。不利于验证指定的非法字段。
2-> 难以选择合适的分隔符,列表的长度难以限制。
2) 解决方案:
1-> 创建一张交叉表。
2-> 当一张表有指向另外两张表的外键时,我们称之为交叉表。
3-> 使用交叉表的优势 : 能使用索引提高联结查询效率,能执行聚合查询。没有上述缺点。
2.单纯的树 ---- > 目标: 分层存储与查询 例子 : 回帖。
1)方案1: 邻接表。
缺陷: 无法完成 查询一个节点的所有后代。无法执行聚合函数。从一颗树中删除一个节点会变的比较复杂。丛树中获得给定节点的所有祖先开销很大。
优势: 增加叶子节点相当简单。
2)方案2:路径枚举
缺陷: 拥有上一个乱穿马路中的所有缺陷。
优势: 插入一个节点相当简单。并且容易获取子节点,父节点。
3)方案3:嵌套集
4)方案4:闭包表
实现: 创建一张额外的关系表,其中存储树中所有祖先-后代关系的节点信息。
优势: 直接获取祖先,后代节点。 插入删除节点方便。
设计 表 查询子节点 查询树 插入 删除 引用完整性
邻接表 1 简单 困难 简单 简单 是
递归查询 1 简单 简单 简单 简单 是
枚举路劲 1 简单 简单 简单 简单 否
嵌套集 1 困难 简单 困难 困难 否
闭包表 2 简单 简单 简单 简单 是
邻接表是最方便的设计, 如果数据库智齿 with 或者 connect by prior 的递归查询,那使用邻接表查询更为高效。
枚举路径能够很直观的展示出祖先到后代之间的路径。
嵌套集 不能保证引用完整性。
闭包表是最通用的设计。
3.需要ID 目标---- 建立主键规范。
主键: 是数据库确保数据行在整张表中唯一性的保障,它是定位到一条记录并且确保不会重复存储的逻辑机制,主键也同时可以被外键引用来
建立表和表之间的关系。
mysql中提供一种与当前处理事物无关的底层方案,来确保每次都能生成全局唯一的一个整数作为主键。即使此时客户端正在发起并发操作。
主键约束的重要性: ×× 如果不使用主键约束,那么必须检查是否有重复行。
1)确保一张表中数据不会出现重复行。
2)在查询中引用单独的一行记录。
3)支持外键。
注:如果两张表都有同样的列名, 就可以使用 using 进行联结查询。
注: mysql中内置函数 获取一个序列生成的最后一个值 : last_insert_id();
当客户端发起并发请求活取最新记录id时,如果使用当前最大值+1的做法不可靠,同样的值可能被多个客户端同时获取,要避免竞争问题必须锁住整张表。
4.目标: 简化数据库架构
省略外键约束能使数据库设计更加简单,灵活,或者执行更加高效,但是必须增加额外代码来手动维护引用的完整性。
注: 任何需要加锁的架构,在高并发和大数据量查询时表现都很糟糕。
当*使用不支持外键约束的数据库产品, 比如mysql 的myisam存储引擎, 为了维护引用的完整性,必须使用监控脚本。
外键的优势:
1)不用在更新或者删除记录前执行select进行检查。
2)在同步修改时不需要再锁住整张表。
3)不再需要执行定期监控脚本来修正不可避免的孤立数据。
5.支持可变数据。
1) 单表继承。
2) 实体表继承。
3) 类表继承。
4) 半结构化数据模型。
6. 多态关联。 目标 引用多个父表
尽可能避免多态关联, 应该使用外键约束等来确保引用完整性。 多态关联通常过度依赖上层程序代码而不是数据库的元数据。
当使用一个面向对象框架时,多态关联似乎是不可避免的。这种类型的框架通过良好的逻辑封装可以减少使用多态关联的风险。