草庐IT

mysql - SQL varchar 列长度的最佳实践

coder 2023-05-10 原文

每次设置一个新的 SQL 表或向现有表添加一个新的 varchar 列时,我都想知道一件事:length 的最佳值是多少>。

因此,假设您有一个名为 name 的列,类型为 varchar。所以,你必须选择长度。我想不出一个> 20个字符的名字,但你永远不会知道。但我总是四舍五入到下一个 2^n 数字,而不是使用 20。在这种情况下,我会选择 32 作为长度。我这样做是因为从计算机科学家的角度来看,数字 2^n 在我看来比其他数字更 even,我只是假设下面的架构可以处理这些数字略好于其他人。

另一方面,例如 MSSQL 服务器,当您选择创建 varchar 列时,将默认长度值设置为 50。这让我思考。为什么是50?它只是一个随机数,还是基于平均列长度,还是什么?

也可能——或者可能是——不同的 SQL 服务器实现(如 MySQL、MSSQL、Postgres 等)具有不同的最佳列长度值。

最佳答案

据我所知,没有任何 DBMS 有任何“优化”可以使 2^n 长度的 VARCHARmax 执行得更好code> 长度不是 2 的幂。

我认为早期的 SQL Server 版本实际上对长度为 255 的 VARCHAR 的处理与最大长度更大的不同。我不知道现在是否仍然如此。

对于几乎所有 DBMS,所需的实际存储空间仅取决于您放入其中的字符数,而不是您定义的 max 长度。因此,从存储的角度来看(很可能也是性能方面),将列声明为 VARCHAR(100)VARCHAR(500)<>

您应该将为 VARCHAR 列提供的 max 长度视为一种约束(或业务规则),而不是技术/物理事物。

对于 PostgreSQL,最好的设置是使用没有长度限制的 text 和一个 CHECK CONSTRAINT,它将字符数限制为您的业务需要的任何内容。

如果该要求发生变化,更改检查约束比更改表要快得多(因为不需要重写表)

这同样适用于 Oracle 和其他 - 在 Oracle 中,它会是 VARCHAR(4000) 而不是 text

我不知道 VARCHAR(max) 和 e.g. 之间是否存在物理存储差异。 SQL Server 中的 VARCHAR(500)。但显然,与 varchar(8000) 相比,使用 varchar(max) 会对性能产生影响。

this link (由 Erwin Brandstetter 作为评论发表)

编辑 2013-09-22

关于bigown的评论:

在 9.2 之前的 Postgres 版本中(在我编写初始答案时不可用),对列定义的更改 确实 重写了整个表,请参见例如here .从 9.2 开始,情况不再如此,一项快速测试证实,增加具有 120 万行的表的列大小确实只需要 0.5 秒。

对于 Oracle 来说,这似乎也是正确的,从更改大表的 varchar 列所需的时间来看。但我找不到任何引用。

对于 MySQL the manual says在大多数情况下,ALTER TABLE 会制作原始表的临时副本”。我自己的测试证实:在有 120 万行的表上运行 ALTER TABLE(与我使用 Postgres 的测试相同)以增加列的大小需要 1.5 分钟。但是,在 MySQL 中,您可以使用“解决方法”来使用检查约束来限制列中的字符数。

对于 SQL Server,我找不到明确的说明,但增加 varchar 列(同样是上面的 120 万行表)大小的执行时间表明 重写发生。

编辑 2017-01-24

似乎我(至少部分)对 SQL Server 有误。见 this answer from Aaron Bertrand这表明 nvarcharvarchar 列的声明长度会对性能产生巨大影响。

关于mysql - SQL varchar 列长度的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8295131/

有关mysql - SQL varchar 列长度的最佳实践的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby-on-rails - unicode 字符串的长度 - 2

    在我的Rails(2.3,Ruby1.8.7)应用程序中,我需要将字符串截断到一定长度。该字符串是unicode,在控制台中运行测试时,例如'א'.length,我意识到返回了双倍长度。我想要一个与编码无关的长度,以便对unicode字符串或latin1编码字符串进行相同的截断。我已经了解了Ruby的大部分unicode资料,但仍然有些一头雾水。应该如何解决这个问题? 最佳答案 Rails有一个返回多字节字符的mb_chars方法。试试unicode_string.mb_chars.slice(0,50)

  3. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  4. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  5. ruby - 匹配大写字母并用后续字母填充,直到一定的字符串长度 - 2

    我有一个驼峰式字符串,例如:JustAString。我想按照以下规则形成长度为4的字符串:抓取所有大写字母;如果超过4个大写字母,只保留前4个;如果少于4个大写字母,则将最后大写字母后的字母大写并添加字母,直到长度变为4。以下是可能发生的3种情况:ThisIsMyString将产生TIMS(大写字母);ThisIsOneVeryLongString将产生TIOV(前4个大写字母);MyString将生成MSTR(大写字母+tr大写)。我设法用这个片段解决了前两种情况:str.scan(/[A-Z]/).first(4).join但是,我不太确定如何最好地修改上面的代码片段以处理最后一种

  6. ruby - 从 String#split 返回的零长度字符串 - 2

    在Ruby1.9.3(可能还有更早的版本,不确定)中,我试图弄清楚为什么Ruby的String#split方法会给我某些结果。我得到的结果似乎与我的预期相反。这是一个例子:"abcabc".split("b")#=>["a","ca","c"]"abcabc".split("a")#=>["","bc","bc"]"abcabc".split("c")#=>["ab","ab"]在这里,第一个示例返回的正是我所期望的。但在第二个示例中,我很困惑为什么#split返回零长度字符串作为返回数组的第一个值。这是什么原因呢?这是我所期望的:"abcabc".split("a")#=>["bc"

  7. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

  8. Ruby - 如何将消息长度表示为 2 个二进制字节 - 2

    我正在使用Ruby,我正在与一个网络端点通信,该端点在发送消息本身之前需要格式化“header”。header中的第一个字段必须是消息长度,它被定义为网络字节顺序中的2二进制字节消息长度。比如我的消息长度是1024。如何将1024表示为二进制双字节? 最佳答案 Ruby(以及Perl和Python等)中字节整理的标准工具是pack和unpack。ruby的packisinArray.您的长度应该是两个字节长,并且按网络字节顺序排列,这听起来像是n格式说明符的工作:n|Integer|16-bitunsigned,network(bi

  9. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  10. ruby - 在 Ruby 中将整数格式化为固定长度的字符串 - 2

    有没有一种简单的方法可以将给定的整数格式化为具有固定长度和前导零的字符串?#convertnumberstostringsoffixedlength3[1,12,123,1234].map{|e|???}=>["001","012","123","234"]我找到了解决方案,但也许还有更聪明的方法。format('%03d',e)[-3..-1] 最佳答案 如何使用%1000而不是进行字符串操作来获取最后三位数字?[1,12,123,1234].map{|e|format('%03d',e%1000)}更新:根据theTinMan的

随机推荐