有奖捉虫:办公协同&微信生态&物联网文档专题 HOT
本文为您介绍云数据库 SQL server 的使用规范以及建议。

目的

规范化对云数据库 SQL Server 的管理和维护,避免操作不当对云数据库 SQL Server 造成不可用等影响。
指导数据库开发人员合理编写 SQL,发挥云数据库 SQL Server 最优性能。

实例规格建议

生产环境尽量不要使用1核规格的实例,1核规格实例可用于体验测试。
建议生产环境至少使用2核及以上规格。由于 SQL Server 使用 Windows 系统,引擎及系统本身需要的资源较多,1核规格不适合运行生产业务,长时间运行后可能会有系统低内存及系统卡顿问题。

实例选型建议

推荐使用双节点(原高可用版/集群版)主备实例。相比于单节点(原基础版)单机实例,双节点实例可以极大提高生产业务的可用性和可靠性。
如果业务有少量写请求、大量读请求,需要添加只读实例时,建议使用双节点 SQL Server 2017 enterprise 版或 SQL Server 2019 enterprise 版,数据同步更高效更稳定。
高可用/集群版实例尽量选择跨 AZ 部署,进行 AZ 级别的容灾。

数据库连接建议

连接云数据库 SQL Server 时,请使用“ip,port”的方式连接,注意连接串中间为逗号。
不建议使用服务器名字连接。应用连接数据库时建议要有重试机制,当数据库发生容灾或者断连时,应用可以通过重试及时恢复连接。

权限管理规范

考虑到云数据库 SQL Server 的稳定性和安全性,云数据库 SQL Server 限制了 sysadmin、shutdown 等权限,有时在云数据库 SQL Server 上执行部分语句时,会出现如下的相关报错:
User does not have permission to perform this action.
You do not have permission to run the RECONFIGURE statement. 解决方法:参数修改,数据库管理,用户管理,备份恢复等操作建议在控制台进行。
按需授权,一般应用程序只授予指定数据库的读写权限即可。
授权对象最小化原则,一般的应用程序访问用户按库级别来授权。
授权用户访问时只允许特定 IP 或 IP 段访问,可以在控制台配置安全组来做限制,安全组的设置请一定按照控制台提示的标准来操作。
管理账号,开发账号,应用账号分离。避免使用管理员账号进行开发或者作为业务账号使用。

日常操作规范及使用建议

从性能上考虑,数据库数量过多会导致实例性能下降,占用 Worker Thread 等资源,同时超过数据库数量创建限制,易发生主备同步异常。建议单实例创建的数据库数量不要超过其最大限制,单实例可以承载的数据库数量跟实例 CPU 核数相关,详细的各版本对应最大数据库数量计算公式请参见 数据库数量
数据库名长度不要超过64个字符,且数据库名当前仅支持数字、大小写字母、下划线_,不支持其他特殊字符。
禁止使用弱密码,提升数据库实例安全性。如非必要请在控制台进行账号和数据库的管理操作。
内网连接登录须确保客户端的云服务器 CVM 与云数据库 SQL Server 是同一账号同一地域同一 VPC 内的机器。
应用不能依赖 sysadmin 权限。具有 sysadmin 角色的账号有超级管理员权限,使用不当会导致数据库安全与稳定性受到威胁,云数据库默认不开放超级管理员权限,应用使用数据库不能依赖于此权限。
关注数据库大小并及时收缩数据库。数据库长时间使用可能会有一些物理空间无法及时释放,需要执行收缩数据库操作才能释放物理空间。需关注日志文件大小及物理文件大小,发现文件膨胀迅速可以在业务低峰期收缩数据库。
建议长时间运行的实例在业务低峰期可以重启。实例长时间运行后可能会出现性能下降,推荐每三个月能够在业务低峰期重启一次实例。
不要在系统库创建表。用户数据请创建用户自定义库存放,不要在系统库创建任何表写入数据,虽然开放了使用系统库的权限,但是任何在系统库存放的数据都是不安全的。
不要将数据库设置为 Single User 模式。Single User 模式只允许一个 Session 访问数据库,会导致其他 Session 无法访问造成云数据库的运维问题。设置 Single User 模式请及时恢复到 Multi User 模式。
慢日志采集用的是扩展事件,属于轻量级跟踪,基本不会对实例产生影响。
定时重建索引。数据库在长时间使用后可能会产生较多的索引碎片,导致数据库访问性能下降,需要定时进行索引重建,可以采用创建 SQL Agent Job 的方式定时重建索引,建议一个月重建一次索引。
定时更新统计信息。数据库统计信息需要经常更新对于性能有益。建议采用创建 SQL Agent Job 的方式每周更新一次统计信息。
设置最大并行度。最大并行度参数影响业务的 CPU 使用率。
备份恢复相关操作请通过管理控制台下发或调用 API 接口下发,不能通过 SSMS 或执行 SQL 直接操作。备份恢复方式迁移上云请参考 冷备迁移
数据库恢复模式(Recovery model)不要设置为 simple 模式,建议使用 full 模式。
设置为 simple 模式将不会对该库执行增量备份,因此该库无法恢复到指定时间点。
对于双节点(原高可用版/集群版)实例,设置数据库恢复模式是 simple 模式后,会导致该库不会建立复制关系,进而无法操作主备切换或者规格变更。 因此,请谨慎使用 simple 模式。
尽量避免业务高峰期做 ddl 操作。
尽量避免业务高峰期批量操作数据,最好在业务低峰期分批来操作。如要全表删除建议业务低峰期使用 truncate 或者 drop。
尽量避免一个实例跑多个业务,耦合度太高会存在业务之间互相影响的风险。
建议避免使用事务自动提交,线上操作养成 begin tran;先行的习惯,降低误操作导致数据丢失的风险,误操作亦可使用云数据库 SQL Server 的回档功能。事务开启之后请及时提交,避免出现实例阻塞。
数据库的操作建议在控制台完成,不建议在 SSMS 客户端直接操作数据库。
业务有推广活动等,请提前预估资源并做好实例相关优化,如需求量比较大时请及时与对应的商务联系。

DTS 数据库迁移建议

迁移上云进行前,需要进行以下检查:
需要检查源及目标数据库版本号。目标数据库的版本号需要大于或等于源数据库的版本号,例如源库为2016版,则迁移的目标库只能为2016、2017、2019版本。
需要检查源及目标数据库架构版本。当源实例为本地 IDC 自建、腾讯云 CVM 服务器自建、其他云厂商的云服务器自建、其他云厂商的云数据库 SQL Server 实例时,可以迁移到腾讯云单节点(原基础版)、双节点(原高可用版/集群版)任意架构版本的 SQL Server 实例;当源实例为腾讯云双节点(原高可用版/集群版)实例时,不能通过 DTS 迁移到腾讯云单节点(原基础版)实例;当源实例为腾讯云单节点(原基础版)实例时,可以通过 DTS 迁移到腾讯云双节点(原高可用版/集群版)实例。
需要检查源及目标数据库网络连通性。源库和目标库数据库网络要能够连通。且源库所在服务器需具备足够的出口带宽,否则将影响迁移效率。
需要检查源及目标端数据库命名。目标端不能和源端有重名的数据库。
需要检查源端数据库实例账号权限。迁移源端的 SQL 服务启动需要改为 local,源端迁移的数据库账号无限制,但是需要有 sysadmin 权限。
需要检查目标端数据库实例账号权限。目标端需使用具有管理员权限的账号进行迁移。
需要检查源端数据库端口开放。源数据库需要开放1433端口,且因 Windows Server 共享问题,源数据库所在的服务要开放文件共享端口445。
需要检查源端数据库恢复模式。源数据库必须得设置为“完全恢复模式”,且在迁移前建议用户自己做下全量备份。
需要检查源端数据库本地盘空间。源数据库所在本地磁盘空间需要足够大,剩余空闲空间能放下要迁移库的大小。
需要检查目标数据库的磁盘空间。目标库所在的磁盘空间要大于源库大小,尽量为源库大小的1.5倍。
需要检查目标端数据库状态。目标端不能有访问,不能有负载业务进行,否则会导致迁移失败。
迁移上云过程中,有以下操作限制需要注意:
同一源实例同一时间只能发起一个迁移任务。
只支持库粒度迁移,即在迁移过程中,只支持将库的所有对象一起迁移,不支持单个表的迁移。
不支持迁移实例级别的 login、job、触发器、db link (link server)。
迁移过程中,请勿修改、删除源数据库和目标数据库中用户信息(包括用户名、密码和权限)和端口号,否则会导致迁移任务失败。
增量同步的过程中,不能进行事务日志备份,否则会截断事务日志,导致事务日志不能连续。
如果仅执行全量数据迁移,请勿在迁移过程中向源实例中写入新的数据,否则会导致源和目标数据不一致。针对有数据写入的场景,为实时保持数据一致性,建议选择全量 + 增量数据迁移。
针对全量 + 增量数据迁移,当单击完成,任务状态为完成中时,请勿向源数据库中写入新的数据,建议在单击完成后,停写两分钟,否则可能会导致源和目标库的数据不一致。
迁移上云完成后,需要进行以下检查:
需要检查权限完整性。权限会影响对于数据库的方案,迁移仅会完成数据恢复。数据库用户恢复,登录名等其他服务级权限需要重新创建,并且关联数据库账户。
需要对索引进行重建。由于迁移完成后数据文件的物理环境发生了改变,数据库索引会失效,需要对索引进行重建,否则可能会导致数据库性能有明显下降。
需要检查实例级别的对象。例如 login、job、触发器、db link (link server)等,迁移完成后,需要用户自己去重建。

库表设计规范

注意事项
云数据库 SQL Server 2014以下版本不支持 MemoryTable,若有 MemoryTable 类的需求建议使用云数据库 Redis、Memcached。
新建表建议遵循数据库三范式,每张表建议要有主键,即使选不出合适的列做主键,也要添加一个列做主键。
字段尽量定义为 NOT NULL 并加上默认值,NULL 会给 SQL 开发带来很多问题导致走不了索引,对 NULL 计算时只能用 IS NULL 和 IS NOT NULL 来判断。
建议事项
通过业务场景分析和数据访问(包括数据库读写 QPS、TPS、存储空间等)的预估,合理规划数据库使用资源,也可以在腾讯云可观测平台控制台界面,配置云数据库 SQL Server 实例的各项监控。
建库原则就是同一类业务的表放一个库,不同业务的表尽量避免公用同一个库,尽量避免在程序中执行跨库的关联操作,此操作对后续的快速回档也会产生一定的影响。
字符集建议统一使用一个字符集,避免不同字符集之间数据乱码。
小数字段推荐使用 decimal 类型,float 和 double 精度不够,特别是涉及金钱的业务。
尽量避免数据库中使用 text/blob 来存储大段文本、二进制数据、图片、文件等内容,而是将这些数据保存成本地磁盘文件,数据库中只保存其索引信息。
尽量不使用外键,建议在应用层实现外键的逻辑,外键与级联更新不适合高并发场景,降低插入性能,大并发下容易产生死锁。
降低业务逻辑和数据存储的耦合度,数据库存储数据为主,业务逻辑尽量通过应用层实现,尽可能减少对实例级别的触发器、linkserver、job 等高级功能的使用,这些功能移植性、可扩展性较差,若实例中存在此类对象,迁移之后需要手动再将这些对象迁移到新的实例。
短期内业务达不到一个比较大的量级,建议避免使用分区表。分区表主要用作归档管理,在业务中大部分的查询不走分区字段的情况下,分区表对性能提升作用不大。
对读压力较大,且一致性要求较低(接受数据秒级延时)的业务场景,建议购买只读实例来实现读写分离策略。

索引设计规范

注意事项
建议不要在更新十分频繁、区分度不高的列上建立索引,记录更新会变更 B+ 树,更新频繁的字段建立索引会大大降低数据库性能。
建复合索引时,区分度最高的列放索引的最左边,例如 select xxx where a = x and b = x;,a 和 b 一起建组合索引,a 的区分度更高,则建 idx_ab(a,b)。业务存在大量非等号和等号混合判断条件场景时,建议把等号条件的列前置,例如,where a xxx and b = xxx那么即使 a 的区分度更高,也建议把 b 放在索引的最前列,因为走不到索引 a。
建议事项
单表的索引数建议不超过5个,单个索引中的字段数建议不超过5个,太多起不到过滤作用,索引也占空间,管理起来也耗资源。
选择业务中 SQL 过滤走的最多的并且重复值比较少的列建索引,业务 SQL 不走的列建索引是无意义的,字段的唯一性越高索引过滤效果也越好。
避免冗余索引,两个索引 (a,b) (a) 同时存在,则 (a) 属于冗余索引 redundant index,若查询过滤条件为 a 列,(a,b) 索引就够了,不用单独建 (a) 索引。
合理利用 Include 索引来降低 IO 开销,常用的列放在前面,不会作为查询条件的列可以放在 Include 中。

SQL 编写规范

注意事项
UPDATE、DELETE 建议使用 WHERE 精准匹配,需要删除大量数据建议分批处理并在业务低峰期进行。
使用 INSERT INTO t_xxx VALUES(xxx),建议显式指定插入的列属性,避免表结构变动导致数据出错。
SQL 语句中最常见的导致索引失效的情况需注意:
隐式类型转换,如索引 a 的类型是 varchar,SQL 语句写成 where a = 1; varchar 变成了 int。
对索引列进行数学计算和函数等操作,例如,使用函数对日期列进行格式化处理。
多列排序顺序不一致问题,如索引是 (a,b),SQL 语句是 order by a b desc。
尽量使 where 条件完全匹配避免条件的模糊匹配和 in,not in 批量匹配。
建议事项 按需索取,拒绝 select *,规避以下问题:
无法索引覆盖,回表操作,增加 I/O。
额外的内存负担,大量冷数据导入缓存,降低查询命中率。
额外的网络传输开销。
尽量避免使用大事务,建议大事务拆小事务,规避大事务造成实例阻塞或主从延迟。
业务代码中事务及时提交,避免产生没必要的锁等待。
尽量减少用多表 join,大表 join。两张表 join 尽量让小表做驱动表,建议 join 列类型一致且都建有索引。
说明
上述情况很难完全避免,推荐方案是不要将此类条件作为主要过滤条件,跟在走索引的主要过滤条件之后则问题不大。
若您在监控上发现全表扫描的量比较大,可以在控制台下载慢日志文件分析。
业务上线之前做有必要的 SQL 审核,日常运维需定期下载慢查询日志做针对性优化。