Membangun tabel yang efektif

Selesai

Desain tabel yang efektif membentuk fondasi database apa pun. Tabel menyusun data Anda dan menentukan seberapa efisien kueri Anda mengakses dan memodifikasi informasi.

Mendesain dan membuat tabel

Tabel adalah blok penyusun dasar database relasional, mengatur data ke dalam baris dan kolom yang mewakili entitas dan atributnya. Dalam sistem relasional, tabel menentukan struktur untuk menyimpan data transaksional, menegakkan hubungan melalui kunci asing, dan menyediakan fondasi untuk kueri dan pelaporan.

Untuk analitik multidirektori, tabel berfungsi sebagai tabel fakta yang menyimpan peristiwa terukur dan tabel dimensi yang menyediakan konteks untuk analisis. Keputusan desain yang Anda buat saat membuat tabel—jenis data, ukuran kolom, batasan, dan hubungan—berdampak langsung pada efisiensi penyimpanan, performa kueri, integritas data, dan skalabilitas di seluruh beban kerja operasional dan analitik.

Pilih jenis data yang sesuai

Jenis data adalah keputusan mendasar yang memengaruhi database Anda. Pilihan yang salah dapat menyebabkan penyimpanan terbuang, performa buruk, kehilangan data, atau kesalahan aplikasi. Tidak seperti kode aplikasi yang dapat Anda refaktor dengan mudah, mengubah jenis data kolom dalam database produksi sering memerlukan pembangunan ulang tabel, yang dapat berarti waktu henti berjam-jam untuk tabel besar.

Pilih jenis data yang tepat saat Anda merancang skema awal, karena ini adalah waktu term mudah untuk memperbaikinya. Selain itu, pertimbangkan jenis data dengan hati-hati saat:

  • Anda menyimpan data di mana presisi penting
  • Anda bekerja dengan tabel volume tinggi di mana biaya penyimpanan dikalikan
  • Anda menentukan kolom yang sering dikueri yang berkinerja lebih cepat dengan jenis yang lebih kecil

Menjelajahi jenis data umum

Jenis data yang sesuai memengaruhi penyimpanan, performa, dan operasi:

Jenis Kategori Tipe Data Ukuran Penyimpanan Panduan Penggunaan Contoh
Numeric INT,BIGINT,DECIMAL,FLOAT 4 bytes, 8 bytes, bervariasi Pilih berdasarkan kebutuhan akan rentang dan presisi Quantity INT, Revenue DECIMAL(10,2), Population BIGINT
String VARCHAR, CHAR, NVARCHAR 1 byte/karakter, tetap, 2 byte/karakter Gunakan VARCHAR untuk data panjang variabel, CHAR untuk panjang tetap, NVARCHAR untuk Unicode Email VARCHAR(100), CountryCode CHAR(2), ProductName NVARCHAR(100)
Tanggal/Waktu DATE, DATETIME2, DATETIMEOFFSET 3 byte, 6-8 byte, 10 byte DATETIME2 memberikan presisi yang lebih baik daripada DATETIME BirthDate DATE, OrderTimestamp DATETIME2, EventTime DATETIMEOFFSET
Binary VARBINARY, IMAGE Bervariasi Untuk menyimpan data biner seperti gambar atau dokumen ProfilePhoto VARBINARY(MAX), DocumentContent VARBINARY(MAX)
Khusus UNIQUEIDENTIFIER, XML, JSON 16 byte, bervariasi, biner asli UNIQUEIDENTIFIER untuk GUID, XML untuk dokumen XML, JSON (SQL 2025+) untuk dokumen JSON dalam format biner asli RowGUID UNIQUEIDENTIFIER, Config XML, Settings JSON

Rincian jenis data memerlukan perhatian yang cermat. Misalnya, menggunakan FLOAT untuk data keuangan alih-alih DECIMAL dapat memperkenalkan kesalahan pembulatan yang tidak dapat diperbaiki tanpa menghitung ulang setiap nilai dependen. Menggunakan kunci UNIQUEIDENTIFIER saat INT sudah mencukupi akan meningkatkan ukuran indeks Anda menjadi tiga kali lipat dan memperlambat setiap operasi JOIN. Sebagian besar keputusan ini memengaruhi performa database dan dapat menentukan apakah kueri berjalan dalam milidetik atau menit.

Memperkirakan persyaratan ukuran tabel

Ukuran tabel bukan hanya tentang biaya penyimpanan; ini berdampak langsung pada operasi database Anda. Ukuran tabel memengaruhi waktu pencadangan dan pemulihan, durasi pembangunan ulang indeks, dan performa kueri.

Penting

Tabel yang dirancang dengan buruk yang menyimpan 200 byte per baris alih-alih 100 byte menggandakan kebutuhan penyimpanan, waktu pencadangan, dan persyaratan I/O Anda.

Skenario lain untuk merencanakan ukuran tabel adalah ketika Anda menghitung biaya penyimpanan untuk database cloud, merancang ruang disk terbatas, atau merencanakan strategi arsip. Semua skenario ini memerlukan perkiraan ukuran yang akurat untuk membuat keputusan berdasarkan informasi tentang sumber daya dan operasi.

Misalnya, perusahaan ritel yang menyimpan 100 juta transaksi setiap hari dengan tambahan 50 byte per baris menghabiskan 5 GB per hari—yaitu 1,8 TB penggunaan penyimpanan yang tidak perlu setiap tahun, ditambah peningkatan proporsional dalam waktu dan biaya pencadangan.

Contoh berikut menunjukkan cara memperkirakan ukuran untuk Employee tabel:

-- Estimate row size for a table
-- Fixed-length columns: sum of column sizes
-- Variable-length: estimate average size
-- Example row calculation:
CREATE TABLE Employee (
    EmployeeID INT,              -- 4 bytes
    FirstName NVARCHAR(50),      -- ~2-100 bytes (avg 40)
    LastName NVARCHAR(50),       -- ~2-100 bytes (avg 40)
    HireDate DATE,               -- 3 bytes
    Salary DECIMAL(10,2)         -- 5 bytes
);  
-- Estimated row size: 4 + 40 + 40 + 3 + 5 = ~92 bytes
-- Plus row overhead (~7 bytes) = ~99 bytes per row
-- 1 million rows ≈ 94 MB

Tip

Anda dapat menggunakan Copilot untuk membantu Anda menghasilkan estimasi ukuran tabel.

Merancang kolom yang efektif

Contoh berikut menunjukkan tabel yang dirancang Product dengan baik yang menerapkan prinsip-prinsip yang tercakup dalam unit ini:

CREATE TABLE Product (
    ProductID INT PRIMARY KEY IDENTITY(1,1),       -- Auto-incrementing surrogate key (4 bytes)
    ProductName NVARCHAR(100) NOT NULL,             -- Unicode support, appropriate length, enforced
    Category NVARCHAR(50) NOT NULL,                 -- Smaller than ProductName (categorization needs less space)
    Price DECIMAL(10,2) NOT NULL,                   -- Exact precision for financial data
    StockQuantity INT NOT NULL DEFAULT 0,           -- Integer sufficient for inventory, default prevents nulls
    LastRestocked DATETIME2 DEFAULT GETUTCDATE()    -- Modern date type with automatic timestamp
);

Tabel ini menunjukkan beberapa praktik terbaik:

  • Jenis data yang sesuai: INT untuk kunci primer (lebih kecil dari BIGINT atau UNIQUEIDENTIFIER), DECIMAL(10,2) untuk perhitungan keuangan yang tepat alih-alih FLOAT, DATETIME2 untuk presisi yang lebih baik daripada warisan DATETIME
  • Kolom berukuran kanan: NVARCHAR(100) untuk nama produk dan NVARCHAR(50) untuk kategori berdasarkan panjang data yang diharapkan
  • Batasan: NOT NULL memastikan kualitas data dengan mencegah nilai penting yang hilang
  • Nilai default: Nilai otomatis untuk StockQuantity (0) dan LastRestocked (waktu UTC saat ini) mengurangi kompleksitas kode aplikasi
  • Kunci primer yang efisien: IDENTITY menghasilkan kunci berurutan yang terkumpul secara efisien dan menggunakan penyimpanan minimal (4 byte vs 16 byte untuk GUID)

Nota

Contoh ini menggunakan NVARCHAR (2 byte per karakter) untuk dukungan Unicode. Jika data Anda hanya ASCII, VARCHAR (1 byte per karakter) memotong penyimpanan string menjadi dua. ProductName VARCHAR(100) menggunakan ~30 byte vs ~60 byte untuk NVARCHAR(100) pada nama 30 karakter. Pada 10 juta baris, ini menghemat sekitar 300 MB. Gunakan NVARCHAR untuk data internasional; gunakan VARCHAR ketika efisiensi penyimpanan penting dan data akan tetap ascii-saja.

Mendesain praktik terbaik

Terapkan prinsip-prinsip utama ini saat merancang dan mengimplementasikan tabel untuk memastikan performa dan keberlanjutan:

  • Menggunakan jenis data yang sesuai - Jenis data yang lebih kecil mengurangi penyimpanan dan meningkatkan performa
  • Pertimbangkan ukuran tabel lebih awal - Memperkirakan ukuran baris dan ukuran tabel total untuk merencanakan penyimpanan dan pengindeksan
  • Menerapkan batasan yang bermakna - Memastikan kualitas data di tingkat database
  • Rencanakan pertumbuhan - Mendesain tabel untuk menangani volume data di masa mendatang
  • Indeks secara strategis - Kolom indeks yang digunakan dalam WHEREklausa , JOIN, dan ORDER BY
  • Pilih penyimpan kolom untuk analitik - Gunakan indeks penyimpan kolom untuk tabel besar dengan kueri analitik
  • Lakukan normalisasi jika diperlukan - Seimbangkan normalisasi dengan kebutuhan kinerja kueri
  • Pantau kompresi baris dan halaman - Aktifkan kompresi untuk tabel besar untuk menghemat ruang

Sebagian besar masalah performa database berasal dari keputusan desain yang buruk yang dibuat di awal pengembangan. Tipe data berukuran besar memboroskan penyimpanan dan memperlambat kueri. Jenis indeks yang hilang atau salah membuat hambatan yang tidak dapat diatasi oleh peningkatan sumber daya. Cegah masalah ini dengan menginvestasikan waktu dalam desain objek yang tepat sebelum Anda membuat atau mengubah tabel. Keputusan yang Anda buat selama desain—memilih jenis data yang sesuai, memperkirakan ukuran tabel, memilih jenis indeks yang tepat—memiliki efek yang jauh lebih besar pada performa dan biaya jangka panjang daripada pengoptimalan apa pun yang dapat Anda terapkan nanti.