VillageSQL is a drop-in replacement for MySQL with extensions.
All examples on this page work on VillageSQL. Install Now →
mysql -u root -p sakila before you start.
How case sensitivity works
Nothing in your query decides it. A collation decides it, and every text column carries one. A character set says which characters a column can hold, and its collation says how to compare them. You override the collation for a single comparison withCOLLATE:
COLLATION_NAME with the collation you want the comparison to use, and
SEARCH_TEXT with the value to match.
Examples
1) 2 strings that differ only in case are equal
2) The same holds against a column
A lower case search term finds an upper case title.3) Read the column’s collation
ci is case-insensitive, which is why
example 2 matched. ai is accent-insensitive, and it does separate work: under
this collation 'e' = 'é' is true, and under utf8mb4_0900_as_cs it is
false.
That table is what your own column’s name means too. Run the query above
against any table and column to see which rules you are working under.
4) Ask for a case-sensitive comparison
COLLATE on a column gives up the index lookup
The index on a column is built in that column’s own collation, so a comparison in a different one cannot use it to find the matching values.EXPLAIN on the
query above reports a scan of all 1,000 rows rather than a lookup. That costs
nothing on 1,000 films and a great deal on a large table. When you need
case-sensitive matching on every query, the
Character sets and collations guide covers storing the
column that way instead.
Where the default comes from
A database created without a collation takes the server’s, a table takes the database’s, and a column takes the table’s. So a column with no collation named anywhere in its history is comparing case-insensitively because of a server setting.@@ in front of a name reads a server setting, and this pair tells you
which one you inherited:
Identifiers follow a different rule
Column names are never case-sensitive. Database and table names are a separate question, decided bylower_case_table_names:
Run
SELECT @@lower_case_table_names; to see where you stand. You cannot change
it from a session: SET GLOBAL lower_case_table_names=1 answers
ERROR 1238 (HY000): Variable 'lower_case_table_names' is a read only variable.
It is a startup setting, tied to how the server was first set up, so treat the
answer as a property of the server you are on.
The practical advice does not depend on the answer. Write every database and
table name in one case and use that spelling everywhere, so that moving the same
SQL between 2 servers cannot turn a working query into ERROR 1146 (42S02), the
error for a table that does not exist.
Summary
- Expect a string comparison to ignore case, because the usual collation ends
_ci. - Read a column’s collation from
INFORMATION_SCHEMA.COLUMNS. - Read a collation name from the end:
_ciand_aiignore,_cs,_asand_binrespect. - Use
COLLATEfor a one-off case-sensitive comparison, and accept that it gives up the index lookup. - Keep one spelling for every database and table name, whatever
lower_case_table_namessays.
See also
- LIKE — where this shows up first
- REGEXP — the same rule, with a different override
- Character sets and collations in MySQL — choosing one for a column
- Using utf8mb4 in MySQL — the character set behind the usual collation

