Database 我们如何处理快速增长的交集表?
例如,我们有表A和表B,它们具有多对多关系。作为一个交集表,表C存储A.id和B.id以及表示两者之间关系的值。或者作为一个具体的例子,想象一下stackexchange,它有一个用户帐户、一个论坛和一个业力分数。或者,一个学生,一门课程,一个年级。如果表A和表B非常大,那么表C可以而且可能会非常快地变得非常大(事实上,让我们假设它确实如此)。我们如何着手处理这样一个问题?有没有更好的方法来设计表格来避免这种情况?没有魔法。如果一些行是连接的,而另一些行不是连接的,则必须以某种方式表示这些信息,“关系”方式是“连接”(也称为“链接”)表。是的,连接表可以变大,但幸运的是数据库能够处理大量数据 使用连接表和逗号分隔列表(或类似列表)有很好的理由,包括:Database 我们如何处理快速增长的交集表?,database,database-design,Database,Database Design,例如,我们有表A和表B,它们具有多对多关系。作为一个交集表,表C存储A.id和B.id以及表示两者之间关系的值。或者作为一个具体的例子,想象一下stackexchange,它有一个用户帐户、一个论坛和一个业力分数。或者,一个学生,一门课程,一个年级。如果表A和表B非常大,那么表C可以而且可能会非常快地变得非常大(事实上,让我们假设它确实如此)。我们如何着手处理这样一个问题?有没有更好的方法来设计表格来避免这种情况?没有魔法。如果一些行是连接的,而另一些行不是连接的,则必须以某种方式表示这些信息,
- 高效查询(通过索引和集群)
- 引用完整性的强制执行
- 如果一个方向,只需在两个外键上创建一个复合主键(让我们称它们为PARENT\u ID和CHILD\u ID)。顺序问题:如果您从父项查询到子项,PK应该是:{parent_ID,CHILD_ID}
- 如果两个方向都,也可以按相反的顺序创建一个复合索引,在本例中为{CHILD_ID,PARENT_ID}
- 如果是,则根据需要在二级索引中添加表格和额外数据。2
- I否,不要对表进行聚类,也不要在二级索引中包含额外的数据。3
:大多数DBMS称之为集群的Oracle特定语法。其他DBMS有自己的语法,有些(MySQL/InnoDB)意味着集群,用户无法关闭它组织索引
:一些DBMS支持。由于聚集表本质上是一个索引,因此也可以对其应用压缩COMPRESS
,JUNCTION\u TABLE\u IE1
:由于额外数据包含在二级索引中,DBMS在从子级到父级的方向上进行查询时,无需触摸表即可获得它。主键充当集群键,因此当从父级查询到子级时,会自然地覆盖额外的数据EXTRA\u DATA
1换句话说,您是否只需要获得给定“父母”的“子女”,或者您可能也需要获得给定子女的父母 2覆盖允许仅从索引满足查询,并避免了在通过聚集表中的辅助索引访问数据时需要的昂贵的双重查找
3这样,额外的数据就不会被重复(这会很昂贵,因为它很大),但是您可以避免双重查找,并用(更便宜的)表堆访问来替换它。但是,请注意,这可能会破坏基于堆的表中范围扫描的性能 你能发布一个模式和一些示例元组吗?谢谢你,这是一个很好的答案,我感谢为后续阅读提供的链接。
CREATE TABLE JUNCTION_TABLE (
PARENT_ID INT,
CHILD_ID INT,
EXTRA_DATA VARCHAR2(50),
PRIMARY KEY (PARENT_ID, CHILD_ID),
FOREIGN KEY (PARENT_ID) REFERENCES PARENT_TABLE (PARENT_ID),
FOREIGN KEY (CHILD_ID) REFERENCES CHILD_TABLE (CHILD_ID)
) ORGANIZATION INDEX COMPRESS;
CREATE UNIQUE INDEX JUNCTION_TABLE_IE1 ON
JUNCTION_TABLE (CHILD_ID, PARENT_ID, EXTRA_DATA) COMPRESS;
CREATE TABLE JUNCTION_TABLE (
PARENT_ID INT,
CHILD_ID INT,
EXTRA_DATA VARCHAR(50),
PRIMARY KEY (PARENT_ID, CHILD_ID),
FOREIGN KEY (PARENT_ID) REFERENCES PARENT_TABLE (PARENT_ID),
FOREIGN KEY (CHILD_ID) REFERENCES CHILD_TABLE (CHILD_ID)
);
CREATE UNIQUE INDEX JUNCTION_TABLE_IE1 ON
JUNCTION_TABLE (CHILD_ID, PARENT_ID) INCLUDE (EXTRA_DATA);