【问题标题】:Why is a primary key index an additional structure?为什么主键索引是一个附加结构?
【发布时间】:2012-09-09 11:47:27
【问题描述】:

我读到 RDMS 以某种形式的 B-tree 将表数据存储在磁盘上,并且表索引也以 B-tree 形式存储。

我读到主键索引是为定义的主键自动创建的,但它也可以随时删除。因此,这意味着 primary-key 索引是 B 树旁边的一个附加结构,仅用于存储表数据。

这不是浪费资源吗?为什么不通过主键索引来保存所有的表?

如果不是这样,那么用于存储表数据的B-tree使用哪个顺序?

感谢澄清

【问题讨论】:

    标签: database data-structures indexing primary-key b-tree


    【解决方案1】:

    主键索引是一种优化,用于查找磁盘上保存该行的位置。作为一个结构,它只包含 PK 数据,而不是整行。

    在数据库上,性能通常取决于从磁盘读取的页面数量与缓存的数量。由于 PK 索引小于整个表,它更有可能在缓存中,它导致从磁盘读取的块更少,从缓存中删除的其他表的块也更少。因此,这是一项重大的性能优化。

    此外,在修改表数据时,行被锁定。如果从磁盘上的表数据中扫描主键,锁定的行会减慢所有其他查询的访问速度。通过将索引分离为一个单独的结构,即使指向的行被锁定,也可以使用索引。

    所以总的来说,单独的 PK 结构是一种经典的时空优化。

    EDIT 表格中各行的顺序是什么?以下答案适用于 Oracle,但适用于许多数据库。

    简短回答:行在磁盘上没有排序,这就是 PK 索引(和其他索引)如此重要的原因。

    长答案:

    虽然主键 b 树结构必须排序(b 树),但表的行分散在表空间中。为了理解这一点,我们需要深入了解各种数据结构。

    首先,数据库被结构化为称为表空间的逻辑实体。表空间是一个或多个磁盘上的一个或多个文件中的空间。文件开始为空。当表空间变满时(从技术上讲,当其中的数据达到阈值时)表空间可以自动增长。它也可以通过放大文件(添加“范围”或添加新文件)手动增长。表空间可以集群在多台机器和磁盘上。

    第二:一个表空间被划分为段,每个段供单个表或索引使用。

    第三:段被分成块,每个块有一个或多个行的空间。这些块与磁盘或操作系统块相同; Oracle 块是一个或多个 OS 块。 (这是为了可传输性,以及管理具有不同块大小的媒体)。

    在插入时,数据库将从表空间中的任何位置选择块中的空间。该行可以按顺序插入(尤其是批量插入到空表中),但通常数据库也会重用由于某些类型的更新而删除或移动行的空间。虽然该位置在理论上是可预测的,但实际上您不应依赖或期望将行放置在任何特定块中。

    Oracle 中一个有趣的事情是 ROWID。这是存储在索引中的引用,允许数据库查找行:

    • 扩展的 rowid 具有四部分格式 OOOOOOFFFBBBBBBRRR:
    • 前 6 个字符 OOOOOO 表示数据对象编号,使用 32 位
    • 接下来的 3 个字符 FFF 表示与表空间相关的数据文件编号,使用 10 位。
    • 接下来的 6 个字符 BBBBB 表示块号,使用 22 位。
    • 最后3个字符RRR代表行号,使用16bit

    更多详情,请参阅http://docs.oracle.com/cd/E11882_01/server.112/e25789/logical.htm#autoId0

    另一个想法:在 DB 世界中有一个名为 partitions 的概念,其中根据某些表达式逻辑将数据集划分为不同的表空间(通常是集群中不同的磁盘或节点)。例如,在客户表上,垂直分区可以由个人所在的国家/地区定义。这样您就可以确保美国客户在物理上位于一个磁盘上,而澳大利亚客户在另一个磁盘上。

    【讨论】:

    • 谢谢你,一个明确的答案。那么,磁盘上的 table-data B-tree 是由哪些列排序的?
    • 编辑了我的答案以解决您的问题
    猜你喜欢
    • 2012-12-21
    • 1970-01-01
    • 2019-09-30
    • 2021-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-21
    相关资源
    最近更新 更多