在SQL Server 2005中,将所有字符字段设置为nvarchar(MAX)而不是显式指定长度(例如nvarchar(255))有什么缺点吗?(除了不能在数据库级别限制字段长度之外)
当前回答
当你知道字段将在一个固定的范围内时,这不是一个好主意——例如5到10个字符。我想我只会在不确定长度的情况下使用max。例如,电话号码永远不会超过一定数量的字符。
你能诚实地说,你不确定表中每个字段的大约长度要求吗?
我确实明白你的意思——有些字段我肯定会考虑使用varchar(max)。
有趣的是,MSDN文档总结得很好:
的大小时使用varchar 列数据条目变化很大。 的大小时使用varchar(max) 列数据条目变化很大, 大小可能超过8000字节。
关于这个问题有一个有趣的讨论。
其他回答
一个不使用max或文本字段的原因是,你不能执行在线索引重建,即REBUILD WITH online = ON,即使与SQL Server企业版。
当你知道字段将在一个固定的范围内时,这不是一个好主意——例如5到10个字符。我想我只会在不确定长度的情况下使用max。例如,电话号码永远不会超过一定数量的字符。
你能诚实地说,你不确定表中每个字段的大约长度要求吗?
我确实明白你的意思——有些字段我肯定会考虑使用varchar(max)。
有趣的是,MSDN文档总结得很好:
的大小时使用varchar 列数据条目变化很大。 的大小时使用varchar(max) 列数据条目变化很大, 大小可能超过8000字节。
关于这个问题有一个有趣的讨论。
起初我是这么想的,但后来又想了想。这样做会影响性能,但同样地,它也可以作为一种文档形式来了解字段的实际大小。当数据库位于更大的生态系统中时,它确实会强制执行。在我看来,关键是要在合理的范围内宽容。
ok, here's my feelings simply on the issue of business and data layer logic. It depends, if your DB is a shared resource between systems that share business logic then of course it seems a natural place to enforce such logic, but its not the BEST way to do it, the BEST way is to provide an API, this allows the interaction to be tested and keeps business logic where it belongs, it keeps systems decoupled, it keeps your tiers within a system decoupled. If however your database is supposed to be serving only one application, then lets get AGILE in thinking, what's true now? design for now. If and when such access is needed, provide an API to that data.
显然,这只是理想情况,如果您正在使用现有系统,那么您可能需要至少在短期内以不同的方式进行操作。
截至SQL Server 2019, NVARCHAR(MAX)仍然不支持SCSU“Unicode压缩”-即使使用行内数据存储存储。SCSU是在SQL Server 2008中添加的,适用于任何ROW/ page压缩的表和索引。
因此,即使没有存储在LOB中,具有相同文本内容的NVARCHAR(1..4000)字段所占用的物理磁盘空间也是NVARCHAR(1..4000)字段的两倍。非scsu浪费取决于所表示的数据和语言。
Unicode压缩实现:
SQL Server使用Unicode标准压缩方案(SCSU)算法的实现来压缩存储在行或页压缩对象中的Unicode值。对于这些压缩对象,对nchar(n)和nvarchar(n)列的Unicode压缩是自动的[并且从未对nvarchar(max)使用]。
另一方面,PAGE压缩(自2014年以来)仍然适用于NVARCHAR(MAX)列,如果它们被写入行内数据。所以缺乏SCSU感觉就像“缺少优化”。与SCSU不同,基于共享前导前缀(例如。重复的值)。
然而,使用NVARCHAR(MAX)可能仍然“更快”,即使使用OPENJSON这样的函数会有更高的IO成本,因为它避免了隐式转换。这是一种隐式转换开销,它取决于使用的相对成本,以及字段是在过滤之前还是过滤之后被处理的。在VARCHAR(MAX)列中使用2019年的UTF-8排序规则时也存在同样的转换问题。
使用NVARCHAR(1-4000)也需要N*2个字节的~8000字节行配额,而NVARCHAR(MAX)只需要24个字节。总体设计和使用需要一起考虑,以考虑具体的实现细节。
+在我的数据库/数据/模式中,通过使用两列(读时合并),可以减少40%的磁盘空间使用,同时仍然支持溢出的文本值。SCSU虽然存在缺陷,但它是一种非常聪明且未得到充分利用的存储Unicode的更有效空间的方法。
这将导致性能问题,尽管如果数据库较小,可能永远不会导致任何实际问题。每条记录将占用硬盘驱动器上更多的空间,如果您一次搜索大量记录,数据库将需要读取更多的磁盘扇区。例如,一个小的记录可以适合50个扇区,而一个大的记录可以适合5个扇区。如果使用大记录,则需要从磁盘读取10倍的数据。
推荐文章
- 如何在Ruby On Rails中使用NuoDB手动执行SQL命令
- 查询JSON类型内的数组元素
- 确定记录是否存在的最快方法
- 获得PostgreSQL数据库中当前连接数的正确查询
- 在SQL选择语句Order By 1的目的是什么?
- 从现有模式生成表关系图(SQL Server)
- 我如何循环通过一组记录在SQL Server?
- 数据库和模式的区别
- 如何在SQL Server中一次更改多个列
- 如何从命令行通过mysql运行一个查询?
- 外键约束可能导致循环或多条级联路径?
- 使用LIMIT/OFFSET运行查询,还可以获得总行数
- 当恢复sql时,psql无效命令\N
- 货币应该使用哪种数据类型?
- 如何选择每一行的列值不是独特的