1、为什么进行数据库设计?
|
良好的设计 |
糟糕的设计 |
|
减少数据冗余 |
存在大量数据冗余 |
|
避免数据维护异常 |
存在数据插入,删除,更新异常 |
|
节约存储空间 |
浪费存储空间 |
|
高效的访问 |
访问效率低 |
2、数据库设计步骤
3、逻辑设计——三大范式
第一范式:强调的是列的原子性,即列不能够再分成其他几列。
--->字段不可分
第二范式:表必须有一个主键;没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分。
-->非主键字段依赖主键
第三范式:非主键列必须直接依赖于主键,不能存在传递依赖。即不能存在:非主键列 A 依赖于非主键列 B,非主键列 B 依赖于主键的情况。
-->非主键字段不能互相依赖
4、物理设计——反范式化
基本表及其字段之间的关系, 应尽量满足第三范式。但是,满足第三范式的数据库设计,往往不是最好的设计。 为了提高数据库的运行效率,常常需要降低范式标准:适当增加冗余,达到以空间换时间的目的。
eg:合理的冗余字段将会给我们减少join的查询
增加数据的读取效率
5、维护优化——分表
项目开发中,我们的数据库数据越来越大,随之而来的是单个表中数据太多。以至于查询速度变慢,而且由于表的锁机制导致应用操作也搜到严重影响,出现了数据库性能瓶颈。
当出现这种情况时,我们可以考虑分表,即将单个数据库表进行拆分,拆分成多个数据表, 然后用户访问的时候,根据一定的算法,让用户访问不同的表, 这样数据分散到多个数据表中,减少了单个数据表的访问压力。 提升了数据库访问性能。
在分表之前, 首先要选中合适的分表策略(以哪个字段为分表字段,需要将数据分为多少张表), 使数据能够均衡的分布在多张表中,并且不影响正常的查询。
垂直拆分是根据业务将一个库(表)拆分为多个库(表)
水平拆分则是根据分片算法将一个库(表)拆分为多个库(表)
①水平分表:降低在查询时需要读的数据和索引的页数 适用场景:表中的数据本身就有独立性,例如表中分表记录各个地区的数据或者不同时期的数据,特别是有些数据常用,有些不常用。 解决:单表中数据量增长出现的压力
②垂直分表:把主键和一些列放在一个表,然后把主键和另外的列放在另一个表中 适用场景:一个表中某些列常用,另外一些列不常用;可以使数据行变小,一个数据页能存储更多数据,查询时减少I/O次数; 把不同的业务模块分成不同的数据表,这些业务模块直接最好是0耦合 不解决问题:单表中数据量增长出现的压力 查询时会减少I/O次数
|
|
水平分表 |
垂直分表 |
|
优点 |
不存在单库大数据,高并发的性能瓶颈 提高了系统的稳定性跟负载能力 |
拆分后业务清晰,拆分规则明确 系统之间整合或扩展容易 数据维护简单 |
|
缺点 |
拆分规则难以抽象 事务一致性难以解决 数据多次扩展难度跟维护量极大
|
部分业务表无法 join 受业务不同的限制存在单库性能瓶颈,不易数据扩展跟性能提高 事务处理复杂 存在单表读写与存储瓶颈
|
策略:取模 枚举 区间范围 时间 (月)
6、维护优化——分库
分表能够解决单表数据量过大带来的查询效率下降的问题, 但是,却无法给数据库的并发处理能力带来质的提升。 面对高并发的读写访问,当数据库master服务器无法承载写操作压力时,不管如何扩展slave服务器,此时都没有意义了。
因此,我们必须换一种思路,对数据库进行拆分,从而提高数据库写入能力,这就是所谓的分库。 与分表策略相似,分库可以采用通过一个关键字取模的方式,来对数据访问进行路由
7. 分库分表有哪些问题
1.事务问题: 在执行分库分表之后,由于数据存储到了不同的库上,数据库事务管理出现了困难
|
|
优点 |
缺点 |
|
方案一:使用分布式事务
|
交由数据库管理,简单有效
|
性能代价高
|
|
方案二:由应用程序和数据库共同控制 |
性能上有优势 |
形成程序逻辑上的事务,又会造成编程方面的负担 |
2.跨库join问题: 在执行分库分表之后,难免会将原来逻辑性很强的数据划分到不同的表/库上,这时,表的关联操作将收到限制,无法join操作
方案:将操作分成多步完成。在第一次查询的结果集中找出关联数据的id,根据这些id发起第二次请求得到关联数据。
8、sharding-jdbc分表算法
实现了一个精准分片的算法,doSharding方法,里面包含两个参数availableTargetNames和shardingValue。 preciseShardingValue------------->分表字段,比如data_type;
availableTargetNames------------->实际数据库表节点 当分表字段满足一定的条件时,返回实际数据库表节点
actual-data-nodes:真实数据节点,由数据源名 + 表名组成,以小数点分隔;多个表以逗号分隔
sharding-column :分表字段