假设我有一个包含100列相同数据类型和100行的表A.
表B包含2列和5000行相同数据类型的上表列。
哪个表占用更多磁盘空间来存储&哪个更有效率?
答案 0 :(得分:5)
一个表有2列或100个。你不会将一个列转换为另一个或者你会做一些非常错误。
产品表可能有100列(项目编号,描述,供应商编号,材料,清单价格,实际价格......)。你怎么会把它变成两列表?键值表?一个非常糟糕的主意。
国家/地区表可能有2列(iso代码和名称)。你会怎么做这个100柱的桌子?通过列usa_name,usa_code,germany_name,germany_code,...?更糟糕的想法。
所以:这个问题是不可能的:-)之间没有什么可以决定的。
答案 1 :(得分:4)
这里真正的答案是......这取决于。
Oracle将其数据存储在“数据块”中,“数据块”存储在“范围”中,存储在构成“表空间”的“段”中。 See here.
数据块很像用于存储操作系统数据的块。实际上,Oracle数据块应该以操作系统块的倍数指定,这样就不会有不必要的I / O开销。
数据块分为5个块:
因此,对于这个问题,Oracle数据存储的两个重要部分是它的数据块是行数据和行目录(在某种程度上,还有自由空间)。
在第一个表格中,您的行数非常大,但行数较少。这将建议一个较小的行目录(除非它跨越多个块,因为行的大小,在这种情况下它将是行*块 - 必要 - 存储 - 它们)。在第二个表中,您有更多行,这将建议比第一个表更大的行目录。
我认为行目录条目是两个字节。它描述了从可以找到行数据的块开始的字节偏移量。如果第二个表中两列的数据类型为TINYINT()
,那么您的行也将是2个字节。实际上,您有更多行,因此您的目录与数据一样大。它是datasize * 2,这将导致您为此表存储更多数据。
另一个问题是,当删除行时,不会删除存储在块的行目录中的数据。包含块中行目录的标头仅在需要空间的新插入时重用。
此外,每个块都有它的可用空间,用于存储更多行和标题信息,以及保存事务条目(请参阅上面的链接)。
无论如何,给定块中的行目录不太可能比行数据大,即使这样,Oracle也可能会占用块中的空闲空间,这取决于表的大小和方式经常被访问以及oracle是否为您自动管理可用空间,或者您是否手动管理(有人这样做吗?)。
此外,如果您在其中任何一个表上抛出索引,无论如何都会改变统计数据。索引像表一样存储,它们有自己的段,范围和块。
最后,你最好的选择是不要过于担心块和诸如此类的东西(毕竟存储便宜):
P.S。如果我在这里歪曲了什么,请原谅我。逻辑数据库存储是复杂的东西,我不太喜欢Oracle,所以我可能会错过一个拼图,但整体要点是相同的。您存储的是实际数据,然后是该数据的元数据。元数据在大小上不太可能胜过数据本身,但在适当的情况下,它是可能的(特别是在编入索引的情况下)。而且,最后,不管怎么说都不用担心。在设计架构时关注最终用户/应用程序的需求。最终用户将比你的盒子更加贪得无厌。
答案 2 :(得分:1)
效率是一个模糊的概念,取决于你在测量什么。如果你不得不跳过提取索引很差(或需要基于函数的索引)的数据,因为磁盘空间被认为比正确的设计更重要,那么我会说从数据检索的角度来看效率低得多的应用程序,更不用说必须处理为实现和克服糟糕设计而实现的代码复杂性。
答案 3 :(得分:0)
考虑到每列必须存储一些元数据,我猜测表B可能更节省空间,因为实际数据的大小在两种情况下都是恒定且相等的。
答案 4 :(得分:0)
就内存而言,我认为这取决于表中存储的数据类型(图像,视频,int,varchar ......等)。 (假设您并不是说两个表都包含相同的数据,因为我没有看到您如何将列更改为行)
就效率而言,我希望我是对的,如果我说表B更有效,因为索引2列更容易索引5因此可以更容易地检索数据,与之相比一个包含5列的表,其中某种查询可能需要更长的时间。