哪个更节省空间?

uhs*_*uhs 0 sql oracle database-design

假设我有一个包含100列相同数据类型和100行的表A.

表B具有2列和5000行相同数据类型的上表列.

哪个表需要更多磁盘空间来存储哪个更高效?

Tho*_*ner 6

一个表有2列或100.你不会将一个转换为另一个或你会做一些非常错误的事情.

产品表可能有100列(项目编号,描述,供应商编号,材料,清单价格,实际价格......).你怎么会把它变成两列表?键值表?一个非常糟糕的主意.

国家/地区表可能有2列(iso代码和名称).你会怎么做这个100柱的桌子?通过列usa_name,usa_code,germany_name,germany_code,...?更糟糕的想法.

所以:问题是不可能的:-)之间没有什么可以决定的.

  • 我说这个问题没有多大意义。您还可能会问,存储图像或声音剪辑是否占用更多磁盘空间?他们是不同的东西。有2列或100列的表也是如此;它们旨在存储不同的数据;那为什么要问呢?答案可能对您没有任何帮助。您不会说“啊,国家/地区表比产品表小?然后,国家/地区比产品要好。”,对吗? (2认同)

JNe*_*ill 6

真正的答案是……这取决于情况。

Oracle 将其数据存储在“数据块”中,“数据块”存储在“范围”中,“范围”存储在构成“表空间”的“段”中。看这里。

数据块很像操作系统用来存储数据的块。事实上,Oracle 数据块应该以操作系统块的倍数来指定,这样就不会产生不必要的 I/O 开销。

一个数据块被分成5个块:

  1. 标头- 其中包含有关块的信息
  2. 表目录- 告诉 oracle 该块包含有关其存储数据的任何表的信息
  3. 行目录- 块的一部分,用于存储有关块中行的信息(如地址)。
  4. 行数据——存储行数据的块的主要内容。请记住,行可以跨越块。
  5. 可用空间- 这是宾果游戏板的中间,您不必将筹码实际放置在这里。

因此,对于这个问题,Oracle 数据存储的两个重要部分是行数据和行目录(在某种程度上,是可用空间)。

在您的第一个表中,您有很大的行,但行数较少。这建议使用较小的行目录(除非由于行的大小而跨越多个块,在这种情况下它将是 Rows*Blocks-Necessary-To-Store-Them)。在第二个表中,您有更多的行,这表明行目录比第一个表更大。

我相信行目录条目是两个字节。它描述了距可以找到行数据的块的开头的偏移量(以字节为单位)。如果第二个表中两列的数据类型是,TINYINT()那么您的行也将是 2 个字节。实际上,您有更多的行,因此您的目录与您的数据一样大。它是datasize*2,这将导致您为此表存储更多数据。

这里的另一个问题是,当删除行时,存储在块的行目录中的数据不会被删除。仅当出现需要空间的新插入时,才会重用块中包含行目录的标头。

此外,每个块都有其可用空间,用于存储更多行和标头信息,以及保存事务条目(请参阅上面的链接)。

无论如何,给定块中的行目录不太可能大于行数据,即使这样,Oracle 也可能会保留块中的可用空间,这取决于表的大小和访问频率。以及 Oracle 是否自动为您管理可用空间,或者您手动管理(有人这样做吗?)。

另外,如果您在这些表中的任何一个上添加索引,无论如何您都会更改所有统计信息。索引像表一样存储,它们有自己的段、范围和块。

最后,最好的选择是不要太担心块之类的东西(毕竟存储很便宜):

  1. 为您的数据定义适当的字段类型。例如,不要将布尔值存储在 CHAR(100) 中。
  2. 明智地定义你的索引。不要只是为了确定而添加索引。调整时做出正确的决定。
  3. 根据最终用户的需求设计架构。这是报告数据库吗?在这种情况下,请寻找非规范化的预聚合数据以保持快速读取。尝试减少用户获取结果集所需的联接数量。
  4. 根据您创建的模式将要执行的查询,重点关注削减 CPU 和 I/O 要求。存储很便宜,CPU 和 I/O 则不然,并且您的最终用户不会关心您需要在您的盒子中塞入多少个硬盘驱动器(或 RAM,如果它位于内存中)。他们将关心应用程序读取和写入的速度。

ps 如果我在这里歪曲了任何内容,请原谅我。逻辑数据库存储是复杂的东西,而且我与 Oracle 打交道不多,所以我可能遗漏了一部分,但总体要点是相同的。这是您存储的实际数据,然后是该数据的元数据。元数据在大小上不太可能胜过数据本身,但在适当的情况下,这是可能的(特别是考虑到索引)。而且,最后,无论如何也不要太担心。在设计架构时关注最终用户/应用程序的需求。最终用户会比你的盒子更犹豫。