为什么每个 RDBMS 都坚持要求你告诉它文本字段的最大长度是多少......为什么它不能从放入数据库的数据中推断出这些信息?

我主要使用 MS SQL Server,但我知道的所有其他数据库也要求您对数据模式设置这些任意限制。现实情况是,这对于工作来说并不是特别有帮助或友好,因为业务需求一直在变化,而且几乎每天都有一些最终用户试图将大量文​​本放入该列中。

任何具有 RDBMS 内部工作知识的人都知道为什么我们不从放入存储的数据中推断出限制吗?我不是在谈论猜测类型信息,而是猜测特定文本列的限制。

我的意思是,我不在数据库中的每个文本列上使用 nvarchar(max) 是有原因的。

有帮助吗?

解决方案

因为计算机(和数据库)是愚蠢的。计算机的猜测能力不太好,除非您告诉它们,否则它们无法判断某一列将用于电话号码或《战争与和平》的副本。显然,数据库可以设计为每列都可以包含无限量的数据——或者至少在磁盘空间允许的范围内——但这将是一种非常低效的设计。为了获得效率,然后,我们进行权衡,让设计者告诉数据库我们期望在列中放入多少。据推测,可能有一个默认值,因此如果您不指定它,它只会使用它。不幸的是,从效率的角度来看,任何违约可能都不适合绝大多数人。

其他提示

这与速度有关。如果指定了字符串的最大大小,您可以优化信息存储方式以加快 I/O 速度。当速度是关键时,您最不希望发生的事情就是仅仅因为您将州缩写更改为全名而突然重新整理所有数据。

设置最大大小后,数据库可以将最大空间分配给该列中的每个实体,并且无论值如何更改,都不需要更改地址空间。

这个帖子 不仅回答了您是否使用的问题 nvarchar(max) 无处不在,但它也让我们深入了解为什么数据库历史上不允许这样做。

这就像说,为什么我们不能直接告诉数据库我们想要一个表,并让它从我们提供的数据中推断出我们需要什么类型和多少列。

简而言之,我们比数据库更了解。假设您有百万分之一的机会将 2,000 个字符的字符串放入数据库中,大多数情况下,它是 100 个字符。数据库可能会炸毁或拒绝 2k 字符串。如果在前三年您只输入了 100 个长度的字符串,它根本无法知道您将需要 2k 长度。

此外,字符的长度用于优化行放置,以便可以更快地读取/跳过行。

我认为这是因为 RDBMS 使用随机数据访问。为了进行随机数据访问,他们必须知道必须跳到硬盘中的哪个地址才能快速读取数据。如果单列的每一行都有不同的数据长度,他们就无法推断出地址的起始点是什么,他们必须直接跳转才能得到它。唯一的方法是他们必须加载所有数据并进行检查。

如果RDBMS在每次添加、更新和删除时将列的数据长度更改为固定数字(例如所有行的最大长度)。这是一个极其耗时的过程

数据库的猜测基于什么?如果业务需求定期发生变化,它会和您一样感到惊讶。如果您有一个不使用 nvarchar(max) 的原因,那么可能也有一个原因它没有默认为该值......

为了举例,我将进入一些流沙并建议您将其与分配内存 (RAM) 的应用程序进行比较。为什么程序员不在程序启动时请求/分配他们需要的所有内存?因为他们常常不知道自己需要多少。这可能会导致应用程序在运行时占用越来越多的内存,并且可能还会释放内存。并且您有多个应用程序同时运行,新应用程序启动,旧应用程序关闭。应用程序总是需要连续的内存块,如果它们的内存分散在整个地址空间中,它们的工作效果就会很差(如果有的话)。随着时间的推移,这会导致内存碎片,以及几十年来人们一直在烦恼的所有垃圾收集问题。

跳回数据库。您希望您的硬盘发生这种情况吗?(请记住,硬盘性能非常, 非常 与内存操作相比慢......)

听起来您的业务规则是:在任何文本框中输入尽可能多的信息,这样您就不会生 DBA 的气。

您不允许用户输入 5000 个字符的地址,因为信封放不下。

这就是为什么推特有文本限制,让每个人都不必费力去阅读一堆无脑的胡言乱语,这些胡言乱语一直没完没了,永远没有切中要害,但只会激怒读者,让他们想知道为什么你如此无视他们的利益。通过选择一种以自我为中心和不人道的生活方式,专注于促进复制和粘贴内存缓冲区上帝允许的尽可能多的数据的行为......

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top