数据库中空值使用的空间

发布于 2024-07-13 22:39:21 字数 334 浏览 7 评论 0原文

如果列为空,是否会影响该列使用的空间? 使用的空间是否由列定义固定? 这是否因数据库而异。 (我主要对 SQL Server 2000 感兴趣。)

澄清: 这个问题与列“可为空”时发生的情况无关(正如 Kritsen 和 gbn 指出的那样,这会增加一点成本)。 问题是,当列实际上为空(在某些特定行中)时是否有任何保存。

...

Cadaeic 提供了 SQL Server 的答案,在 2008 版本之前,SQL Server 中似乎没有节省,而根据 Quassnoi 的说法,如果空列位于末尾,则可以在 Oracle 中节省成本。 感谢您的回答,他们都很有帮助。

If a column is null, does that affect the space used by the column?
Is the space used fixed by the column definition?
Does this vary from database to database.
(I am mainly interestred in SQL Server 2000.)

Clarification:
The question relates not to what happens when the column is 'nullable' (This costs another bit as Kritsen & gbn pointed out). The question is, is there any saving when the column is actually null (in some particular row).

...

Cadaeic provided the answer for SQL Server which seems to be no savings in SQL Server until version 2008, whereas according to Quassnoi you can get savings in Oracle if the null columns are at the end. Thanks for the answers, they were all helpful.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

山有枢 2024-07-20 22:39:21

在列中存储 NULL 不会特别消耗或节省空间。 对于固定长度的数据,整个空间仍然保留。

另一方面,可变长度数据只需要数据长度加上存储实际长度的开销。 例如,VARCHAR(n)将使用2个字节的数据来指示实际长度,因此所需的存储空间始终为n+2。

此外,应该提到的是,如果 SET ANSI_PADDING ON,则具有 NULL 值的 char(n) 将表现为 VARCHAR(n)。

无论如何,在使用 SQL Server 2000 或 SQL Server 2005 时,您不会认识到存储 NULL 所带来的空间“节省”。SQL Server 2008 引入了稀疏列的概念,它可以为主要为 NULL 的列节省空间。

Storing a NULL in a column does not specifically cost or save space. For fixed-length data, the entire space is still reserved.

On the other hand, variable-length data requires only the length of the data plus overhead to store the actual length. For example, a VARCHAR(n) will use 2 bytes of data to indicate that actual length, so the storage space required is always n+2.

Additionally, it should be mentioned that if SET ANSI_PADDING ON, a char(n) with a NULL value will behave as a VARCHAR(n).

No matter what, you will not recognize space "savings" from storing NULLs when using SQL Server 2000 or SQL Server 2005. SQL Server 2008 introduces the concept of a sparse column, which can yield savings for columns that are primarily NULL.

别闹i 2024-07-20 22:39:21

SQL Server 有一个位来指示 NULL。 如果列定义为 NOT NULL,则不会使用此类位。

VARCHAR 使用可变长度来存储数据(因此具有指示实际数据长度的开销),而 CHAR 是固定宽度。

因此,在此基础上,CHAR(1) NOT NULL 比 VARCHAR(1) NOT NULL “短”,因为 VARCHAR 需要长度指示符,而 CHAR 将始终仅使用一个字节。

编辑:请注意,有一个允许 NULL 的 BIT 字段需要两个位来存储它! 我经常看到 BIT 字段没有考虑到这一点,不需要存储 NULL 但没有设置为 NOT NULL,所以无意中有点浪费

SQL Server has a Bit to indicate NULL. There is no such bit used if the column is defined as NOT NULL

VARCHAR uses variable length to store data (and thus has overhead of indicating how long the actual data is), whereas CHAR is fixed width.

So on that basis a CHAR(1) NOT NULL is "shorter" than a VARCHAR(1) NOT NULL as VARCHAR needs a length indicator, and CHAR will always use just one byte.

EDIT: Note that having a BIT field that allows NULL requires two bits to store it! I often see BIT fields where this has not been considered, don't need to store NULL but have not been set to NOT NULL so are wasting a bit unintentionally

幸福%小乖 2024-07-20 22:39:21

在 Oracle 中,它取决于列的类型及其在行中的位置。

如果 NULL 列位于行的最后,那么它们根本不占用任何空间。 Oracle 将总行大小添加到每行前面,所有不适合的内容都被视为NULL

如果NULL列后面有一些非NULL数据,则NULL将存储为0xFF的单个字节code> (即 NULL 类型)。

VARCHAR2 相当于 NULL。 如果您测试从 SELECT 列表返回的文字 NULL 的类型,它将给您一个 VARCHAR2(0)

In Oracle, it depends on type of the column and its position in the row.

If the NULL columns are last in the row, then they don't take any space at all. Oracle prepends the total row size to each row, everything that doesn't fit is considered NULL.

If there is some non-NULL data after a NULL column, then the NULL is stored as a single byte of 0xFF (that is, NULL type).

Empty VARCHAR2 is equivalent to NULL. If you test the type of a literal NULL returned from SELECT list, it will give you a VARCHAR2(0).

放赐 2024-07-20 22:39:21

它存储在位图中,而不是作为列值。

示例:名为中间名行 1 的可空 varchar 列

  • ,“bob”存储为偏移量,bob 为 3 个字节,“bob”
  • 行 2 的长度为 2 个字节,NULL 行不存储为像“bob”这样的值,但在行标题中

除非您有一个非常小的表,例如单列 char(1),否则它会更有效

链接 1
链接 2

It's stored in a bitmap, not as a column value.

Example: a nullable varchar column called middle name

  • row 1, "bob" is stored as an offset, 3 bytes for bob, 2 bytes for length of "bob"
  • row 2, NULL row is not stored as a value like "bob", but in the row header

Unless you have a very small table, say a single column char(1), then it's more efficient

Link 1
Link 2

皓月长歌 2024-07-20 22:39:21

如果使用 varchar 或 nvarchar 数据类型,则行使用的字节数会较小。 这就是为什么您可以创建一个表(但不应该),该表的潜在字节数多于记录中实际存储的字节数。

The number of bytes used by the row is smaller if you are using varchar or nvarchar datatypes. This is why you can create a table (but shouldn't) that has more potential bytes than can actually be stored in a record.

桃气十足 2024-07-20 22:39:21

在Oracle 11G中,我也遇到了同样的情况。 您不能通过将列设置为 NULL 来释放(检查 dba_segments)现有行占用的空间,无论其位置如何,在中间还是在末尾。

UPDATE AUCORE_QA.SYSTEM_AUDIT_LOGS SET KEY=NULL;
SELECT OWNER, TABLESPACE_NAME , SEGMENT_NAME,SEGMENT_TYPE,BYTES/1024/1024 MB
FROM DBA_SEGMENTS 
WHERE OWNER LIKE 'AUCORE_QA' AND SEGMENT_TYPE='TABLE' AND SEGMENT_NAME like '%AUDIT_LOG%'
ORDER BY BYTES DESC;

但是,我将列设置为“可为空”,并且能够看到后续插入行的节省。

ALTER TABLE SYSTEM_AUDIT_LOGS MODIFY KEY NULL;

In Oracle 11G, I also had a same situation. You can not free up (check dba_segments) space which occupied by existing rows by setting a column NULL regardless of its position, in the middle or in the end.

UPDATE AUCORE_QA.SYSTEM_AUDIT_LOGS SET KEY=NULL;
SELECT OWNER, TABLESPACE_NAME , SEGMENT_NAME,SEGMENT_TYPE,BYTES/1024/1024 MB
FROM DBA_SEGMENTS 
WHERE OWNER LIKE 'AUCORE_QA' AND SEGMENT_TYPE='TABLE' AND SEGMENT_NAME like '%AUDIT_LOG%'
ORDER BY BYTES DESC;

However, I made the column 'Nullable' and was able to see the save savings for subsequent inserted rows.

ALTER TABLE SYSTEM_AUDIT_LOGS MODIFY KEY NULL;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文