上云无忧 > 文档中心 > 百度智能云云数据库 FusionDB 建表最佳实践
云数据库 FusionDB
百度智能云云数据库 FusionDB 建表最佳实践

文档简介:
云数据库 FusionDB 在创建表时必须显式指定分布键(DISTRIBUTED RANDOMLY 或 DISTRIBUTED BY (col1, col2,...))。默认情况下,如果创建表时不指定分布键,云数据库 FusionDB 将使用第一个字段作为分布键,这种情况有时会有比较大的风险所以应该坚决杜绝这种情况。
*此产品及展示信息均由百度智能云官方提供。免费试用 咨询热线:400-826-7010,为您提供专业的售前咨询,让您快速了解云产品,助您轻松上云! 微信咨询
  免费试用、价格特惠

分布键

云数据库 FusionDB 在创建表时必须显式指定分布键(DISTRIBUTED RANDOMLY 或 DISTRIBUTED BY (col1, col2,...))。默认情况下,如果创建表时不指定分布键,云数据库 FusionDB 将使用第一个字段作为分布键,这种情况有时会有比较大的风险所以应该坚决杜绝这种情况。

一般来说,均匀为第一大原则,选取更有业务意义的字段,建议选一个常用于Join的字段做分布键。分布键的作用是什么?一者,是为了把数据均匀的分散到所有Primary Instance;再者,是为了能够实现Local计算,尽量减少数据的shuffle。比如在做Join时,为了减少数据的重分布,只有当关联字段包含所有分布键字段的情况下,才能实现Local Join,才能保证数据减少发生shuffle。为了提升这种可能性,当然字段越少越好,只有单元素的集合才最容易成为其他集合的子集。

关于随机分布,我们需要有充分的认知,对于不太可能和其他大表进行关联的大表来说,如果我们实在找不到合适的分布键,有时我们可以使用Randomly策略,至少可以确保数据的均匀分布,当其与小表Join时,执行计划会优先选择将小表做Broadcast。分布键的选择是一个比较有技术含量的事情。对于Create时没有指定分布键又没有PK的情况,云数据库 FusionDB 将缺省使用第一个字段作为分布键,这种情况有时会有比较大的风险。

正确实例:

CREATE TABLE test_table ( createdate DATA, id INT, name varchar(64)) DISTRIBUTED RANDOMLY;

CREATE TABLE test_table ( createdate DATA, id INT, name varchar(64)) DISTRIBUTED RANDOMLY;

错误示例:

CREATE TABLE test_table ( createdate DATA, id INT, name varchar(64));

AOT

云数据库 FusionDB 中存储数据有2种存储模型:一种是默认类型的Heap表;另一种是appendonly表;

Heap表可以进行循环的Update、Delete和单行Insert操作,也可以进行并发的Update、Delete、Insert。

Appendonly表用于初始加载数据后很少更新,并且后续只是进行批量插入的操作。不推荐对Appendonly表进行单条Insert,Update,Delete操作和并发的Update,Delete操作,并发的Insert是可以进行的。由于对Appendonly进行Update和Delete的空间不会像Heap表那样被重复使用,因此Appendonly表不适合进行频繁的更新操作,Appendonly表适合于一次加载后频繁查询分析的大表。

Appendonly表相比于Heap表在数据存储时页面结构做了优化,每行记录相比于Heap表少20字节的行头信息,因此数据量更小,查询性能更好。因此可结合业务特点选择合适的。

Heap表实例:

CREATE TABLE test_table ( createdate DATA, id INT, name varchar(64)) DISTRIBUTED RANDOMLY;

AOT表实例:

CREATE TABLE test_table ( createdate DATA, id INT, name varchar(64)) 
WITH (APPENDONLY=true)<br>DISTRIBUTED RANDOMLY;

行存&列存

行存是数据库存储的传统方式,由多列组合而成的一行连续地存储在磁盘上,因此完整的一行使用单I/O即可从磁盘读取。

列存是每列都会创建一个文件,如果表带有分区,每个分区子表的每列都会创建一个文件。当一个Query仅仅访问带有很多列的列存表中的一小部分列时,其他不相关的列不会备从磁盘检索到,因此I/O的开销相比于行存会小很多。

行存适合于传统的频繁进行更新和插入的交易类型的事务,和对于常用每个Query都涉及记录中的很多列的情况。如果Select列表和Where条件需要数据表中大多数列,则此数据表采用行存最适合。此外,由于行存在灵活性和性能的综合方面有着很好的优势,因此行存适用于通用的或混合工作类型。

列存对于读取操作做了优化,但并未对写操作做优化,一行中的不同列会被写入到磁盘的不同区域。列存对于有很多列的宽表,并且Query只访问这些列中的一小部分集合的典型应用有非常好的性能。

另一方面,列存是把相同数据类型的值存储在一起,因此相比行存占用更少的空间,也使用更少的磁盘I/O。列存表也比行存表也有更好的压缩效果。

列存适合的场景:在数据仓库的分析工作中,对于经常需要对宽表小部分列做聚合计算的场景;有单个些列经常被更新并且不修改其他列的场景;

在一张宽表中读完整的一条记录时,列存相比行存需要花费更多的时间,因为每一列在每个segment上都是单独的一个文件。

最终选择行存还是列存,需要结合业务特征做最优的选择。

行存示例:

CREATE TABLE test_table ( createdate DATA, id INT, name VARCHAR(64)) 
WITH (APPENDONLY=true, ORIENTATION=row)
DISTRIBUTED RANDOMLY;

列存实例:

CREATE TABLE test_table ( createdate DATA, id INT, name VARCHAR(64)) 
WITH (APPENDONLY=true, ORIENTATION=column)
DISTRIBUTED RANDOMLY;

数据压缩

考虑到随着业务的发展,数据量存储的压力,对于数据量大一些的冷数据可以考虑采用压缩。只要压缩级别不是太高,都可以有效的降低存储空间,并且对查询性能不会造成太大的影响。常用的压缩选项是zlib5,但是如果提升到zlib9,可能压缩效果会提升10%+,但访问性能会成倍下降。有时候quicklz也是不错的选择,但其压缩效果不如zlib,当然访问性能也会比zlib好一些。具体生产场景可以结合业务场景做一些对比测试,如果访问是I/O瓶颈可以采用压缩存储,使用CPU来换I/O,并可以测试不同的压缩算法和级别以获得最满意的压缩选项。列压缩的压缩率比行压缩的更好,但应与表尺寸一并考虑。

对于大表来说,采用压缩存储,既节省空间也节省IO资源。长远来看还可降低阵列卡和磁盘的故障率。 只有AOT表才能使用使用表压缩,Heap不能使用压缩。

压缩示例(使用Zlib方式,压缩级别为5)

CREATE TABLE test_table ( createdate DATA, id INT, name VARCHAR(64)) 
WITH (APPENDONLY=true, ORIENTATION=row, COMPRESSTYPE=zlib, COMPRESSLEVEL=5)
DISTRIBUTED RANDOMLY;

分区表

云数据库 FusionDB 的分区原理与其他数据库无异,合适的分区可以减少磁盘I/O操作加速查询效率,但是建议是不要把表分区设计的过于零碎,一般来说一个表的分区数量,几十、上百个就差不多了,不宜过多,对应冷数据可以做分区合并并压缩存储已节省存储空间。分区之间数据无需均匀。具体的分区策略是否合理,需要根据具体情况来评估。

分区表最好选择日期字段做为分区键,按月或者按天分区,具体可以根据业务的使用而决定。

另外,一般不建议用多级分区,多级分区维护困难,同时数据文件的数量也会剧增。

按月分区示例:

CREATE TABLE test_table ( createdate DATA, id INT, name VARCHAR(64)) 
WITH (APPENDONLY=true, ORIENTATION=row, COMPRESSTYPE=zlib, COMPRESSLEVEL=5)
DISTRIBUTED RANDOMLY
PARTITION BY range(createdate)
(
PARTITION m201801 START (date '2018-01-01') INCLUSIVE END (date '2018-02-01') EXCLUSIVE,
PARTITION m201802 START (date '2018-02-01') INCLUSIVE END (date '2018-03-01') EXCLUSIVE,
PARTITION m201803 START (date '2018-03-01') INCLUSIVE END (date '2018-04-01') EXCLUSIVE,
PARTITION m201804 START (date '2018-04-01') INCLUSIVE END (date '2018-05-01') EXCLUSIVE,
PARTITION m201805 START (date '2018-05-01') INCLUSIVE END (date '2018-06-01') EXCLUSIVE,
PARTITION m201806 START (date '2018-06-01') INCLUSIVE END (date '2018-07-01') EXCLUSIVE,
PARTITION m201807 START (date '2018-07-01') INCLUSIVE END (date '2018-08-01') EXCLUSIVE,
PARTITION m201808 START (date '2018-08-01') INCLUSIVE END (date '2018-09-01') EXCLUSIVE,
PARTITION m201809 START (date '2018-09-01') INCLUSIVE END (date '2018-10-01') EXCLUSIVE,
PARTITION m201810 START (date '2018-10-01') INCLUSIVE END (date '2018-11-01') EXCLUSIVE,
PARTITION m201811 START (date '2018-11-01') INCLUSIVE END (date '2018-12-01') EXCLUSIVE,
PARTITION m201812 START (date '2018-12-01') INCLUSIVE END (date '2019-01-01') EXCLUSIVE,
DEFAULT PARTITION other
);

数据类型

在建表时,各字段的数据类型的选择也是比较讲究的:

  1. 使用相同数据类型的字段进行表Join操作,如果数据类型不一致,那么云数据库 FusionDB 需要对字段进行动态类型转化以确保字段可以比较,另外,由于字段之间类型不匹配,很可能会导致系统选用错误的Join方式,从而查询性能严重下降。因此在建表时需兼顾各表中字段类型的兼容。
  2. 选择正确的数据类型。比如一个日期字段,可以设置为date、varchar等类型,但除非是特殊要求,否则最为合适的是选用date类型。因为在云数据库 FusionDB 中,如果使用日期字段作为过滤条件,date类型比较效率比varchar类型的比较效率要高;再者无法针对varchar类型对表进行基于时间的分区,这对大表的优化造成影响。
相似文档
  • 在云数据库 FusionDB 中建议设置定期空洞回收的维护任务。 回收空洞: 云数据库 FusionDB 使用MVCC机制,数据的更新操作(INSERT、UPDATE、DELETE、ALTER TABLE ADD COLUMN )不会直接修改原数据,而是标记数据为不可用,然后插入新数据。
  • 云数据库 FusionDB 功能说明: 云数据库 FusionDB,作为一套完整的分布式数据库系统,提供创建、删除、查看等实例管理,账号管理、白名单管理、监控等功能。
  • API认证机制: 所有API的安全认证一律采用Access Key与请求签名机制。 Access Key由Access Key ID和Secret Access Key组成,均为字符串。 对于每个HTTP请求,使用下面所描述的算法生成一个认证字符串。
  • 如果您是初次调用百度智能云产品的API,可以观看API入门视频指南,快速掌握调用API的方法。 获取集群信息,包括集群ID、集群名、连接信息、计算节点数、计算节点套餐规格(内存、存储空间)、集群状态、锁定模式、创建时间、区域等信息。
  • 申请了云数据库 FusionDB 实例,默认账号的密码是什么? 默认账号是useradmin,初始密码不提供,需要到控制台->账号管理中修改密码后使用。 云数据库 FusionDB 可以通过SQL语句或客户端工具进行数据库账号的创建和删除吗? 用户可以使用useradmin账号通过SQL语句或客户端工具进行数据库账号的创建和删除以及给账号授权,管理控制台不提供该功能。
官方微信
联系客服
400-826-7010
7x24小时客服热线
分享
  • QQ好友
  • QQ空间
  • 微信
  • 微博
返回顶部