drizzle-team / drizzle-team/drizzle-orm
[FEATURE]: Support specifying index type (USING BTREE/HASH) in MySQL schema definitions for drizzle-kit migrations
- Dominant language
- TypeScript
- Stars
- 35.8k
- Forks
- 1.6k
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 4
Description
## Feature Request
Currently, Drizzle ORM's runtime API supports `.using("btree")` for MySQL indexes (as documented), but drizzle-kit does not generate the explicit `USING BTREE` clause in migration SQL files, even when specified in the schema.
## Problem
When introspecting existing MySQL databases or comparing schema dumps, the generated Drizzle migrations omit the `USING BTREE` clause, causing schema differences even though the behavior is functionally equivalent.
### Examples
**Regular Index:**
Original schema:
```sql
CREATE TABLE `account_statement` (
`id` bigint NOT NULL AUTO_INCREMENT,
`accounting_date` varchar(8) NOT NULL,
PRIMARY KEY (`id`),
KEY `accounting_date_INDEX` (`accounting_date`) USING BTREE
);
```
Drizzle schema (current):
```typescript
index("accounting_date_INDEX").on(table.accountingDate)
```
Generated by drizzle-kit:
```sql
KEY `accounting_date_INDEX` (`accounting_date`)
-- Missing: USING BTREE
```
**Unique Constraint:**
Original schema:
```sql
CREATE TABLE `company_manager` (
`id` int NOT NULL AUTO_INCREMENT,
`code` varchar(3) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `company_manager_code_unique` (`code`) USING BTREE
);
```
Drizzle schema (current):
```typescript
unique("company_manager_code_unique").on(table.code)
```
Generated by drizzle-kit:
```sql
UNIQUE KEY `company_manager_code_unique` (`code`)
-- Missing: USING BTREE
```
## Use Cases
1. **Schema Parity**: Developers want schema dumps to match existing databases exactly for documentation, auditing, or compliance purposes
2. **Non-InnoDB Engines**: MEMORY tables require `USING HASH` or other index types
3. **Schema Diff Tools**: Teams using schema comparison tools that flag missing `USING BTREE` clauses as differences
4. **Migration Accuracy**: Ensuring generated migrations match the source schema precisely
## Current State
According to the [official documentation](https://orm.drizzle.team/docs/indexes-constraints#indexes), Drizzle ORM provides the following API for MySQL:
```typescript
index("name")
.on(table.name)
.algorithm("default") // "default" | "copy" | "inplace"
.using("btree") // "btree" | "hash"
.lock("default") // "none" | "default" | "exclusive" | "shared"
```
However:
- The runtime API supports `.using("btree")`
- drizzle-kit does **not** generate the `USING` clause in migration SQL files
- This affects both regular indexes (`index()`) and unique constraints (`unique()` / `uniqueIndex()`)
## Suggested Enhancement
Support the existing `.using()` method in drizzle-kit migrations:
```typescript
// For regular indexes
index("accounting_date_INDEX")
.on(table.accountingDate)
.using("btree")
// For unique indexes
uniqueIndex("email_idx")
.on(table.email)
.using("btree")
```
This should generate:
```sql
KEY `accounting_date_INDEX` (`accounting_date`) USING BTREE
CREATE UNIQUE INDEX `email_idx` ON `user` (`email`) USING BTREE
```
**Note**: The `unique()` constraint function may also need similar support, or we should use `uniqueIndex()` instead when index type specification is needed.
## Expected Result
- Developers can use the existing `.using("btree")` API in schema definitions
- drizzle-kit generates migrations with `USING BTREE` (or `USING HASH`) clauses when `.using()` is specified
- Better DDL parity between source databases and generated migrations
- Support for non-default index types (e.g., HASH for MEMORY tables)
## Notes
While BTREE is the default for InnoDB and functionally equivalent, explicit specification is valuable for:
- Exact schema matching
- Documentation accuracy
- Schema comparison tools
- Non-InnoDB storage engines
Contributor guide
Assessment
This issue has not been assessed yet.