MySQL: A Detailed Explanation and Selection Guide for MySQL…

Last updated: 2026-08-26

Data types determine how data is stored, how much space it occupies, and what operations can be performed on it—choosing the wrong type can have serious consequences.

This lesson provides a systematic overview of all MySQL data types and strategies for selecting them.

100%
graph TB
    A[MySQL Data Types] --> B[Integer Types]
    A --> C[Floating-point/Fixed-point type]
    A --> D[String Type]
    A --> E[Date and Time Type]
    A --> F[JSON Type]
    B --> B1[TINYINT]
    B --> B2[SMALLINT]
    B --> B3[INT]
    B --> B4[BIGINT]
    C --> C1[FLOAT]
    C --> C2[DOUBLE]
    C --> C3[DECIMAL]
    D --> D1[CHAR]
    D --> D2[VARCHAR]
    D --> D3[TEXT]
    D --> D4[ENUM]
    E --> E1[DATE]
    E --> E2[DATETIME]
    E --> E3[TIMESTAMP]

1. What You'll Learn



2. A True Story About a Precision Issue

(1) Pain Point: The amount was calculated incorrectly

An e-commerce system stores product prices as FLOAT:

SQL
-- Demonstration of Floating-Point Precision Loss
SELECT 0.1 + 0.2;  -- Results: 0.300000004(approximate value,Inaccurate)

-- It becomes more apparent after it is entered into the table
CREATE TABLE float_demo (price FLOAT);
INSERT INTO float_demo VALUES (199.99);
SELECT price FROM float_demo;  -- Results: 199.99(The display is correct, but there is a slight error in the internal storage.)
SELECT price + 0.01 FROM float_demo;  -- Cumulative errors may become apparent during calculations

After 1,000 transactions, the cumulative accuracy error caused a discrepancy of a few yuan in the financial reconciliation.

(2) Solution for DECIMAL

SQL
-- DECIMAL Precise Storage,No error
CREATE TABLE decimal_demo (price DECIMAL(10,2));
INSERT INTO decimal_demo VALUES (199.99);
SELECT price + 0.01 FROM decimal_demo;  -- Results: 200.00(Accurate)

Result: price = 200.00, accurate with no errors.

Type Accuracy Applicable Scenarios
FLOAT Approximate (6–7 digits) Scientific calculations; precision not required
DOUBLE Approximate (15–16 bits) Scientific Computing
DECIMAL Precision Amounts, financial data


3. Integer Types

Type Bytes Signed Range Unsigned Range
TINYINT 1 -128 ~ 127 0 ~ 255
SMALLINT 2 -32,768 ~ 32,767 0 ~ 65,535
MEDIUMINT 3 -8,388,608 ~ 8,388,607 0 ~ 16,777,215
Input 4 -2,147,483,648 ~ 2,147,483,647 0 ~ 4,294,967,295
BIGINT 8 -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 0 ~ 18,446,744,073,709,551,615

▶ Example: Integer Types

SQL
CREATE TABLE user_stats (
    id INT PRIMARY KEY AUTO_INCREMENT,
    age TINYINT UNSIGNED,              -- Age 0-255 Enough
    view_count INT UNSIGNED,           -- Number of views
    total_orders BIGINT UNSIGNED       -- Total Number of Orders(It's very likely)
);

-- UNSIGNED Indicates unsigned(Only positive numbers)
INSERT INTO user_stats (age, view_count, total_orders) 
VALUES (25, 1000000, 9999999999);
▶ Try it Yourself

Output:

TEXT 📖 Display only
Output displayed
💡 Tip: Choose the smallest data type that meets your needs to save storage space. Use TINYINT for age and BIGINT for user ID.



4. Floating-Point and Fixed-Point Types

Type Bytes Precision Use Cases
FLOAT 4 6–7 digits Scientific Computing
DOUBLE 8 15–16 bits Scientific Computing
DECIMAL(M,D) Variable Exact Amounts, Finance

M = total number of digits, D = number of decimal places. DECIMAL(10,2) indicates up to 10 integer digits + 2 decimal places.

▶ Example: Using DECIMAL

SQL
CREATE TABLE financials (
    id INT PRIMARY KEY,
    amount DECIMAL(12,2),       -- Amount,Maximum 9999999999.99
    rate DECIMAL(5,4),          -- Ratio,Maximum 9.9999
    quantity DECIMAL(8,0)       -- Number of integers
);

INSERT INTO financials VALUES (1, 1234567.89, 0.0850, 1000);
SELECT * FROM financials;
▶ Try it Yourself

Output:

TEXT 📖 Display only
+----+-------------+--------+----------+
| id | amount      | rate   | quantity |
+----+-------------+--------+----------+
|  1 | 1234567.89  | 0.0850 |     1000 |
+----+-------------+--------+----------+


5. String Type

Type Maximum Length Features Use Cases
CHAR(N) 255 bytes Fixed length, fast Cell phone numbers, ID numbers, MD5
VARCHAR(N) 65,535 bytes Variable length, space-saving Username, email, title
TINYTEXT 255 bytes Text Short text
TEXT 65,535 bytes Text Article Content
MEDIUMTEXT 16M Text Long Article
LONGTEXT 4G Text Extra-long text
ENUM 65,535 values Enumeration Status, Type
SET 64 values Set Multi-select labels

(1) CHAR vs VARCHAR

SQL
-- CHAR(10) Fixed length, storing 'abc' uses 10 bytes
-- VARCHAR(10) Variable length, storing 'abc' uses 4 bytes (3 + 1 length prefix)

CREATE TABLE phones (
    -- Mobile Number (Fixed 11 digits), use CHAR for faster lookup
    mobile CHAR(11),
    -- Username length varies, use VARCHAR to save space
    username VARCHAR(50)
);

▶ Example: ENUM Enumeration Type

SQL
CREATE TABLE orders (
    id INT PRIMARY KEY,
    status ENUM('pending', 'paid', 'shipped', 'completed', 'cancelled') DEFAULT 'pending'
);

INSERT INTO orders (id, status) VALUES (1, 'paid');
INSERT INTO orders (id) VALUES (2);  -- Default 'pending'

-- ENUM stores numerical indexes (1,2,3...), not strings
SELECT status, status + 0 AS index_num FROM orders;
▶ Try it Yourself

Output:

TEXT 📖 Display only
+---------+-----------+
| status  | index_num |
+---------+-----------+
| paid    |         2 |
| pending |         1 |
+---------+-----------+


6. Date and Time Types

Type Format Range Bytes
DATE YYYY-MM-DD 1000-01-01 ~ 9999-12-31 3
TIME HH:MM:SS -838:59:59 ~ 838:59:59 3
DATETIME YYYY-MM-DD HH:MM:SS 1000-01-01 ~ 9999-12-31 8
TIMESTAMP YYYY-MM-DD HH:MM:SS 1970-01-01 ~ 2038-01-19 4
Year YYYY 1901 ~ 2155 1

(1) DATETIME vs TIMESTAMP

Dimension DATETIME TIMESTAMP
Range 1000–9999 1970–2038
Storage 8 bytes 4 bytes
Time Zone Do Not Convert Automatically Convert to UTC
Recommendation Date Record Creation/Modification Time

▶ Example: Using Dates and Times

Output:

TEXT 📖 Display only
Query OK, 0 rows affected

Query OK, 1 row affected

---+---------+------------------
id | name    | email            
---+---------+------------------
1  | Alice   | alice@email.com  
2  | Bob     | bob@email.com    
3  | Charlie | charlie@email.com
---+---------+------------------
3 rows in set
SQL
CREATE TABLE events (
    id INT PRIMARY KEY AUTO_INCREMENT,
    event_name VARCHAR(100),
    event_date DATE,
    start_time TIME,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

INSERT INTO events (event_name, event_date, start_time) 
VALUES ('Tech Conference', '2026-09-15', '09:00:00');

SELECT * FROM events;

Output:

TEXT 📖 Display only
+----+----------------+------------+------------+---------------------+---------------------+
| id | event_name     | event_date | start_time | created_at          | updated_at          |
+----+----------------+------------+------------+---------------------+---------------------+
|  1 | Tech Conference| 2026-09-15 | 09:00:00   | 2026-07-03 10:00:00 | 2026-07-03 10:00:00 |
+----+----------------+------------+------------+---------------------+---------------------+

Output:

TEXT 📖 Display only
Output displayed


7. JSON Data Type (MySQL 8.0+)

▶ Example: Working with JSON

Output:

TEXT 📖 Display only
Query OK, 0 rows affected

Query OK, 1 row affected

--------+-------+--------
name    | color | storage
--------+-------+--------
Alice   | Red   | 25     
Bob     | Blue  | 26     
Charlie | Green | 27     
--------+-------+--------
3 rows in set

---+-------+----------------
id | name  | email          
---+-------+----------------
1  | Alice | alice@email.com
2  | Bob   | bob@email.com  
---+-------+----------------
2 rows in set
SQL
CREATE TABLE products (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100),
    attributes JSON
);

INSERT INTO products (name, attributes) VALUES 
('iPhone', '{"color": "black", "storage": 128, "tags": ["phone", "apple"]}');

-- Extract JSON value
SELECT 
    name,
    attributes->>'$.color' AS color,
    attributes->>'$.storage' AS storage
FROM products;

-- JSON Array Lookup
SELECT * FROM products WHERE JSON_CONTAINS(attributes->'$.tags', '"apple"');

Output:

TEXT 📖 Display only
Output displayed

Output:

TEXT 📖 Display only
+--------+-------+---------+
| name   | color | storage |
+--------+-------+---------+
| iPhone | black | 128     |
+--------+-------+---------+


8. Best Practices for Choosing Data Types

Scenario Recommended Type Reason
Primary Key ID BIGINT AUTO_INCREMENT Wide range, good performance
Username VARCHAR(50) Variable length, saves space
Email VARCHAR(100) Variable-length
Phone Number CHAR(11) Fixed length, fast lookups
Password Hash CHAR(60) bcrypt fixed at 60 characters
Amount DECIMAL(10,2) Precise Calculation
Status ENUM or TINYINT Finite options
Article Content TEXT Long Text
Creation Time TIMESTAMP Automatically managed, 4 bytes
JSON Data JSON Supports indexes and functions

❓ FAQ

Q What is the difference between VARCHAR(255) and VARCHAR(256)?
A For VARCHAR lengths ≤255, 1 byte is used to store the length; for lengths >255, 2 bytes are used. There is no fundamental difference in performance, but 255 is a commonly used cutoff point.
Q What should I do about the TIMESTAMP 2038 problem?
A A fix is already planned for MySQL 8.0. If you're concerned, use DATETIME instead.
Q Can a single field store multiple values?
A You can use the SET data type or a JSON array, but it is recommended to break it down into related tables (which is more standard practice).
Q Can the TEXT field be indexed?
A Yes, but only prefix indexes can be created (INDEX(col(100))). If you need a full index, consider using VARCHAR.

📖 Summary


📝 Exercises

  1. Basic Question (Difficulty ⭐): Design the products table for an e-commerce system, and select the appropriate data types to store the name, price, inventory, status, and description.

  2. Advanced Exercise (Difficulty ⭐⭐): Create a table named user_profiles that contains a field named preferences of type JSON, and practice extracting and querying JSON values.

  3. Challenge (Difficulty: ⭐⭐⭐): Compare the differences in precision between DECIMAL(10,2) and FLOAT when storing amounts, and use experiments to demonstrate the accuracy of DECIMAL.

Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏