gpt4 book ai didi

sql - 解决 SQL Server 最大列限制 1024 和 8kb 记录大小

转载 作者:行者123 更新时间:2023-12-02 00:43:25 25 4
gpt4 key购买 nike

我正在创建一个包含 1000 列的表。大部分栏目是nvarchar类型。表已创建,但有警告

Warning: The table "Test" has been created, but its maximum row size exceeds the allowed maximum of 8060 bytes. INSERT or UPDATE to this table will fail if the resulting row exceeds the size limit.



表的大部分列已经有数据(即 99% 的列有数据)。
当我尝试在第 310 列之后更新任何列时(因为所有开始的 309 列都有一些值),它会给出错误:

Cannot create a row of size 8061 which is greater than the allowable maximum row size of 8060.



我将此数据插入所有起始 308 列

“Lorem ipsum dolor 坐 amet,consectetur adipisicing 精英。”

当我使用 ntext数据类型然后它允许我更新大约 450 列,但超出了 ntext也不允许我。我必须更新至少 700 列。哪个 SQL Server 不允许这样做。我的情况是我无法将表的某些列移动到另一个表。

实际上,我正在为现有的窗口应用程序工作。这是一个非常大的窗口应用程序。

实际上,我尝试在其中插入多达 700 个 nvarchar 列数据的表是在运行时动态创建的。
只有在某些情况下才需要插入 400-600 列。但通常它需要 100 -200 列,我可以轻松处理。

问题是我无法将此表拆分为多个表。因为使用这种结构创建的许多表和表的名称都保存在另一个表中,即有 100 多个具有这种结构的表并且它们是动态创建的。为了创建表和操作它的数据,使用了 4-5 种语言(C#、Java ..),WCF、Windows 服务和 Web 服务也涉及。

所以我不认为在拆分表格后操作表格及其数据会很容易。如果我拆分表格,则需要进行大量结构更改。

所以请建议我解决这个问题的最佳方法是什么。

我也试过用 稀疏列喜欢:
Create table ABCD(Id int, Name varchar(100) Sparse, Age int);

我也想过 列存储索引 但我的目的没有解决。

稀疏列允许我为一个表创建 3000 列,但它也限制了我的页面大小。

有没有办法使用一些临时表或使用任何其他类型的 SQL 服务器对象来实现它?

最佳答案

SQL Server 最大列数限制

每个短字符串列的字节数 8,000

每个 GROUP BY、ORDER BY 的字节数 8,060

每行字节数 8,060

每个索引键的列数 16

每个外键的列数 16

每个主键的列数 16

每个非宽表的列数 1,024

每个宽表的列数 30,000

每个 SELECT 语句的列数 4,096

每个 INSERT 语句的列数 4096

每个 UPDATE 语句的列数(宽表) 4096

结合时 varchar、nvarchar、varbinary、sql_variant、或超过 的 CLR 用户定义类型列8,060 每行字节数,请考虑以下事项:

超过 8,060 字节的行大小限制可能会影响性能,因为 SQL Server 仍然保持每页 8 KB 的限制。当 varchar、nvarchar、varbinary、sql_variant 或 CLR 用户定义类型列的组合超过此限制时,SQL Server 数据库引擎会将宽度最大的记录列移动到 ROW_OVERFLOW_DATA 分配单元中的另一页,同时保持 24-原始页面上的字节指针。当记录根据更新操作被加长时,将大记录移动到另一个页面是动态的。缩短记录的更新操作可能会导致记录被移回 IN_ROW_DATA 分配单元中的原始页面。此外,查询和执行其他选择操作(例如对包含行溢出数据的大型记录进行排序或连接)会减慢处理时间,因为这些记录是同步处理的,而不是异步处理的。

因此,在设计具有多个 varchar、nvarchar、varbinary、sql_variant 或 CLR 用户定义类型列的表时,请考虑可能溢出的行的百分比以及可能查询此溢出数据的频率。如果可能对多行行溢出数据进行频繁查询,请考虑对表进行规范化,以便将某些列移动到另一个表中。然后可以在异步 JOIN 操作中查询。

  • 单个列的长度仍必须在
    8,000 字节用于 varchar、nvarchar、varbinary、sql_variant 和 CLR
    用户定义的类型列。只有它们的总长度可以超过
    表的 8,060 字节行限制。
  • 其他数据类型列的总和,包括 char 和 nchar 数据,
    必须在 8,060 字节的行限制内。大对象数据也是
    免于 8,060 字节的行限制。
  • 聚集索引的索引键不能包含 varchar 列
    在 ROW_OVERFLOW_DATA 分配单元中有现有数据。如果
    在 varchar 列和现有的列上创建聚集索引
    数据在 IN_ROW_DATA 分配单元中,后续插入或
    将数据推离行的列上的更新操作将
    失败。有关分配单位的详细信息,请参阅表和
    索引组织。
  • 您可以包括包含行溢出数据的列作为键或
    非聚集索引的非键列。
  • 使用稀疏列的表的记录大小限制为 8,018
    字节。当转换数据加上现有记录数据超过
    8,018 字节,返回 MSSQLSERVER 错误 576。当列是
    在稀疏和非稀疏类型之间转换,数据库引擎保持一个
    当前记录数据的副本。这暂时使存储加倍
    这是记录所必需的。 .
  • 获取有关可能包含的表或索引的信息
    行溢出数据,使用 sys.dm_db_index_physical_stats 动态
    管理功能。

  • 创建具有 n 个列和数据类型 Nvarchar 的表
    CREATE Proc [dbo].[CreateMaxColTable_Nvarchar500]
    (@TableName nvarchar(100),@NumofCols int)
    AS
    BEGIN

    DECLARE @i INT
    DECLARE @MAX INT
    DECLARE @SQL VARCHAR(MAX)
    DECLARE @j VARCHAR(10)
    DECLARE @len int
    SELECT @i=1
    SELECT @MAX=@NumofCols
    SET @SQL='CREATE TABLE ' + @TableName + '('

    WHILE @i<=@MAX

    BEGIN
    select @j= cast(@i as varchar)
    SELECT @SQL= @SQL+'X'+@j +' NVARCHAR(500) , '
    SET @i = @i + 1
    END
    select @len=len(@SQL)

    select @SQL = substring(@SQL,0,@len-1)


    SELECT @SQL= @SQL+ ' )'

    exec (@SQL)

    END

    有关更多信息,您可以访问以下链接:

    http://msdn.microsoft.com/en-us/library/ms186981%28SQL.105%29.aspx?PHPSESSID=tn8k5p1s508cop8gr43e1f34d2

    http://technet.microsoft.com/en-us/library/ms143432.aspx

    但是请您说说为什么需要一个包含这么多列的表?
    我认为您应该考虑重新设计数据库。

    关于sql - 解决 SQL Server 最大列限制 1024 和 8kb 记录大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14070932/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com