✅ 1. In MySQL (InnoDB)
🔹 By default:
- The primary key becomes the clustered index.
- If no primary key is defined, InnoDB picks:
- the first unique NOT NULL index, or
- creates a hidden
row_id.
🔹 To define your own clustered index:
You just declare a primary key, and it becomes clustered:
CREATE TABLE Users (
user_id INT NOT NULL,
name VARCHAR(100),
email VARCHAR(100),
PRIMARY KEY (user_id) -- this is the clustered index
);
To use a different column:
CREATE TABLE Orders (
order_number INT,
customer_id INT,
order_date DATE,
PRIMARY KEY (order_date, order_number) -- clustered index on (order_date, order_number)
);
🧠 MySQL does not let you create a clustered index directly by name — it’s always tied to the primary key in InnoDB.
✅ 2. In SQL Server
Here you have full control and can explicitly create a clustered index:
CREATE CLUSTERED INDEX idx_order_date
ON Orders(order_date);
You can also specify it during table creation:
CREATE TABLE Products (
product_id INT,
name VARCHAR(100),
price DECIMAL(10, 2),
CONSTRAINT pk_product PRIMARY KEY CLUSTERED (product_id)
);
✅ 3. In PostgreSQL
PostgreSQL does not support true clustered indexes — but it allows clustering once, and you must re-cluster manually when data changes.
CREATE INDEX idx_order_date ON Orders(order_date);
CLUSTER Orders USING idx_order_date;
⚠️ PostgreSQL won’t maintain the clustering automatically.
🧠 Summary Table
| DBMS | Clustered Index Defined By |
|---|---|
| MySQL | Automatically via primary key (InnoDB) |
| SQL Server | Explicit with CREATE CLUSTERED INDEX |
| PostgreSQL | Not automatic; use CLUSTER manually |
🔑 In simple terms:
A clustered index determines the default physical order of rows in the table — the table is stored on disk sorted by this index.
So yes:
- When you define a clustered index, the table rows are physically arranged in that order.
- It’s like saying: “This is the natural sort order of the table.”
📌 Key Points Recap:
| Concept | Description |
|---|---|
| 📚 Clustered Index | Defines the physical order of rows in the table |
| 📦 Table = Index | The data is stored within the index itself (not separate) |
| 🧱 Only One Per Table | Because you can’t store the rows in multiple physical orders |
| ⚡ Fast for Range Queries | Since rows are already sorted, range scans (BETWEEN, <, >) are efficient |