A Workaround for MySQL ERROR 1070
As documented in the Reference Manual MySQL supports a maximum of 16 columns per index. That’s more than sufficient for most index use cases, but what about unique constraints? If I create a fact table with more than 16 dimension columns in my star schema, and then try to add an index to enforce a unique constraint across all of the dimension columns, then I’ll get this error:
1
| |
For multi-column unique indexes, internally MySQL concatenates all of the column values together in a single hyphen-delimited string for comparison. Thus I can simulate a multi-column unique index by adding an extra column that stores the concatenated column values, and adding a unique index on that column.
Read on for details…
I could populate the new column in my application code, but for the sake of this blog post I’ll use MySQL triggers instead.
Here’s a table with 20 columns:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
As previously discussed, I can’t add a unique index on all 20 columns:
1 2 3 | |
Proceeding with the workaround, I add a new column with a unique index on it. The column needs to be long enough to store the concatenated values. For my test table each INT column value can be up to 11 chars long, each CHAR column value can be up to 8 characters long, and the hyphens will account for 19 characters, so the new column needs to store up to (10 * 11) + (10 * 8) + 19 = 209 characters. I’ll make it 255:
1 2 3 | |
I need two triggers to populate the new column, a BEFORE INSERT trigger and an AFTER INSERT trigger. Here they are:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | |
To test the unique index I try to insert two duplicate rows:
1 2 3 4 5 6 7 | |
The second insert failed as desired. Now let me test an update:
1 2 3 4 5 6 | |
Again the unique constraint was properly enforced.
