我知道 254 个字符的电子邮件地址是有效的,但我研究过的实现倾向于使用 varchar(60) 到 varchar(80) 或等效的。例如:此 SQL Server 建议使用 varchar(80) 或此 Oracle 示例
是否有理由不使用最大 254 个字符?根据定义,varchar 不是只使用存储数据所需的存储空间吗?
是否存在显着的性能影响/权衡导致如此多的实现使用少于全部 254 个可能的字符?
我知道 254 个字符的电子邮件地址是有效的,但我研究过的实现倾向于使用 varchar(60) 到 varchar(80) 或等效的。例如:此 SQL Server 建议使用 varchar(80) 或此 Oracle 示例
是否有理由不使用最大 254 个字符?根据定义,varchar 不是只使用存储数据所需的存储空间吗?
是否存在显着的性能影响/权衡导致如此多的实现使用少于全部 254 个可能的字符?
我一直用
varchar(320)
,但真的应该是varchar(319)
。这就是为什么。该标准规定了以下限制:@
符号1 个字符。<
周围尖括号>
)。现在,有些人会说您需要支持的不仅仅是这些。有些人还会说您需要为域名支持 Unicode(这意味着您必须切换到 Unicode
nvarchar
)。虽然标准可能会在此期间发生变化(我已经有一段时间没有参与游戏了),但我非常有信心,此时世界上大多数服务器都不会接受 Unicode 电子邮件地址,我敢肯定许多服务器在创建和/或接受大于 319 个字符(可能大于 254/255/256)的地址时会遇到问题。一个合理的上限应该更像是 128 个字符,因为实际上,比这更长的 e-amil 地址根本不实用,即使它们是在某些服务之外自动完成的。也就是说,您现在可以为最坏的情况做好准备,如果您愿意(并且如果您在 SQL Server 2008 R2 或更高版本中使用数据压缩,您将受益于 Unicode 压缩,这意味着您只需为实际需要的字符支付 2 字节的损失它)。这样,您可以使您的专栏尽可能宽,并且您可以让人们在其中塞入他们想要的任何太长的垃圾 - 如果他们给您垃圾,他们就不会收到电子邮件,就像他们不会一样如果插入失败,将收到一封电子邮件。问题是如果你让无效的垃圾进入,你必须处理它。而且无论您制作什么大小 - 如果有人试图将 400 个字符填充到 319 个字符的列中,那么有人会尝试将 1025 个字符填充到 1024 个字符的列中。任何明智的人都没有理由拥有大于 319 个字符的电子邮件地址,除非他们使用它来明确测试系统边界。
但我认为我们需要停止就此征求意见- 并停止查看其他实现以寻求指导(在这种情况下发生的情况是,您引用的那些没有费心做自己的功课,只是从中挑选数字,嗯,你知道的)。您可以直接访问该标准- 确保您查阅最新版本,至少支持该标准,并保持在标准之上,以便您可以适应规范的变化。
编辑感谢@ypercube 在聊天中的 ping。
顺便说一句,也许您一开始就不想将整个地址转储到单个列中。规范化可能表明您不想存储
@hotmail.com
1500 万次,因为更精简的 FK int 可以正常工作并且没有可变长度列的额外开销。您还可以规范化用户名,[email protected]
并[email protected]
共享一个共同的用户名 - 他们彼此不认识,但您的数据库并不关心这一点。我在这里谈到了一些:
然而,这对上述 254 个字符的限制提出了挑战,因为对于将有效的 255 个字符的域与有效的 1 个字符的本地部分组合时会发生什么似乎并没有达成共识。这应该被世界上大多数服务器接受,但似乎违反了这个 254 个字符的限制。那么,当域可以重新用作有效的 255 个字符的 URL时,您是否会创建一个
Domains
人为地降低电子邮件地址长度限制的表?编辑有一条评论:
虽然我同意“无限”字符串列的用例,但这不是其中之一。当您从完善的标准中了解数据域时,您应该使用它们。该链接讨论了如果您选择不当,这可能会导致最终用户出错。所以呢?没有理由让人们在域之外插入值(例如,一个 6 亿字符长的电子邮件地址),以免他们这样做时出错。事实上,我认为电子邮件正是链接所讨论的那种反例。
至少在 SQL Server 中正确定义列意味着您不会遭受记录在案的类型性能损失或
max
由于varchar/nvarchar
声明太宽而浪费内存。虽然使用检查约束来限制长度使得以后在任一方向上调整最大长度变得更加容易,但这似乎与正确的列定义相比没有任何其他好处(用户无论哪种方式都会出错)。这个决定有几个考虑因素。首先也是最重要的是使用数据必须符合的必要限制的当前和未来预测。
varchar(1024)
当您只存储不应超过 32 个字符的字符串(强调should关键字)时,您不想将每个字符串列数据类型设置为这是有原因的。如果您有某种漏洞,将电子邮件全部修改为 255 个字符,那么您可能会对页面拆分产生长期的性能影响。这可能看起来不寻常,而且很可能是这样,但您需要根据业务需求调整数据大小。就像数据库与应用程序辩论中的古老约束一样,我坚信数据类型限制和允许值也应该在数据层强制执行。
这让我想到了下一点。数据库很可能只是数据层。应用层使用什么?例如,如果您有一个应用程序,您只能为电子邮件地址输入 80 个字符,那么您为什么希望数据类型更大呢?企业需要回答两个问题:
只有这样你才会有答案。
是和不是。可变长度数据将有一种偏移量来记录它的长度。
RFC 5321(当前的 SMTP 规范,已废弃 RFC2821)指出:
所以 64 + 255 + @ 符号意味着 VARCHAR(320)。您可能永远不需要这么多,但以防万一,拥有它是安全的。
作为对已经在这里的出色答案的评论:
首先,如果您已经创建了字段 as
varchar(240)
并且您想稍后将其更改为更长的字段,例如varchar(320)
,那么此更改应该是数据库服务器上的一个微不足道的操作 - 当然,这取决于您的数据库产品。其次,根据平均行大小和页大小,使用
varchar(320)
代替varchar(240)
可能不会改变分配的页数(表实际占用的磁盘空间)。第三,上面有人谈到验证电子邮件地址。我认为只有一种确定的方法可以验证电子邮件地址,那就是向它发送电子邮件。:-)
VARCHAR 的任何变体仅使用数据块中所需的空间。与使用固定长度 CHAR 所浪费的空间相比,用于存储长度的额外字节是微不足道的。
由于 VARCHAR 列长度实际上是“最大长度”,因此在任何情况下都应将其设置为大于可能的最大长度。只会使用每行所需的空间。然后应用程序应该设计有滚动字段或任何基于典型值有意义的东西。
数据库设计就像一张物理纸,它规定了大小的硬性限制。纸页无法放大。在这个比喻中,应用程序就像打印在页面上的表格。可以做很多事情来调整我们可以在表单中保存多少数据。
尽管增加 VARCHAR 大小的命令可能看起来很简单并且可以立即在小表上运行,但在具有数千行或更多行的表上这样做可能需要某种数据库静默,同时重新生成所有数据和索引块。一种方法是将所有内容复制到具有较大列的新表中。无论使用什么技术,这都是一笔大买卖。因此,一旦加载生产表,您应该考虑 VARCHAR 列大小在很大程度上是不可变的。
VARCHAR 是用于电子邮件地址的最佳数据类型,因为电子邮件的长度变化很大。NVARCHAR 也是一种替代方法,但我建议仅在电子邮件地址包含扩展字符时使用它,并且请记住,与 VARCHAR 相比,它需要双倍的存储空间。
在我的环境中,我们使用 varchar(70),因为我遇到的最长的是 60-70 字符长,但这也取决于贵公司的客户群。此外,作为旁注,请确保您对电子邮件地址的有效性进行了一些电子邮件验证检查。例如使用检查约束或 CHARINDEX
使用 SQL
DOMAIN
如果您使用的是企业数据库服务器,则应该以某种方式将电子邮件地址存储为
DOMAIN
具有某种程度的有效性。域在 SQL 规范中指定例如,免费和开源的 PostgreSQL 支持这一点,除非您对规范的实施有任何限制,否则该列本身包含有效的电子邮件。例如你可以..
DOMAIN
通过电子邮件的 HTML5 规范创建自定义。DOMAIN
,在检查时检查服务器的 MX 记录。我在这个特定于 PostgreSQL 的答案中评估这些选项