100 lines
5.0 KiB
Markdown
100 lines
5.0 KiB
Markdown
---
|
|
title: MySQL to TiDB SQL Compatibility Notes (Common Breaks)
|
|
---
|
|
|
|
# MySQL to TiDB SQL Compatibility Notes (Common Breaks)
|
|
|
|
Use this as a quick "lint list" when adapting MySQL SQL to TiDB.
|
|
|
|
## Detect TiDB vs MySQL quickly
|
|
|
|
```sql
|
|
SELECT VERSION();
|
|
```
|
|
|
|
If the returned string contains `TiDB`, you are connected to TiDB and can infer the TiDB version from that string.
|
|
|
|
## Unsupported or commonly unavailable features (avoid generating by default)
|
|
|
|
Always confirm your TiDB version and deployment (TiDB Cloud tier/region vs self-managed) before relying on borderline features.
|
|
|
|
- Stored procedures and stored functions
|
|
- Triggers
|
|
- Events (event scheduler)
|
|
- User-defined functions (UDF)
|
|
- `SPATIAL` / `GEOMETRY` functions, data types, and indexes
|
|
- XML functions
|
|
- `XA` syntax (TiDB uses 2PC internally but does not expose XA over SQL)
|
|
- `CREATE TABLE ... AS SELECT ...` (CTAS)
|
|
- `CHECK TABLE`, `CHECKSUM TABLE`, `REPAIR TABLE`, `OPTIMIZE TABLE`
|
|
- `HANDLER`, `CREATE TABLESPACE`
|
|
- Some advanced query syntaxes might be unsupported depending on TiDB version (examples seen in TiDB docs include `SKIP LOCKED`, lateral derived tables, and `JOIN ... ON (subquery)` patterns)
|
|
|
|
## FULLTEXT: clarify intent
|
|
|
|
- Do not assume MySQL `FULLTEXT` indexes work everywhere on TiDB.
|
|
- If the user needs keyword search, prefer TiDB full-text search when their deployment supports it (see `skills/tidb-sql/references/full-text-search.md`).
|
|
|
|
## Views
|
|
|
|
- Views are not updatable: do not emit `UPDATE/INSERT/DELETE` against views.
|
|
|
|
## SELECT syntax edge cases
|
|
|
|
- Do not emit `SELECT ... INTO @variable` (unsupported).
|
|
- In TiDB, `SELECT ... GROUP BY expr` does not imply `ORDER BY expr` (MySQL 5.7 behavior differs). If ordering matters, add an explicit `ORDER BY`.
|
|
|
|
## Built-in functions (be defensive)
|
|
|
|
- TiDB supports most MySQL built-ins, but not all. When porting SQL that uses non-trivial built-ins, validate availability with:
|
|
|
|
```sql
|
|
SHOW BUILTINS;
|
|
```
|
|
|
|
## Charset/collation pitfalls
|
|
|
|
- TiDB supports a limited set of character sets. If you see errors around charset/collation, stick to commonly supported sets like `utf8mb4` (and avoid exotic charsets).
|
|
- Default charset/collation can differ from MySQL: TiDB defaults are typically `utf8mb4` and `utf8mb4_bin`. If you depend on case-insensitive comparisons, set the collation explicitly.
|
|
|
|
## Name casing pitfalls
|
|
|
|
- TiDB supports `lower_case_table_names = 2` only (case-insensitive lookup behavior). Do not rely on two objects whose names differ only by letter case.
|
|
|
|
## AUTO_INCREMENT pitfalls (and why AUTO_RANDOM is common on TiDB)
|
|
|
|
- AUTO_INCREMENT IDs are globally unique in TiDB, but not necessarily sequential across nodes. Avoid mixing implicit IDs with custom explicit values.
|
|
- Removing `AUTO_INCREMENT` is possible (guarded by `tidb_allow_remove_auto_inc`), but adding it later is not supported.
|
|
- If you do not define a primary key, TiDB uses `_tidb_rowid`. Its allocator can interact with AUTO_INCREMENT in ways that surprise MySQL users.
|
|
- If you are designing a write-heavy schema, prefer `AUTO_RANDOM` for BIGINT PKs when it fits (see `skills/tidb-sql/references/auto-random.md`).
|
|
|
|
## DDL / schema changes (be conservative, TiDB has extra restrictions)
|
|
|
|
- Avoid "multi-change" `ALTER TABLE` that references the same column/index more than once in one statement.
|
|
- Avoid packing multiple TiDB-specific schema changes into one `ALTER TABLE` when possible (split them).
|
|
- Not all type changes are supported via `ALTER TABLE` (for unsupported changes, plan a backfill/migration).
|
|
- `ALGORITHM={INSTANT,INPLACE,COPY}` is treated as an assertion, not as an algorithm selector.
|
|
- Adding/dropping a clustered primary key can be unsupported; in practice, treat PK changes as "new table + backfill + swap".
|
|
- Index type decorations like `USING HASH|BTREE|RTREE|FULLTEXT` can be parsed but ignored. Do not rely on them to change behavior.
|
|
|
|
## Partitioning notes (avoid fancy operations unless you know TiDB supports them)
|
|
|
|
- Supported partitioning types include `HASH`, `RANGE`, `LIST`, and `KEY`.
|
|
- Some partition DDL operations are ignored, and `SUBPARTITION` is not supported. If you need advanced partition DDL, confirm support on your TiDB version first.
|
|
|
|
## Optimizer / plan differences
|
|
|
|
- `optimizer_switch` is read-only and does not affect TiDB plans.
|
|
- Optimizer hints are not a drop-in replacement for MySQL hints. Use `EXPLAIN` on TiDB to validate critical queries.
|
|
- For structured plans, use `EXPLAIN FORMAT = "tidb_json"` (see `skills/tidb-sql/references/explain.md`).
|
|
|
|
## Timezone and timestamp defaults
|
|
|
|
- TiDB supports named timezones based on system timezone rules; MySQL often requires timezone tables for named timezones.
|
|
- TiDB only supports `explicit_defaults_for_timestamp = ON`. If you are porting MySQL 5.7-era SQL that relies on implicit TIMESTAMP defaults, test carefully and set defaults explicitly.
|
|
|
|
## Deprecated MySQL features you should avoid porting
|
|
|
|
- Floating-point type precision specifiers (prefer `DECIMAL` when you need fixed precision).
|
|
- `ZEROFILL` (pad in the application layer instead).
|