Memilih tipe data yang tepat adalah fundamental untuk performa dan storage efficiency. Setelah mengoptimasi ratusan tables, saya memahami impact dari choices data type yang tepat maupun salah.
Numeric Types
1. Integer Types
CREATE TABLE test_integers ( tiny TINYINT, -- -128 to 127 atau 0 to 255 (UNSIGNED) small SMALLINT, -- -32768 to 32767 medium MEDIUMINT, -- -8388608 to 8388607 normal INT, -- -2147483648 to 2147483647 big BIGINT, -- -9223372036854775808 to 9223372036854775807-- UNSIGNED untuk positive only positive_id INT UNSIGNED -- 0 to 4294967295);
Pilihan Guide:
– TINYINT: Boolean, small counters (0-255)
– SMALLINT: Status codes, year, small IDs
– INT: Primary keys, regular counters (2 billion max)
– BIGINT: Timestamps, large counters, UUIDs2. Decimal Types
CREATE TABLE financial_data ( -- DECIMAL untuk exact precision (currency!) price DECIMAL(10,2), -- 99999999.99 exchange_rate DECIMAL(9,6), -- 99.999999 large_amount DECIMAL(19,4), -- Untuk accounting-- FLOAT/DOUBLE untuk scientific (hati-hati!) latitude FLOAT, -- 7 digit precision longitude DOUBLE -- 15 digit precision);
Rule: Gunakan DECIMAL untuk currency, jangan FLOAT/DOUBLE!
String Types
1. CHAR dan VARCHAR
CREATE TABLE string_examples ( -- CHAR: Fixed length, padding dengan spaces country_code CHAR(2), -- 'US', 'ID' gender CHAR(1), -- 'M', 'F'-- VARCHAR: Variable length, efficient storage username VARCHAR(50), -- Max 50 chars email VARCHAR(100), -- Max 100 chars description VARCHAR(500) -- Longer text);
Pilihan:
– CHAR: Fixed length (codes, flags)
– VARCHAR: Variable length (names, emails)
– Rule: VARCHAR(20-255) untuk kebanyakan strings2. TEXT Types
CREATE TABLE content_data ( short_text TEXT, -- Max 64KB medium_content MEDIUMTEXT, -- Max 16MB long_content LONGTEXT -- Max 4GB );Tips:
– TEXT untuk content yang lebih dari 255 chars
– BLOB untuk binary data (images, files)
– Consider separate tables untuk large TEXT/BLOBDate and Time Types
1. DATE, TIME, DATETIME, TIMESTAMP
CREATE TABLE temporal_data ( -- DATE: Calendar dates birth_date DATE, -- '1990-05-15'-- TIME: Time of day atau duration business_hours TIME, -- '09:00:00' duration TIME, -- '02:30:00' -- DATETIME: Date dan time combination created_at DATETIME, -- '2024-01-15 14:30:00' -- TIMESTAMP: Unix timestamp, auto timezone modified_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- YEAR: Year value model_year YEAR -- 1990, 2024);
Pilihan:
– DATE: Birth dates, anniversaries
– DATETIME: Timestamps, created_at
– TIMESTAMP: Auto-updating, timezone-aware
– YEAR: Model years, copyright years2. Range dan Storage
| Type | Range | Storage |
|---|---|---|
| DATE | 1000-01-01 to 9999-12-31 | 3 bytes |
| DATETIME | 1000-01-01 00:00:00 to 9999-12-31 23:59:59 | 8 bytes |
| TIMESTAMP | 1970-01-01 00:00:01 to 2038-01-19 | 4 bytes |
Boolean dan ENUM
1. Boolean (TINYINT)
CREATE TABLE flags (
-- MySQL tidak punya native BOOLEAN
is_active TINYINT(1), -- 0 atau 1
is_deleted BOOLEAN, -- Alias untuk TINYINT(1)
is_published TINYINT(1) DEFAULT 0
);
-- Penggunaan
INSERT INTO flags (is_active) VALUES (1); -- TRUE
INSERT INTO flags (is_active) VALUES (0); -- FALSE
2. ENUM dan SET
CREATE TABLE status_data ( -- ENUM: Single value dari predefined list status ENUM('draft', 'published', 'archived') DEFAULT 'draft',-- SET: Multiple values dari predefined list permissions SET('read', 'write', 'delete') DEFAULT 'read');
-- Penggunaan
INSERT INTO status_data (status) VALUES ('published');
INSERT INTO status_data (permissions) VALUES ('read,write');JSON Type (MySQL 5.7+)
CREATE TABLE json_data ( id INT AUTO_INCREMENT PRIMARY KEY, attributes JSON, metadata JSON,-- Virtual column dari JSON name VARCHAR(100) AS (JSON_UNQUOTE(JSON_EXTRACT(attributes, '$.name'))) STORED, -- Index pada JSON path INDEX idx_name (name));
-- Penggunaan
INSERT INTO json_data (attributes) VALUES
('{"name": "Product A", "price": 99.99, "category": "electronics"}');-- Query JSON
SELECT * FROM json_data WHERE JSON_EXTRACT(attributes, '$.price') > 50;Best Practices
1. Storage Efficiency
-- Pilih smallest sufficient type -- BAD CREATE TABLE bad_example ( id BIGINT, -- Overkill untuk < 2 billion rows status VARCHAR(100), -- Overkill untuk 'active'/'inactive' tiny_flag INT -- TINYINT sudah cukup );-- GOOD CREATE TABLE good_example ( id INT UNSIGNED, -- Sufficient untuk 4 billion status VARCHAR(20), -- Reasonable length tiny_flag TINYINT -- Efficient );
2. Performance Considerations
-- Smaller types = faster queries -- Fixed length = better performance-- CHAR lebih cepat daripada VARCHAR untuk short strings hash CHAR(64) -- MD5 atau SHA256 hash
-- INT lebih cepat daripada VARCHAR untuk comparisons status_code INT -- 1, 2, 3 daripada 'active', 'pending', 'done'
3. Future-Proofing
-- Plan untuk growth -- Jika expect > 2 billion rows dalam 5 tahun id BIGINT UNSIGNED -- Better dari INT-- Jika expect international users name VARCHAR(255) -- CJK characters take more bytes
-- Jika expect long content description TEXT -- VARCHAR(255) tidak akan cukup
Kesimpulan
Memilih tipe data yang tepat:
– Reduces storage: Gunakan smallest sufficient type
– Improves performance: Fixed length lebih cepat
– Ensures accuracy: DECIMAL untuk currency
– Enables features: JSON untuk flexible dataDengan pemilihan yang bijaksana, database Anda akan lebih efficient dan scalable.
Ditulis oleh
Hendra Wijaya