Storing SHA1 hash values in MySQL
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
A SHA1 hash is 160 bits long, which means it can be stored either as 20 raw bytes or as a 40-character hexadecimal string. In MySQL, both approaches work, but they are not equivalent in storage cost or ergonomics. The best design depends on whether you want compact binary storage or easier human readability. The more important security point is that SHA1 should not be used for password hashing in new systems.
Know the Two Common Storage Forms
SHA1 values are usually represented in one of two ways:
- raw binary digest, which is 20 bytes
- hexadecimal text, which is 40 characters
If you compute a SHA1 hash in application code and keep it as hex, a schema like this works:
If you store the raw digest instead, use a binary column:
Binary storage is smaller and usually better for indexing efficiency. Hex storage is easier to inspect manually in SQL queries.
CHAR(40) Versus BINARY(20)
CHAR(40) is simple because the value looks like what most developers expect:
But it uses twice as much space as the raw digest because every byte is written as two hex characters.
BINARY(20) is more compact and more natural if you care about storage efficiency or large indexes.
A practical rule is:
- use
CHAR(40)if human readability in SQL tooling matters more - use
BINARY(20)if compact storage and indexing matter more
Insert SHA1 Values in MySQL
If you want MySQL to compute the SHA1 value and store it as hex text:
If you want to store the raw binary digest, convert the hex output using UNHEX:
SHA1() returns hex text by default, so UNHEX(...) is the bridge from textual representation to the compact binary form.
Read Binary Hashes Back as Hex
When you store a binary digest, it is often helpful to display it as hex in queries.
This gives you the familiar 40-character representation without giving up compact storage internally.
Indexing and Uniqueness
Hashes are often used for deduplication or integrity checks, so indexes matter.
Or for hex storage:
A unique index is useful if the hash is being used as a content fingerprint and duplicate values should not be inserted.
Do Not Use SHA1 for Passwords
This is the most important caution in the whole topic. SHA1 is no longer appropriate for password hashing. It is too fast and has known cryptographic weaknesses.
If the goal is password storage, use a dedicated password-hashing algorithm such as:
- bcrypt
- Argon2
- PBKDF2
Those algorithms are intentionally slow and designed for credential storage. SHA1 is not.
SHA1 can still appear in non-password contexts such as legacy content fingerprints, file integrity checks, or compatibility with older systems, but even there many teams now prefer SHA-256 or stronger options.
Migration Considerations
If you already have SHA1 stored as CHAR(40) and want to move to BINARY(20), you can convert existing rows:
If you are migrating to a stronger hash such as SHA-256, remember that the schema needs to change too:
- SHA1 hex length is 40
- SHA-256 hex length is 64
- SHA1 binary length is 20
- SHA-256 binary length is 32
Do not assume a stronger hash will fit into the old column definition.
Common Pitfalls
A common mistake is storing SHA1 as VARCHAR(40) when the length is fixed. CHAR(40) or BINARY(20) is a better fit.
Another issue is treating SHA1 as acceptable for password storage. It is not. Use a password-hashing algorithm instead.
Developers also sometimes store hex text and then forget they are paying double the storage compared with raw binary.
Finally, be explicit about case handling. Hex strings can appear in upper or lower case; binary storage avoids that inconsistency entirely.
Summary
- A SHA1 digest is 20 bytes in binary or 40 characters in hexadecimal.
- Use
BINARY(20)for compact storage orCHAR(40)for easier readability. - In MySQL,
SHA1()returns hex text;UNHEX(SHA1(...))stores the compact binary form. - '
HEX(binary_column)is useful for displaying binary digests as readable text.' - Do not use SHA1 for passwords; use a dedicated password-hashing algorithm instead.
Related reading
- Storing Time Series in AWS DynamoDb
- Strange MySQL Popup Mysql Installer is running community mode
- Stream delete events from MySQL to PostgreSQL via Apache-kafka
- Streaming data from Kafka into Cassandra in real time
- substitution cipher with different alphabet length
- Suddenly getting Unable to connect to the server net/http TLS handshake timeout from kubectl
- Strict consistency vs atomic consistency
- Strict serializability example clarification?

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.