【发布时间】:2010-10-06 07:53:59
【问题描述】:
快速提问,我很好奇一次性定义的数据库表与随着时间的推移添加了列的数据库表之间是否有任何区别。增加列的性能是否会受到某种程度的影响?
无论如何,数据库供应商在这里并不太相关,除非在这种情况下存在供应商差异。
谢谢
【问题讨论】:
标签: database-design alter-table
快速提问,我很好奇一次性定义的数据库表与随着时间的推移添加了列的数据库表之间是否有任何区别。增加列的性能是否会受到某种程度的影响?
无论如何,数据库供应商在这里并不太相关,除非在这种情况下存在供应商差异。
谢谢
【问题讨论】:
标签: database-design alter-table
在 Oracle 中,您可以向现有的填充表添加空列,除了表结构的逻辑重新定义之外,基本上不会发生任何事情。但是,当您填充这些列时,这当然可能在添加列时发生,然后行必须扩展,并且您可能会遇到一些问题,即某些行在包含它们的块中没有足够的可用空间,在这种情况下它们将被迁移到不同的块,指针留在原始位置(因此索引不受影响,因为它们继续指向原始位置)。
因此,如果您将填充的列添加到其中包含行的表中,那么您可能需要重命名原始表并执行“create table as select”来创建和填充新版本。索引、触发器、特权等当然也必须迁移。但是,如果表不是太大,您可以添加填充的列,由于行迁移而降低性能,然后执行表移动以重新组织它。
【讨论】:
这里有 供应商差异。 SQL 语言由标准定义,但存储细节留给每个供应商来实现。
例如,在 MySQL 中,当您添加一列时,数据库引擎会复制整个表,为每一行的新列腾出空间。一旦它复制了所有行,它就会删除表的旧副本。因此,新表的存储方式与您从一开始就使用新列定义它一样。但是您必须在 ALTER TABLE 返回之前等待复制完成(如果表很大,这可能需要很长时间)。
在另一个品牌的数据库中(虽然我没有想到),添加一列可能会将额外的列与原始表分开存储。这将有助于快速添加新列,但检索数据会受到数据断开部分的影响。大概您以后可以告诉数据库引擎对表进行“碎片整理”并将所有列放在一起。
【讨论】:
这将完全取决于存储引擎。一般来说,我对添加列感到非常满意,也许是在向它们扔一个 OPTIMIZE TABLE 之后。
【讨论】: