我在一个表中需要 1100 列。我在同一个表中已经有 928 列,现在我需要添加新的 150 列。
我知道 SQL Server 最多允许 1024 列。
现在我不会创建新表。如果我创建新表并加入我的 require 表,我需要在很多地方进行更改,这对我来说是不可能的。所以我想在同一个表中添加所有列(需要表)。我知道这很难执行这个表,但目前我需要满足这个要求。
TT.*_*TT. 14
这个怎么样:
创建视图应该允许您选择最多 4,096 列。参考:SQL Server 的最大容量规范。
关于宽桌。使用宽表时,您需要一种非常特殊的数据类型。如果您的列比 1,024 列宽得多(即数据应该是稀疏的),那么大多数列应该是 NULL。宽表和非宽表的最大行大小相同。
也许在某些时候,您的数据足够稀疏以适应最大行大小……直到插入的行不是。使用我概述的视图回避了这一点,可用于非稀疏数据。
从本质上讲,您要问的问题是“如何创建具有 1024 列以上的表?” 对此的答案很简单,“在 SQL Server 中没有简单的方法可以超过该硬限制。您应该将数据拆分到多个表中。”。
您可以使用稀疏列和宽表。但是,这有其自身的一套限制和限制。例如,您不能对稀疏列使用压缩索引。虽然可以使用宽表,但我建议您考虑其他方法。
鉴于您必须将数据拆分为至少两个表,我认为您需要考虑三个方面:规范化、性能和向后兼容性。
单个表上有数百列表明您的数据模型没有很好地规范化。在你的问题中,你没有指定这个非常宽的表中的数据类型,但我预计最好将这些数据分解成更小的逻辑部分,然后将表分解成许多表。没有看到具体的表定义,我无法提出任何具体建议,但根据经验,这肯定是正确的举措。根据我的经验,拥有 1000 列的表是数据库设计非常糟糕的标志。
例如,一个Person
表可能不应该在同一个表中包含地址信息。相反,这应该分成单独Person
和Address
表。同样,Address
表中的每个地址应该只包含一行。该Person
表将加入到Address
一对多关系中。
拥有非常宽的表会增加 IO,从而加剧任何磁盘 IO 瓶颈。通过在一行中有更多数据,SQL Server 在每 8k 页上存储更少的行(在您的场景中,每页可能只有 1 行)。较低的行到页密度意味着即使是简单任务的 IO 也可能比规范化场景中的 IO 高很多倍。
此外,如果一行的宽度超过 8060 字节,SQL Server 将使用行溢出数据页。这意味着要读取单行,SQL Server 实际上必须对每一行执行多次读取。可以在此处阅读有关 SQL Server 如何存储溢出数据的其他详细信息。
为了向后兼容,您可以创建一个连接基础表的非常宽的视图。您可以利用INSTEAD OF
视图上的触发器,这允许在视图上执行 DML 并实际更新底层基表。这称为对表进行垂直分区。
短期而言,此方法允许您将数据放在多个物理表中,但仍可通过单个合并视图进行访问。您可以继续在拆分非常宽的表格方面取得进展,并且仍然可以通过视图向后兼容。
从长远来看,最好更新您的代码库以始终直接访问基础表,并慢慢减少/消除使用非常广泛的视图。
小智 5
我真的建议你退后一步(而不是考虑这个可能的解决方案),看看你试图解决的问题。如果您正在以这种方式探索关系数据库模型的局限性,那么可能会发生一些事情。
在这些情况下,这是我的推理方式:
检查 (1) 通常是可取的,如果有什么可以避免迷失在实际问题的迷宫中(因为正在使用的工具在压力下会崩溃)。有时,视角的改变可以避免很多悲伤。然后,如果模型真的不起作用,那么我会转到(2),然后是(3)。
在您的特定情况下,具有(例如)50 列的表在关系模型中开始变得笨拙,超出它可能根本没有意义。我们不能假设设计和构建关系数据库引擎的人会考虑它,除非可能用于重型实现。
一般的想法是表表达数据之间的关系:
所以我们真的很想知道问题是什么,因为(正如一位著名的 Python 老师经常做的那样)我们很想用拳头敲桌子,说“一定有更好的方法”!