设计表的时候,对变长字段长度选择的一点思考

简介: 原文:设计表的时候,对变长字段长度选择的一点思考不管是在MSSQL还是MySQL或者Oracle,变长字段的长度衡量都是要经常面对的。对于一个变长的字段,在满足业务的情况下(其实所谓的满足业务是一个比较模糊的东西),到底是选择varchar(50)还是varchar(200)亦或是varchar(500)?对于保守型选择,往往是选择一个较大的长度,比如varchar(500)要比varchar(50)更具有兼容性,因为是变长字段的原因,存储空间也一样。
原文: 设计表的时候,对变长字段长度选择的一点思考

不管是在MSSQL还是MySQL或者Oracle,变长字段的长度衡量都是要经常面对的。
对于一个变长的字段,在满足业务的情况下(其实所谓的满足业务是一个比较模糊的东西),到底是选择varchar(50)还是varchar(200)亦或是varchar(500)?
对于保守型选择,往往是选择一个较大的长度,比如varchar(500)要比varchar(50)更具有兼容性,因为是变长字段的原因,存储空间也一样。
这样的选择并不能说就不好,看站在哪个角度来看问题。
那么,相对于varchar(50),varchar(500)在更具备兼容性的同时,有哪些不好的地方,也是需要思考的,。

这里的原则就是:对于可变长度的字段,在满足条件的前提下,尽可能使用较短的变长字段长度。

 

以下是一个相对极端的例子,以SQL Server为例,
TestVarchar1和TestVarchar2的SortColumn 字段长度分别是varchar(50)和varchar(8000),两个表写入10000条测一样的试数据,
SortColumn 的实际长度是36个字符。

Create Table TestVarchar1
(
    Id INT IDENTITY(1,1),
    SortColumn varchar(50)
)

Create Table TestVarchar2
(
    Id INT IDENTITY(1,1),
    SortColumn varchar(8000)
)

DECLARE @SortColumn char(36);
set @SortColumn = CAST(NEWID() as char(36))
insert into TestVarchar1(SortColumn) values (@SortColumn)
insert into TestVarchar2(SortColumn) values (@SortColumn)
GO 10000

 

1,基于存储空间的考虑

存储空间上,存储不超过一定长度的变长字段,不同长度的变长字段存储空间是一样的,比如选择使用varchar(50)和varchar(500)是一样的,
也就说,对于不超过50个字符串的数据存储,两者在物理空间占用上并没有区别。

这里会发现,两个表的数据在完全一致的情况下,其存储空间也是完全一样的,的确,并不会因为varchar使用一个较长的长度而多占用存储空间

2,基于性能的考虑
选择varchar(50)还是varchar(8000),在性能上确实有显著的差异,考虑到某些查询需要内存(Memory Grant),查询引擎会预估当前查询需要的内存,影响查询内存的因素有以下几个方面
1,查询的类型,有没有聚合运算,有没有排序等等
2,每个操作符涉及到的记录数量
3,数据行的大小(这里是字段类型的长度而不是字段实际长度)
当行记录的数据类型长度较大的时候,执行计划预估的平均大小较大,数据类型定义的长度越大,预估的长度越大,需要分配的内存越大
如果一个查询涉及一些聚合操作并且数据量较大,就可能需要大量的内存来完成这个查询,查询引起会分配多余实际需要的内存。

两者对数据行Size的预估是一样的(尽管是完全一样的数据)

造成的结果就是两个查询的内存授予是一样的,同时第二个执行计划还有一个警告信息(黄色的感叹号)

以上可以看出,尽管两个表的数据是完全一致的,
不过字段的最大长度不一致,造成执行计划预估出现较大的偏差,因此给予较高的内存,浪费无所谓的资源。

再看一个通过聚合函数操作两张表的例子,会增加CPU的使用。

因此对于可变长度的字段,在满足条件的前提下,尽可能使用较短的变长字段长度。

 

 

当然,较大的字段(相比较小)还可能存在一些不是太直观的影响,参考:https://yq.aliyun.com/articles/17147?spm=a2c4e.11155435.0.0.578a71a89qSBMc

目录
相关文章
|
4月前
ASCII码表
ASCII码表
25 0
|
存储 数据库
长整数在插入较短的列时会被转换,但不会被截断为什么?公式是什么?
长整数在插入较短的列时会被转换,但不会被截断为什么?公式是什么?
|
存储 SQL 数据库
数据库字段长度多少才是合理的
设计数据库时经常要做的就是给字段设置数据类型,但是对于一些字段是需要设置长度的,那么需要设置多少长度才算是合适的?
1898 0
|
存储 SQL 缓存
InnoDB(1)变长字段长度列表--mysql从入门到精通(六)
InnoDB(1)变长字段长度列表--mysql从入门到精通(六)
C#编程-125:ASCII码表
C#编程-125:ASCII码表
363 0
C#编程-125:ASCII码表
|
关系型数据库 MySQL PHP
mysql获取字段长度,mysql查询字段长度
mysql获取字段长度,mysql查询字段长度
2067 0
|
人工智能 自然语言处理 算法
快抖“变长”,爱优腾“变短”
快抖“变长”,爱优腾“变短”
163 0
快抖“变长”,爱优腾“变短”
|
SQL Oracle 关系型数据库
三大关系数据库字段值超长的一个有趣对比
三大关系数据库字段值超长的一个有趣对比   在开发中,我们可能会遇到插入字段值超长的情况,前阵子遇到这样一个案例,结果一对比后发现一个有趣的现象,如果插入字段值超长,ORACLE、SQL Server、MySQL它们会提示那个字段值超长吗?下面看看实验吧:   ORACLE数据库   SQL> ...
1275 0
|
SQL 关系型数据库 Oracle
[20180613]缩短字段长度.txt
[20180613]缩短字段长度.txt --//最近遇到的一个问题,就是修改字段长度.理论讲增加字段长度没有什么问题,而缩短我记忆里好像不行的, --//即使当前记录满足缩短字段长度需求.
1241 0