In MySQL, does following statement make sense?
CREATE TABLE `sku_classification` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`sku` int(10) unsigned NOT NULL,
`business_classification_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `IDX_SKU_BUSINESS_CLASSIFICATION` (`sku`,`business_classification_id`),
UNIQUE KEY `sku` (`sku`)
)
Is it an unnecessary overkill to add a unique key on a combination of fields (sku
,business_classification_id
), one of which (sku
) already has unique index on it? Or is it not, and there is indeed some reason for such duplicate unique index?
Yes, you can. But it does not make sense. But, let's analyze what is going on.
An INDEX
(UNIQUE
or not) is a BTree that facilitates lookups in the table.
A UNIQUE
index is both an index and a "constraint" saying that there shall not be any duplicates.
You have already said UNIQUE(sku)
. This provides both an index an a uniqueness constraint.
Adding UNIQUE(sku, x)
in that order:
SELECT
were sku
and x
. Even so, you may as make it an INDEX
not a UNIQUE
, because...INSERT
must do some extra effort to prevent "duplicate key". (OK, the INSERT
code is not smart enough to see that you have UNIQUE(sku)
.)If that is your complete table, there is no good reason to have the id AUTO_INCREMENT
; you may as well promote sku
to be the PRIMARY KEY
. (A PK is a UNIQUE KEY
.)
Furthermore... If, on the other hand, you were suggesting UNIQUE(x, sku)
, then there is one slight difference. This provides you a way to efficiently lookup by x
-- a range of x
, or x=constant AND sku BETWEEN ...
, or certain other thing that are not provided by (sku, x)
. Order matters in an index. But, again, it may as well be INDEX(x, sku)
, not UNIQUE
.
So, the optimal set of indexes for the table as presented is not 3 indexes, but 1:
PRIMARY KEY(sku)
One more note: With InnoDB, the PK is "clustered" in BTree with the data. That is, looking up by the PK is very efficient. When you need to go through a "secondary index", there are two steps: first drill down the secondary index's BTree to find the PK, then drill down the PK's BTree.