假设我有一个表A,其中有100列相同的数据类型和100行。表B有2列和5000行,数据类型与上述表列相同。哪一个表需要更多的磁盘空间来存储&哪一个更有效?
pb3skfrl1#
这里真实的答案是...这要看情况。Oracle将其数据存储在“数据块”中,这些数据块存储在“扩展区”中,这些扩展区存储在组成“表空间”的“段”中。See here.数据块与用于存储操作系统数据的块非常相似。实际上,Oracle数据块应该以操作系统块的倍数指定,这样就不会有不必要的I/O开销。一个数据块被分成5个块:1.Header-包含有关块的信息1.表目录-告诉oracle该块包含有关它存储数据的表的信息1.行目录-存储块中有关行的信息(如地址)的块部分。1.行数据-存储行数据的块的主要部分。请记住,内存可以跨块。1.自由空间-这是宾果游戏板的中间,你不必把你的芯片放在这里。因此,Oracle数据存储的两个重要部分,对于这个问题,在它的数据块中是行数据和行目录(在某种程度上,自由空间)。在第一个表中,你有非常大的行,但它们的数量较少。这意味着一个较小的行目录(除非它因为行的大小而跨越多个块,在这种情况下,它将是“N Blocks-Necessary-To-Store-Them”)。在第二个表中,你有更多的行,这意味着一个比第一个表更大的行目录。我相信一个行目录条目是两个字节。它描述了从可以找到行数据的块开始的字节偏移量。如果你在第二个表中的两个列的数据类型是TINYINT(),那么你的行也是2个字节。实际上,你有更多的行,所以你的目录和你的数据一样大。它是datasize2,这将导致您为此表存储更多数据。这里的另一个问题是,当删除行时,存储在块的行目录中的数据不会被删除。包含块中行目录的头部只有在新的插入沿着需要空间时才被重用。此外,每个块都有空闲空间,用于存储更多的行和标题信息,以及保存事务条目(请参见上面的链接)。无论如何,给定块中的行目录不太可能大于行数据,即使这样,Oracle也可能会保留块中的空闲空间,这取决于表的大小和访问频率,以及Oracle是否自动为您管理空闲空间,或者手动管理(有人这样做吗?)。另外,如果你在这些表中的任何一个上设置索引,你会改变所有的统计信息。索引像表一样存储,它们有自己的段、区和块。最后,你最好的选择是不要太担心块和诸如此类的东西(毕竟,存储是便宜的):1.为你的数据定义合适的字段类型。例如,不要在CHAR(100)中存储布尔值。1.明智地定义你的索引。不要仅仅为了确定而添加索引。当你调优的时候要做出正确的决定。1.根据最终用户的需求设计方案。这是一个报告数据库吗?在这种情况下,尝试非规范化的预聚合数据以保持快速读取。尽量减少用户在其结果集上所需的连接数。1.根据您创建的模式的查询来减少CPU和I/O需求。存储很便宜,CPU和I/O不便宜,您的最终用户不会给予关于您需要将多少硬盘驱动器(或内存中的RAM)塞进您的盒子。他们会关心应用程序的读写速度。附言:如果我在这里歪曲了什么,请原谅我。逻辑数据库存储是一个复杂的东西,我和Oracle打交道不多,所以我可能漏掉了一块拼图,但总体要点是一样的。有你存储的实际数据,然后是该数据的元数据。元数据不太可能在大小上胜过数据本身,但在适当的情况下,这是可能的(特别是考虑到索引)。最后,无论如何不要太担心它。在设计模式时,关注最终用户/应用程序的需求。最终用户将比你的盒子更犹豫。
TINYINT()
vwkv1x7d2#
一个表要么有2列,要么有100列。你不会把一列转换成另一列,或者你会做一些非常错误的事情。一个产品表可能有100列(产品编号,描述,供应商编号,材料,标价,实际价格...)。你怎么把它变成一个两列的表?一个键值表?一个非常糟糕的主意。一个国家表可能有2列(iso代码和名称)。你怎么能让这个表有100列呢?通过列usa_name,usa_code,德国_name,德国_code,.?一个更糟糕的主意。所以:这个问题是毫无疑问的:-)没有什么可以决定的。
gmol16393#
效率是一个模糊的概念,它取决于您所测量的内容。(或需要基于函数的索引),因为磁盘空间被认为比适当的设计更重要,那么我想说,从数据检索的Angular 来看,更不用说必须处理代码复杂性,以尝试克服糟糕的设计。
ijxebb2r4#
考虑到每列都必须存储一些Meta数据,我猜表B可能更节省空间,因为实际数据的大小是恒定的,并且在两种情况下都是相等的。
qcbq4gxm5#
就内存而言,我认为这取决于存储在表中的数据类型(图像,视频,int,varchar等)。(假设你并不意味着两个表包含相同的数据,因为我看不出你如何将列改为行)在效率方面,我希望我是正确的,如果我说表B更有效,因为索引2列比索引5列更容易,因此与具有5列的表相比,数据可以以任何可能的方式更容易检索,其中某种查询可能需要更长的时间。
5条答案
按热度按时间pb3skfrl1#
这里真实的答案是...这要看情况。
Oracle将其数据存储在“数据块”中,这些数据块存储在“扩展区”中,这些扩展区存储在组成“表空间”的“段”中。See here.
数据块与用于存储操作系统数据的块非常相似。实际上,Oracle数据块应该以操作系统块的倍数指定,这样就不会有不必要的I/O开销。
一个数据块被分成5个块:
1.Header-包含有关块的信息
1.表目录-告诉oracle该块包含有关它存储数据的表的信息
1.行目录-存储块中有关行的信息(如地址)的块部分。
1.行数据-存储行数据的块的主要部分。请记住,内存可以跨块。
1.自由空间-这是宾果游戏板的中间,你不必把你的芯片放在这里。
因此,Oracle数据存储的两个重要部分,对于这个问题,在它的数据块中是行数据和行目录(在某种程度上,自由空间)。
在第一个表中,你有非常大的行,但它们的数量较少。这意味着一个较小的行目录(除非它因为行的大小而跨越多个块,在这种情况下,它将是“N Blocks-Necessary-To-Store-Them”)。在第二个表中,你有更多的行,这意味着一个比第一个表更大的行目录。
我相信一个行目录条目是两个字节。它描述了从可以找到行数据的块开始的字节偏移量。如果你在第二个表中的两个列的数据类型是
TINYINT()
,那么你的行也是2个字节。实际上,你有更多的行,所以你的目录和你的数据一样大。它是datasize2,这将导致您为此表存储更多数据。这里的另一个问题是,当删除行时,存储在块的行目录中的数据不会被删除。包含块中行目录的头部只有在新的插入沿着需要空间时才被重用。
此外,每个块都有空闲空间,用于存储更多的行和标题信息,以及保存事务条目(请参见上面的链接)。
无论如何,给定块中的行目录不太可能大于行数据,即使这样,Oracle也可能会保留块中的空闲空间,这取决于表的大小和访问频率,以及Oracle是否自动为您管理空闲空间,或者手动管理(有人这样做吗?)。
另外,如果你在这些表中的任何一个上设置索引,你会改变所有的统计信息。索引像表一样存储,它们有自己的段、区和块。
最后,你最好的选择是不要太担心块和诸如此类的东西(毕竟,存储是便宜的):
1.为你的数据定义合适的字段类型。例如,不要在CHAR(100)中存储布尔值。
1.明智地定义你的索引。不要仅仅为了确定而添加索引。当你调优的时候要做出正确的决定。
1.根据最终用户的需求设计方案。这是一个报告数据库吗?在这种情况下,尝试非规范化的预聚合数据以保持快速读取。尽量减少用户在其结果集上所需的连接数。
1.根据您创建的模式的查询来减少CPU和I/O需求。存储很便宜,CPU和I/O不便宜,您的最终用户不会给予关于您需要将多少硬盘驱动器(或内存中的RAM)塞进您的盒子。他们会关心应用程序的读写速度。
附言:如果我在这里歪曲了什么,请原谅我。逻辑数据库存储是一个复杂的东西,我和Oracle打交道不多,所以我可能漏掉了一块拼图,但总体要点是一样的。有你存储的实际数据,然后是该数据的元数据。元数据不太可能在大小上胜过数据本身,但在适当的情况下,这是可能的(特别是考虑到索引)。最后,无论如何不要太担心它。在设计模式时,关注最终用户/应用程序的需求。最终用户将比你的盒子更犹豫。
vwkv1x7d2#
一个表要么有2列,要么有100列。你不会把一列转换成另一列,或者你会做一些非常错误的事情。
一个产品表可能有100列(产品编号,描述,供应商编号,材料,标价,实际价格...)。你怎么把它变成一个两列的表?一个键值表?一个非常糟糕的主意。
一个国家表可能有2列(iso代码和名称)。你怎么能让这个表有100列呢?通过列usa_name,usa_code,德国_name,德国_code,.?一个更糟糕的主意。
所以:这个问题是毫无疑问的:-)没有什么可以决定的。
gmol16393#
效率是一个模糊的概念,它取决于您所测量的内容。(或需要基于函数的索引),因为磁盘空间被认为比适当的设计更重要,那么我想说,从数据检索的Angular 来看,更不用说必须处理代码复杂性,以尝试克服糟糕的设计。
ijxebb2r4#
考虑到每列都必须存储一些Meta数据,我猜表B可能更节省空间,因为实际数据的大小是恒定的,并且在两种情况下都是相等的。
qcbq4gxm5#
就内存而言,我认为这取决于存储在表中的数据类型(图像,视频,int,varchar等)。(假设你并不意味着两个表包含相同的数据,因为我看不出你如何将列改为行)
在效率方面,我希望我是正确的,如果我说表B更有效,因为索引2列比索引5列更容易,因此与具有5列的表相比,数据可以以任何可能的方式更容易检索,其中某种查询可能需要更长的时间。