MySQL/InnoDB tables are always clustered (more on clustering here and here).
Since primary key also acts as a clustering key1, using the surrogate primary key means you are physically sorting the table in order that doesn't have a useful meaning for the client applications and cannot be utilized for querying.
Furthermore, secondary indexes in clustered tables can be "fatter" than in heap-based tables and may require double lookup.
For these reasons, you'd want to avoid surrogates and use more "natural" keys, similar to this:

({USER_ID, PICTURE_NO}
in table VOTE
references the same-named fields in PICTURE
. The VOTE.VOTER_ID
references USER.USER_ID
. Use integers for *_ID
and *_NO
fields if you can.)
This physical model will enable extremely efficient querying for:
- Pictures of the given user (a simple range scan on
PICTURE
primary/clustering index).
- Votes on the given picture (a simple range scan on
VOTE
primary/clustering index). Depending on circumstances, this may actually be fast enough so you don't have to cache the sum in PICTURE
.
If you need votes of the given user, change the VOTE
PK to: {VOTER_ID, USER_ID, PICTURE_NO}
. If you need both (votes of picture and votes of user), keep the existing PK, but create a covering index on {VOTER_ID, USER_ID, PICTURE_NO, VOTE_VALUE}
.
1 In InnoDB. There are DBMSes (such as MS SQL Server) where clustering key can differ from primary.