简体   繁体   中英

How to enforce case sensitive unique index only on subset of data in MySQL?

I realize MySQL has different collations I can use to enforce a case sensitive unique index, but for my particular use case, I want to enforce that only on a subset of the data.

Most of the unique IDs in the data set aren't case sensitive, so making the entire column case sensitive is not ideal. I can identify which rows have case sensitive IDs also.

It also seems MySQL doesn't have a way of creating an index with a condition either (correct me if I'm wrong).

Here is my schema

masterId - int
canonicalId - varchar
environment - int

canonicalId is the column I'm referring to, and it can be tied to different environments. Right now I have a unique index on canonicalId and environment. Environment "7" to give an example should have case sensitive IDs, the rest do not...

What is a good way to handle this?

Also: I don't think making all the unique IDs case sensitive would be a good solution here. We get these IDs from different services and the casing could very well change on them but not represent different items. That's why I only want to enforce case sensitivity on a service is known to use case sensitive IDs.

I was thinking of creating a SHA-256 hash of the canonicalId for this particular environment and the actual data along with the associated hash would be stored in a separate table if needed for lookup purposes later. I only need to ensure uniqueness in this table, as the information in the masterId column is used everywhere else in my application. Not sure if that would be the best way though.

Using a Generated Expression you can create:

alter table t
add g varchar(20) charset utf8 COLLATE utf8_bin GENERATED ALWAYS AS (
   IF(environmentId=7, canonicalId, UPPER(canonicalId))
)

Note: MariaDB doesn't support explicit collation on generated columns ( MDEV-12161 ).

The collation on g, via explict or table defaul, needs to be case sensitive.

Then make environmentId , g unique:

alter table t add unique index gunique(environmentId, g)

https://dbfiddle.uk/?rdbms=mariadb_10.3&fiddle=bba30d04eb21cc60a1c1f8993e5be6e6

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM