可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.