云服务器内容精选

  • 数据库不建议修改的会话级参数 foreign_key_checks 参数解释:bool类型,默认全局值为ON。在创建外键的时候,如果设置为ON,则会检查外键的规范性,例如外键不能reference同一张表中的键等。 不建议修改的原因: foreign_key_checks值为ON时,无法通过该参数检查的外键,本身就是不规范的使用方法,建议优化SQL,规范数据库使用。 如果该参数线程级设置为了OFF,一些不规范的外键在主机被创建出来,但由于备机仍为ON,这些外键创建的DDL语句会在备机复制时执行不通过,导致复制异常。详见外键使用不规范导致实例重启失败或执行表操作报错ERROR 1146: Table 'xxx' doesn't exist。 单机实例也建议遵循foreign_key_checks为ON的外键规范性检查。 innodb_strict_mode 参数解释:bool类型,默认全局值为ON。如果设置为ON,那么一些不规范的InnoDB表操作,会直接报错而非warning,例如:InnoDB页面为16KB时,单行的大小超过了8KB。 不建议修改的原因: 最常见的一个异常场景是,如果主机线程级设置成了OFF,使用Alter Table DDL加列时,如果字段数较多,单行长度超过了8KB,在主机能执行成功,但因为备机该参数仍为ON,导致备机该Alter DDL执行直接报错,出现复制异常。 如果有业务需求,建议Global级别主备一起修改。 default_storage_engine 参数解释:枚举值类型,只能填可用的存储引擎名,默认全局值为InnoDB。在CREATE/ALTER TABLE DDL语句未显式指定存储引擎时,选择的默认存储引擎。 不建议修改的原因: 由于RDS for MySQL产品主备复制使用的是开源社区基于Binlog的复制模式,建表语句中,如果没有显式指定存储引擎的CREATE/ALTER TABLE DDL语句,不会把默认的存储引擎记录到Binlog(与社区行为一致)。而在备机复制,执行该DDL时,会使用备机复制线程的default_storage_engine(为全局的InnoDB)。 如果主机session级别修改该参数为非InnoDB的存储引擎,执行CREATE/ALTER DDL语句就会出现主机创的表定义为非InnoDB引擎,而备机的表定义为InnoDB的不一致情况。 unique_checks 参数解释:bool类型,默认全局值为ON。如果设置为ON,对InnoDB表中二级索引唯一键进行唯一性检查。 不建议修改的原因: 如果主机session级设为OFF,则不会进行二级索引的唯一键的唯一性检查,二级索引唯一键重复的DML语句会执行成功。但是在备机,同样的DML会因为唯一性检查执行失败,导致复制异常。 sql_log_bin 参数解释:默认ON,控制当前会话的SQL是否计入Binlog。 不建议修改的原因: RDS for MySQL产品主备复制使用的是开源社区基于Binlog的复制模式。如果主机单个会话的参数值设为OFF,则对表的修改不会计入Binlog,该修改无法同步到备机,导致主备数据不一致。 old_alter_table 参数解释:bool值,默认OFF。当值为ON时,在ALTER TABLE语句中使用基于COPY临时表实现的算法,会影响数据库性能,一般情况下不建议开启。 不建议修改的原因: 涉及ALTER IGNORE选项在备机可能会回放失败。 基于COPY实现的ALTER TABLE性能较差。
  • 数据库索引设计规范 每个InnoDB表强烈建议有一个主键,且不使用更新频繁的列作为主键,不使用多列主键。不使用UUID、MD5、字符串列作为主键。建议选择值的顺序是连续增长的列作为主键,所以建议选择使用自增ID列作为主键。 限制每张表上的索引数量,建议单张表索引不超过5个。索引并不是越多越好,索引可以提高查询的效率,但会降低写数据的效率。有时不恰当的索引还会降低查询的效率。 禁止给表中的每一列都建立单独的索引。设计良好的联合索引比每一列上的单独索引效率要高出很多。 建议在下面的列上建立索引: 在SELECT,UPDATE,DELETE语句的WHERE从句上的列。 在ORDER BY,GROUP BY,DISTINCT上的列。 多表JOIN的关联列。 索引列顺序: 区分度最高的放在联合索引的最左侧。区分度=列中不同值的数量/列的总行数。 尽量把字段长度小的列放在联合索引的最左侧。因为字段长度越小,一页能存储的数据量越大,IO性能也就越好。 使用最频繁的列放到联合索引的左侧。这样可以比较少的建立一些索引。 避免冗余的索引,如:primary key(id),index(id),unique index(id) 避免重复的索引,如:index(a,b,c),index(a,b),index(a),重复的和冗余的索引会降低查询效率,因为RDS for MySQL查询优化器无法选择使用目标索引。 在VARCHAR字段上建立索引时,需指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索引长度即可。 一般对字符串类型数据,长度为20的索引,区分度会高达90%以上,可以使用 count(distinct left(列名, 索引长度))/count(*) 的区分度来确定。 对于频繁查询优先考虑使用覆盖索引。 覆盖索引指包含了所有查询字段的索引,不仅仅是WHERE从句GROUP BY从句中的列,也包含SELECT查询的列组合,避免InnoDB表进行索引的二次查询。 外键约束: 建立外键关系的对应列的字符集必须保持一致或者存在外键关系的子表父表的字符集保持一致。
  • 数据库基本设计规范 所有表如果没有特殊需求,都要使用InnoDB存储引擎。InnoDB存储引擎支持事务、行级锁、具有更好的恢复性、高并发下性能更强。 数据库和表的字符集统一使用UTF8字符集,避免由于字符集的转换产生乱码。 所有的表和字段都需要添加注释。使用comment从句添加表和列的备注,从设计初期维护好数据字典。 表单行长度不得超过1024字节。 谨慎使用RDS for MySQL分区表,避免跨分区查询,否则查询效率会降低。分区表在逻辑上表现为一个表,但是在物理层面上将数据存储在多个文件。 表中的列不要太多,尽量做到冷热数据分离,减小表的宽度,以便在一页内存中容纳更多的行,进而减少磁盘IO,更有效的利用缓存。 经常一起使用的列尽量放到一个表中,避免过多的关联操作。 禁止在表中建立预留字段,否则修改列的类型会导致锁表,修改一个字段类型的成本要高于增加一个字段。 禁止在数据库中存储图片、文件等大的二进制数据。 不建议使用全文索引,社区MySQL全文索引局限性较多。 表数量不建议超过2万张。 客户端连接保持时长不建议超过8小时。 为避免高并发场景下数据库实例OOM,建议tmp_table_size、innodb_buffer_pool_size、max_connections、sort_buffer_size、read_buffer_size、read_rnd_buffer_size、join_buffer_size、thread_stack、binlog_cache_size等参数配置不要超过默认值。
  • 数据库命名规范 所有的数据库对象名称(包括库名、表名、列名等)建议以小写字母命名,每个单词之间用下划线分割。 所有的数据库对象名称禁止使用RDS for MySQL保留关键字。 MySQL官方保留字与关键字(MySQL 8.0):https://dev.mysql.com/doc/refman/8.0/en/keywords.html MySQL官方保留字与关键字(MySQL 5.7):https://dev.mysql.com/doc/refman/5.7/en/keywords.html RDS for MySQL的保留关键字在兼容社区MySQL8.0的基础上,新增了部分保留关键字,需要在业务使用中避免使用保留关键字来命名。 表1 RDS for MySQL新增的保留关键字 保留字 相关场景 RECYCLE_BIN 回收站 数据库对象的命名要能做到见名知意,并且不超过32个字符。 数据库中用到的临时表以“tmp”为前缀并以日期为后缀。 数据库中用到的备份表以“bak”为前缀并以日期为后缀。 在不同的库或表中,要保证所有存储相同数据的列名和列类型必须一致。
  • 数据库字段设计规范 控制单表字段数量,字段上限50左右。 优先为表中的每一列选择符合存储需要的最小的数据类型。优先考虑数字类型,其次为日期或二进制类型,最后是字符类型。列的字段类型越大,建立索引占据的空间就越大,导致一个页中的索引越少,造成IO次数增加,从而影响性能。 整数型选择能符合需求的最短列类型,如果为非负数,声明需是无符号(UNSIGNED)类型。 每个字段尽可能具有NOT NULL属性,int等数字类型默认值推荐给0,varchar等字符类型默认值给空字符串。 避免使用ENUM类型,可以用TINYINT类型替换。 修改ENUM值需要使用ALTER语句,ENUM类型的ORDER BY操作效率低,需要额外操作。 如果定义了禁止ENUM的枚举值是数值,可使用其他数据类型(如char类型)。 实数类型使用DECIMAL,禁止使用FLOAT和DOUBLE类型。 FLOAT和DOUBLE在存储的时候,存在精度损失的问题,很可能在值的比较时,得到错误的结果。 使用datetime、timestamp类型来存储时间,禁止使用字符串替代。 使用数字类型INT UNSIGNED存储IP地址,用INET_ATON、INET_NTOA可以在IP地址和数字类型之间转换。 VARCHAR类型的长度应该尽可能短。VARCHAR类型虽然在硬盘上是动态长度的,但是在内存中占用的空间是固定的最大长度。 使用VARBINARY存储大小写敏感的变长字符串,VARBINARY默认区分⼤小写,没有字符集概念,速度快。
  • 分片设计规范 对于使用DDS分片集群,建议尽可能的使用分片集合以充分利用性能,详情请参见设置数据分片以充分利用分片性能。 分片集合使用上建议如下: 对于大数据量(数据量过百万),并有较高读写请求的业务场景,数据量随着业务量增大而增大的,建议采用分片。 对于采用hash分片的集合,需要根据业务后面实际数据量大小,采用预分片,提前预置chunk数量,减少自动均衡和分裂对业务运行造成影响。 对于非空集合开启分片,应将均衡器的开启时间窗放在业务空闲时,避免分片间均衡数据与业务冲突影响性能。设置时间窗口的API接口详情请参见设置集群均衡活动时间窗。 需要基于分片键排序查询且增加数据时可以分布均匀建议使用范围分片,其他使用哈希分片。 合理设计shard key,防止出现大量的数据使用相同shard key,导致出现jumbo chunk。 使用分片集群,执行dropDatabase后,一定要执行flushRouterConfig命令,详情请参见如何规避dds mongos路由缓存缺陷。 业务的update请求需要注意与片键相适配。在使用分片表时,如果出现如下场景则update请求会报错,并返回“An upsert on a sharded collection must contain the shard key and have the simple collation”。 update请求的filter中未携带片键字段且选项multi:false set中未携带片键字段且选项upsert:true
  • 索引设计规范 使用逻辑复制时,对需要进行逻辑复制的表设计主键或者唯一键。 使用外键时,一定要设置外键被删除或更新的动作,例如ON DELETE CASCADE。 在使用频繁(如查询、排序)的字段上创建索引。 对于固定条件的查询,建议创建并使用部分索引。 对于经常使用表达式作为查询条件的查询,建议创建并使用表达式索引。 索引也会占用存储,单表索引数量不宜太多,比如单列索引个数小于5,复合索引个数小于3。
  • SQL设计 查询时指定返回需要的字段,不要返回用不到的字段。 查询或比较字段是否为NULL时,只能使用IS NULL或IS NOT NULL条件。 查询条件中,尽量使用NOT EXISTS替代NOT IN。 聚合数据时,尽量使用UNION ALL代替UNION。 删除数据时,尽量使用TRUNCATE代替全表DELETE。 分批提交大事务中对数据的修改,防止事务提交或回滚时压力集中。 创建函数时,应该定义函数易变性分类为对它们合法的分类中最严格的种类,而不是选择默认的VOLATILE。VOLATILE类函数调用并发过高可能导致新连接无法接入。
  • 数据库连接 使用GeminiDB Mongo时,可能会遇到因为mongod连接数用满了,导致客户端无法连接的问题。mongod的服务模型是每个网络连接由一个单独的线程来处理,每个线程配置了1MB的栈空间,当网络连接数太多时,过多的线程会导致上下文切换开销变大,同时内存开销也会上涨。 客户端使用GeminiDB Mongo驱动连接数据库的时候,一定要配置连接池,连接池大小最大不要超过200。 客户端使用GeminiDB Mongo驱动连接数据库的时候,要计算业务一共有多少个客户端, 每个客户端配置的连接池大小是多少,总的连接数不要超过当前实例能承受的最大连接数的80%。 对于副本集,客户端需要同时配置主备节点的IP地址。 GeminiDB Mongo默认提供rwuser用户,使用rwuser登录时认证库必须是admin。 父主题: 使用规范
  • 数据库索引设计规范 每个InnoDB表强烈建议有一个主键,且不使用更新频繁的列作为主键,不使用多列主键。不使用UUID、MD5、字符串列作为主键。最好选择值的顺序是连续增长的列作为主键,所以建议选择使用自增ID列作为主键。 限制每张表上的索引数量,建议单张表索引不超过5个。索引并不是越多越好,索引可以提高查询的效率,但会降低写数据的效率。有时不恰当的索引还会降低查询的效率。 禁止给表中的每一列都建立单独的索引。设计良好的联合索引比每一列上的单独索引效率要高出很多。 建议在下面的列上建立索引: 在SELECT,UPDATE,DELETE语句的WHERE从句上的列。 在ORDER BY,GROUP BY,DISTINCT上的列。 多表JOIN的关联列。 索引列顺序: 区分度最高的放在联合索引的最左侧。区分度=列中不同值的数量/列的总行数。 尽量把字段长度小的列放在联合索引的最左侧。因为字段长度越小,一页能存储的数据量越大,IO性能也就越好。 使用最频繁的列放到联合索引的左侧。这样可以比较少的建立一些索引。 避免冗余的索引,如:primary key(id),index(id),unique index(id) 避免重复的索引,如:index(a,b,c),index(a,b),index(a),重复的和冗余的索引会降低查询效率,因为Flexus云数据库RDS查询优化器会不知道该使用哪个索引。 在VARCHAR字段上建立索引时,需指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索引长度即可。 一般对字符串类型数据,长度为20的索引,区分度会高达90%以上,可以使用 count(distinct left(列名, 索引长度))/count(*) 的区分度来确定。 对于频繁查询优先考虑使用覆盖索引。 覆盖索引指包含了所有查询字段的索引,不仅仅是WHERE从句GROUP BY从句中的列,也包含SELECT查询的列组合,避免InnoDB表进行索引的二次查询。 外键约束: 建立外键关系的对应列的字符集必须保持一致或者存在外键关系的子表父表的字符集保持一致。
  • 数据库基本设计规范 所有表如果没有特殊需求,都要使用InnoDB存储引擎。InnoDB存储引擎支持事务、行级锁、具有更好的恢复性、高并发下性能更强。 数据库和表的字符集统一使用UTF8字符集,避免由于字符集的转换产生乱码。 所有的表和字段都需要添加注释。使用comment从句添加表和列的备注,从设计初期维护好数据字典。 表单行长度不得超过1024字节。 谨慎使用Flexus云数据库RDS分区表,避免跨分区查询,否则查询效率会降低。分区表在逻辑上表现为一个表,但是在物理层面上将数据存储在多个文件。 表中的列不要太多,尽量做到冷热数据分离,减小表的宽度,以便在一页内存中容纳更多的行,进而减少磁盘IO,更有效的利用缓存。 经常一起使用的列尽量放到一个表中,避免过多的关联操作。 禁止在表中建立预留字段,否则修改列的类型会导致锁表,修改一个字段类型的成本要高于增加一个字段。 禁止在数据库中存储图片、文件等大的二进制数据。 不建议使用全文索引,社区MySQL全文索引局限性较多。
  • 数据库命名规范 所有的数据库对象名称(包括库名、表名、列名等)建议以小写字母命名,每个单词之间用下划线分割。 所有的数据库对象名称禁止使用Flexus云数据库RDS保留关键字。 MySQL官方保留字与关键字(MySQL 8.0):https://dev.mysql.com/doc/refman/8.0/en/keywords.html MySQL官方保留字与关键字(MySQL 5.7):https://dev.mysql.com/doc/refman/5.7/en/keywords.html 数据库对象的命名要能做到见名知意,并且不超过32个字符。 数据库中用到的临时表以“tmp”为前缀并以日期为后缀。 数据库中用到的备份表以“bak”为前缀并以日期为后缀。 在不同的库或表中,要保证所有存储相同数据的列名和列类型必须一致。
  • 数据库字段设计规范 控制单表字段数量,字段上限50左右。 优先为表中的每一列选择符合存储需要的最小的数据类型。优先考虑数字类型,其次为日期或二进制类型,最后是字符类型。列的字段类型越大,建立索引占据的空间就越大,导致一个页中的索引越少,造成IO次数增加,从而影响性能。 整数型选择能符合需求的最短列类型,如果为非负数,声明需是无符号(UNSIGNED)类型。 每个字段尽可能具有NOT NULL属性,int等数字类型默认值推荐给0,varchar等字符类型默认值给空字符串。 避免使用ENUM类型,可以用TINYINT类型替换。 修改ENUM值需要使用ALTER语句,ENUM类型的ORDER BY操作效率低,需要额外操作。 如果定义了禁止ENUM的枚举值是数值,可使用其他数据类型(如char类型)。 实数类型使用DECIMAL,禁止使用FLOAT和DOUBLE类型。 FLOAT和DOUBLE在存储的时候,存在精度损失的问题,很可能在值的比较时,得到错误的结果。 使用datetime、timestamp类型来存储时间,禁止使用字符串替代。 使用数字类型INT UNSIGNED存储IP地址,用INET_ATON、INET_NTOA可以在IP地址和数字类型之间转换。 VARCHAR类型的长度应该尽可能短。VARCHAR类型虽然在硬盘上是动态长度的,但是在内存中占用的空间是固定的最大长度。 使用VARBINARY存储大小写敏感的变长字符串,VARBINARY默认区分⼤小写,没有字符集概念,速度快。
  • 数据库实例 数据库实例类型选择 表1 数据库实例类型选择 实例类型 说明 高可用 一主一备的经典高可用架构。适用于大中型企业的生产数据库,覆盖互联网、物联网、零售电商、物流、游戏等行业应用。 备节点提高了实例的可靠性,创建主节点的过程中,同步创建备节点,备节点创建成功后,支持开放可读能力。 当主节点故障后,会发生主备切换,数据库客户端会发生短暂中断,数据库客户端需要支持重新连接。 单机 采用单个数据库节点部署架构,只包含一个节点,但具有高性价比。 适用于个人学习、微型网站以及中小企业的开发测试环境。 单机出现故障后,无法保障及时恢复。 只读 只读实例为单机版只读实例。 购买只读实例时,注意表库名的大小写敏感要与主实例保持一致。 当只读实例与主数据库之间复制异常后,需要较长时间重建和恢复(取决于数据量)。 只读实例创建完成后,可通过time_zone参数修改时区。要求只读实例的时区和主实例一致,否则会导致数据同步异常。 实例性能规格选择 支持独享型实例规格,完全独享的CPU和内存,性能长期稳定,不会因为物理机上其它实例的行为而受到影响,适用于对性能稳定性要求较高的应用场景。
  • 备份恢复 业务高峰时执行备份可能会备份失败,建议手动备份选择在业务低峰期间,自动备份建议根据业务需要自定义备份时间段(默认自动备份时间段为01:00-02:00 (GMT+08:00))。 实例写入业务较多时,建议备份策略设置成每天做一次自动备份。 建议根据业务需要设置备份保留天数(默认保留7天)。 建议根据业务需要设置Binlog本地保留时长(默认为0,表示Binlog备份完成后本地日志会被删除)。 使用表级时间点恢复功能时,建议提前确认所选时间点之前是否有对无主键大表的删除操作,如果有该操作,恢复完成时间不易评估。 创建实例前建议根据需要选择存储类型。 删除实例后,自动备份的全量备份和Binlog备份也会删除,对数据有需要时,建议删除前进行手动全量备份。 建议自定义回收站策略,防止误删实例无法恢复。