openclaw/skills/tidb-sql/references/mysql-compatibility-notes.md

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).