“Too many indexes on table” error when creating re

2019-04-06 22:53发布

问题:

I have tblUsers which has a primary key of UserID.

UserID is used as a foreign key in many tables. Within a table, it is used as a foreign key for multiple fields (e.g. ObserverID, RecorderID, CheckerID).

I have successfully added relationships (with in the the MS Access 'Relationship' view), where I have table aliases to do the multiple relationships per table:

*tblUser.UserID -> 1 to many -> tblResight.ObserverID

*tblUser_1.UserID -> 1 to many -> tblResight.CheckerID

After creating about 25 relationships with enforcement of referential integrity, when I try to add an additional one, I get the following error:

"The operation failed. There are too many indexes on table 'tblUsers.' Delete some of the indexes on the table and try the operation again."

I ran the code I found here and it returned that I have 6 indexes on tblUsers. I know there is a limit of 32 indexes per table.

Am I using the relationship GUI wrong? Does access create an index for the enforcement of referential integrity any time I create a relationship (especially indexes that wouldn't turn up when I ran the script)? I'm kind of baffled, any help would be appreciated.

回答1:

Okay, after doing some more research, I think I got the answer to this question. Apparently this is a very common ceiling with access. I'll sum up this post I found below:

Each table can only have 32 'constraints'. Each index and enforcement of referential integrity (RI) counts towards this 32. MS Access automatically creates a constraint when you select to enforce RI; you cannot disable this option.

All the code snipets and things I found through google, returned that I had six indexes on the table (and hence I was getting confused). What I wasn't finding/didn't know was that my 25 relationships were counted against my 32, because I had RI enforced.

My solution to this was to drop RI on the 'lower priority' fields (it pains me to say that), and to 'enforce' it through the data entry forms.

Basically, this is one more reason I'm migrating out access and into PostgreSQL shortly.

If anyone has a better work around, I would love to here it. Thanks.



回答2:

Your table has hidden indexes which were created when you defined your relationships. The names for hidden indexes start with the "~" character. But the code you found ignores hidden indexes because of this expression:

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

You could make that ListIndexes() function include hidden indexes by changing that line to this:

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

Also, you can verify the total number of indexes for your table with this statement in the Immediate Window:

? CurrentDb.TableDefs("tblUsers").Indexes.Count


回答3:

You can get a listing of all indexes, including hidden ones, with the following:

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

Which gives

0            PrimaryKey  
1            ProjectBusinessUnitID_6D55FF7827CC48648A15A8E576EF02EF  
2            ProjectDivisionID_9CAC7B9D8136467B97F9BAA7217EAC38
etc

Note that if you have any multivalue fields in a table each will have a hidden index.



回答4:

It is quite old, but the problem come back very often and this thread comes first in search machines (someone told me ;) )

A good possibility to overcome this problem is to work with a "helper-Table" to link to other Tables.

An example: A table Article is linked to a lot of other tables for different reasons. Also she may need a lot of foreign keys for itself. Such table get very often out of possible indexes. I do also have three or four of them in my biggest projects.

To almost double the possible RI Joins/indexes you can work with a helper table which has a 1:1 RI Join to the table tblArticle with just the Unique-Identifier as a Field. I do name it the same not with shortletter fk in Front of it as I would do normally. Let's call it tblArticleLinker.

Every table that gets a foreign Key from tblArticle, for example an Order-Position, get its join from the tblArticleLinker. --> You do not loose an index for all these links, just one to the Linkertable

The only thing you have to make sure, is that you always add the key to the linkertable when saving, otherwise it is not possible to use the Record.

Such a table is - from my experience - much easier to handle than the usual approach to split the fields in different tables. In Queries you do not especially need the helpertable (sometimes queries are faster if you do so), you could link directly to the table. It is just not done automatically as usual.

Tipp: Same approach can also be used to make sure, that only "released" Records can be used by the user. Or to just use as a Hard-Filter. This helps to overcome possible Software-Bugs which do not follow the logic they should.