Ms access &引用;“表上的索引太多”;在Microsoft Access 2010中创建关系时出错

Ms access &引用;“表上的索引太多”;在Microsoft Access 2010中创建关系时出错,ms-access,relationship,indexing,Ms Access,Relationship,Indexing,我有一个主键为UserID的tblUsers UserID在许多表中用作外键。在一个表中,它被用作多个字段(例如ObserverID、RecorderID、CheckerID)的外键 我已成功添加了关系(在MS Access的“关系”视图中),其中我有表别名来处理每个表的多个关系: *tblUser.UserID->1对多->tblResight.ObserverID *tblUser_1.UserID->1对多->tblResight.CheckerID 在使用引用完整性的强制创建了大约25个

我有一个主键为UserID的tblUsers

UserID在许多表中用作外键。在一个表中,它被用作多个字段(例如ObserverID、RecorderID、CheckerID)的外键

我已成功添加了关系(在MS Access的“关系”视图中),其中我有表别名来处理每个表的多个关系:

*tblUser.UserID->1对多->tblResight.ObserverID

*tblUser_1.UserID->1对多->tblResight.CheckerID

在使用引用完整性的强制创建了大约25个关系之后,当我尝试添加另一个关系时,我得到以下错误:

“操作失败。表'tblUsers'上的索引太多。请删除该表上的一些索引,然后重试该操作。”

我运行了我找到的代码,它返回我在tblUsers上有6个索引。我知道每个表有32个索引的限制


我使用的关系GUI是否错误?access是否会在我创建关系时创建一个索引来强制执行引用完整性(尤其是在我运行脚本时不会出现的索引)?我有点困惑,任何帮助都将不胜感激。

您的表有隐藏索引,这些索引是在您定义关系时创建的。隐藏索引的名称以“~”字符开头。但是,由于以下表达式,您找到的代码忽略隐藏索引:

If Left(tbl.Name, 4) <> "MSys" And Left(tbl.Name, 1) <> "~" Then

好吧,在做了更多的研究之后,我想我找到了这个问题的答案。很明显,这是一个非常常见的有通道的天花板。我将总结我的发现如下:

每个表只能有32个“约束”。引用完整性(RI)的每个索引和强制执行都计入32。当您选择强制RI时,MS Access会自动创建约束;不能禁用此选项

我通过谷歌找到的所有代码片段和东西都返回了我在表上有六个索引(因此我感到困惑)。我没有发现/不知道的是,我的25段恋情与我的32段恋情相比被计算在内,因为我有强制的RI

我的解决方案是将RI放在“低优先级”字段上(这让我很难说),并通过数据输入表单“强制”它

基本上,这是我即将从access迁移到PostgreSQL的另一个原因


如果有人有更好的工作,我很乐意在这里。谢谢。

您可以获得所有索引(包括隐藏索引)的列表,包括以下内容:

Sub TableListIndexes(sTableName As String, Optional bPrintFields As Boolean = False)

    'Print indexes on a table, and fields in each index.
    'Need to add a reference to Microsoft ADO Ext. [version] for DDL and Security (ADOX).

    Dim cat As New ADOX.Catalog
    Dim idxs As ADOX.Indexes
    Dim idx As ADOX.Index
    Dim col As ADOX.Column
    Dim i As Integer

    Set cat.ActiveConnection = CurrentProject.Connection
    Set idxs = cat.Tables(sTableName).Indexes
    For Each idx In idxs
        Debug.Print i, idx.Name
        If bPrintFields Then
            For Each col In idx.Columns
                Debug.Print , col
            Next
        End If
        i = i + 1
    Next

End Sub

Sub TestTableListIndexes()
    TableListIndexes "tblProject"
End Sub

0            PrimaryKey  
1            ProjectBusinessUnitID_6D55FF7827CC48648A15A8E576EF02EF  
2            ProjectDivisionID_9CAC7B9D8136467B97F9BAA7217EAC38
etc

请注意,如果表中有任何多值字段,则每个字段都将有一个隐藏索引

它已经很老了,但是问题经常出现,而且这个线程在搜索机器中是第一个出现的(有人告诉我;)

克服此问题的一个很好的方法是使用“帮助表”链接到其他表

例如: 由于不同的原因,表格文章链接到许多其他表格。此外,她自己可能需要很多外键。这样的表经常从可能的索引中获取。在我最大的项目中,我也有三四个

要使可能的RI联接/索引几乎翻一番,您可以使用一个辅助表,它与表tblArticle具有1:1的RI联接,并且仅将唯一标识符作为字段。我确实给它起了同样的名字,而不是像平常一样在它前面加上短字母fk。我们称之为Tblaticlelinker

每个从tblArticle获取外键的表(例如订单位置)都从tblArticleLinker获取其联接。 -->您不会丢失所有这些链接的索引,只是链接表的索引

唯一需要确保的是,保存时始终将密钥添加到linkertable,否则无法使用该记录

根据我的经验,这样的表比通常在不同表中拆分字段的方法更容易处理。在不特别需要helpertable的查询中(如果这样做,有时查询会更快),可以直接链接到表。它只是没有像往常一样自动完成


Tipp:同样的方法也可以用来确保用户只能使用“已发布”的记录。或者只是用作硬过滤器。这有助于克服可能出现的软件错误,这些错误不符合它们应该遵循的逻辑

谢谢HansUp,但这些基本上还是给了我相同的答案,六。在做了更多的研究之后,我想我回答了我自己的问题。在这篇文章中,你似乎使用了“约束”这个词,而实际上你的意思是“索引”。RI创建了隐藏索引,但是,一般来说,大多数表与其他两三个表没有多大关系,所以用一个PK和,比如说,3个外键约束,您只使用了4个索引,剩下28个。如果有一个表确实需要索引28个字段,那么我建议您看看您的结构,它很可能是非规范化的。@David-W-Fenton:没有理由相信索引超过25个表示表是非规范化的。事实上,由于外键约束,规范化会导致更多索引。OP可以有一个包含25个字段的表,每个字段都是25个不同表中的外键。很容易想象一个对象有25个不同的、独立的属性,这些属性都可以表示为25个不同的表中的索引,而不会“失去规范化”。如果是这样的话,你会建议如何处理这个问题?把桌子分成两张1:1的桌子?这不是一个理想的解决方案。对我来说,25段感情是荒谬的。在我看来,你可能有一个重复的字段,因此,一个非规范化的结构。
Sub TableListIndexes(sTableName As String, Optional bPrintFields As Boolean = False)

    'Print indexes on a table, and fields in each index.
    'Need to add a reference to Microsoft ADO Ext. [version] for DDL and Security (ADOX).

    Dim cat As New ADOX.Catalog
    Dim idxs As ADOX.Indexes
    Dim idx As ADOX.Index
    Dim col As ADOX.Column
    Dim i As Integer

    Set cat.ActiveConnection = CurrentProject.Connection
    Set idxs = cat.Tables(sTableName).Indexes
    For Each idx In idxs
        Debug.Print i, idx.Name
        If bPrintFields Then
            For Each col In idx.Columns
                Debug.Print , col
            Next
        End If
        i = i + 1
    Next

End Sub

Sub TestTableListIndexes()
    TableListIndexes "tblProject"
End Sub
0            PrimaryKey  
1            ProjectBusinessUnitID_6D55FF7827CC48648A15A8E576EF02EF  
2            ProjectDivisionID_9CAC7B9D8136467B97F9BAA7217EAC38
etc