mariadb-agents-schema-reviewer
A deterministic procedure for reviewing a MariaDB schema (CREATE TABLE DDL, migration script, or existing schema dump) before it ships. This is an ORCHESTRATION skill : it does not teach syntax, it applies a fixed 10-dimension checklist and produces a graded findings report. Every check cites the canonical skill that explains the underlying rule.
Quick Reference
- Run ALL 10 review dimensions in order. Never skip a dimension because the schema "looks fine".
- Grade every finding with one of three severities : BLOCKER, WARNING, SUGGESTION.
- BLOCKER : the schema must not ship. Examples : MyISAM on a transactional table, a table with no PRIMARY KEY, FLOAT used for a money column.
- WARNING : the schema works but carries a known cost or footgun. Examples : CHAR(36) UUID-text PK on InnoDB,
utf8 (utf8mb3) charset on text columns, a multi-tenant table with no leftmost tenant_id index.
- SUGGESTION : a stylistic or maintainability improvement. Examples : inconsistent naming case, oversized VARCHAR, TEXT where VARCHAR fits.
- Every finding cites the canonical skill that explains the rule. NEVER report a problem without a skill-ref.
- Output a single findings table : dimension, severity, location, problem, fix, skill-ref. Close with a verdict line.
- A clean schema still gets a report : the table has zero rows and the verdict is
PASS.
The 10 Review Dimensions
| # |
Dimension |
What it checks |
Canonical skill |
| 1 |
Storage engine |
InnoDB for transactional tables ; flag MyISAM |
mariadb-core-storage-engines |
| 2 |
Primary key |
every table has a PK ; flag UUID-text PK |
mariadb-impl-schema-design |
| 3 |
Indexing |
composite column-order, redundant indexes, FK indexes |
mariadb-syntax-indexing |
| 4 |
Charset / collation |
utf8mb4 on text columns ; flag utf8 / latin1 |
mariadb-errors-encoding-and-collation |
| 5 |
Normalization |
repeating groups, unjustified denormalization |
mariadb-impl-schema-design |
| 6 |
Multi-tenant |
detect tenant_id ; flag missing leftmost tenant index |
mariadb-impl-schema-design |
| 7 |
Naming |
case consistency, reserved words, Frappe tab pattern |
mariadb-impl-schema-design |
| 8 |
Constraints |
missing CHECK / FK where invariants are implied |
mariadb-syntax-check-constraints |
| 9 |
Data types |
DECIMAL for money, oversized VARCHAR, TEXT misuse |
mariadb-syntax-sql-ddl |
| 10 |
JSON |
JSON column without CHECK (JSON_VALID(col)) |
mariadb-syntax-json |
The full rule set per dimension (IF condition THEN severity) is in references/methods.md.
Review Decision Tree
For each table in the schema :
1. ENGINE clause present ?
absent -> NOTE : engine defaults to InnoDB (acceptable, 10.2+)
MyISAM / MEMORY on a table with FK / transactional intent -> BLOCKER
ARIA on user data -> WARNING
-> ref mariadb-core-storage-engines
2. PRIMARY KEY present ?
absent -> BLOCKER (InnoDB synthesises a hidden 6-byte PK, unindexable)
CHAR(36) / VARCHAR(36) UUID-text PK -> WARNING (use BINARY(16))
-> ref mariadb-impl-schema-design
3. Indexes :
composite index leftmost column not the equality predicate -> WARNING
two indexes where one is a prefix of the other -> SUGGESTION (redundant)
FOREIGN KEY column with no index -> WARNING
-> ref mariadb-syntax-indexing
4. CHARSET on text columns :
utf8 / utf8mb3 -> WARNING (3-byte, no emoji, no full Unicode)
latin1 with no explicit reason -> WARNING
utf8mb4 -> PASS
-> ref mariadb-errors-encoding-and-collation
5. Normalization :
column names like addr1, addr2, addr3 (repeating group) -> WARNING
comma-separated list stored in one column -> WARNING
denormalized copy with no stated reason -> SUGGESTION
-> ref mariadb-impl-schema-design
6. Multi-tenant :
tenant_id / org_id / company column present ?
YES and no index starts with it -> WARNING
YES and PK does not lead with it (for tenant-scoped tables) -> SUGGESTION
-> ref mariadb-impl-schema-design
7. Naming :
mixed case across tables (Users + order_line) -> SUGGESTION
reserved word as identifier without backticks -> BLOCKER
tab<Doctype> prefix -> NOTE : Frappe/ERPNext schema, do not rename
-> ref mariadb-impl-schema-design
8. Constraints :
status / type column with finite value set, no CHECK -> SUGGESTION
child table referencing a parent, no FOREIGN KEY -> WARNING
-> ref mariadb-syntax-check-constraints
9. Data types :
FLOAT / DOUBLE for a money / price / amount column -> BLOCKER
VARCHAR(255) for a country code / boolean flag -> SUGGESTION
TEXT for a column that is always short -> SUGGESTION
-> ref mariadb-syntax-sql-ddl
10. JSON :
JSON column without CHECK (JSON_VALID(col)) -> WARNING
JSON column queried by path with no virtual-column index -> SUGGESTION
-> ref mariadb-syntax-json
JSON Storage Caveat
MariaDB JSON is a LONGTEXT alias, not native binary. Use CHECK (JSON_VALID(col)) for structure ; use functional indexes on virtual columns for index access. A JSON column without that CHECK accepts 'not even json' silently, so dimension 10 grades a missing CHECK as a WARNING, not a SUGGESTION.
Output Format
Always produce a findings table, then a verdict. Severity sort order : BLOCKER first, then WARNING, then SUGGESTION.
## Schema Review : <schema name or "supplied DDL">
| Dimension | Severity | Location | Problem | Fix | Skill ref |
|-----------|----------|----------|---------|-----|-----------|
| Storage engine | BLOCKER | `orders` | ENGINE=MyISAM on a transactional table | ALTER TABLE orders ENGINE=InnoDB | mariadb-core-storage-engines |
| Primary key | WARNING | `users.id` | CHAR(36) UUID-text PK bloats secondary indexes | Use BINARY(16) with UUID_TO_BIN(uuid, 1) | mariadb-impl-schema-design |
| ... | ... | ... | ... | ... | ... |
**Verdict** : FAIL (1 blocker, 1 warning) | Re-review after blockers are fixed.
Verdict rules :
- Any BLOCKER ->
FAIL. The schema must not ship.
- Zero BLOCKER, one or more WARNING ->
PASS WITH WARNINGS. May ship, but warnings carry documented cost.
- Zero BLOCKER and zero WARNING ->
PASS.
Cross-Reference Map
This skill orchestrates and references the following skills. When a finding needs more depth than the fix column allows, point the user at the cited skill :
mariadb-core-storage-engines : engine selection, InnoDB vs MyISAM vs Aria.
mariadb-impl-schema-design : PK strategy, normalization, multi-tenant pattern, naming.
mariadb-syntax-indexing : leftmost-prefix rule, composite column order, FK indexes.
mariadb-errors-encoding-and-collation : utf8mb3 vs utf8mb4, collation pitfalls.
mariadb-syntax-check-constraints : CHECK syntax and JSON_VALID enforcement.
mariadb-syntax-json : JSON-as-LONGTEXT, virtual-column functional indexes.
mariadb-syntax-sql-ddl : column data types, VARCHAR vs TEXT, DECIMAL for money.
When NOT to Use This Skill
- For tuning an individual slow query : use
mariadb-agents-query-optimizer.
- For writing new DDL from scratch : use
mariadb-impl-schema-design and mariadb-syntax-sql-ddl directly.
- This skill reviews structure, not data : it does not inspect row contents or run profiling.
References
references/methods.md : the complete 10-dimension review procedure, each check as a deterministic IF / THEN rule with severity and skill-ref.
references/examples.md : 8 worked reviews including a MyISAM schema, a multi-tenant schema, a Frappe-style schema, a JSON-heavy schema, a clean schema, and a migration DDL.
references/anti-patterns.md : 6 reviewer anti-patterns, why each one ships broken schemas, and the correct procedure.
1---2name: mariadb-agents-schema-reviewer3description: Use when reviewing a proposed MariaDB schema before it ships, auditing an existing schema for engine / indexing / naming / normalization problems, or validating a migration DDL. Prevents the common mistake of shipping a schema with MyISAM tables, UUID-text PKs, missing tenant indexes, utf8 charset, or composite indexes in the wrong column order. Covers a deterministic schema-review checklist : storage-engine choice, primary-key type, indexing strategy and column-order, charset / collation, normalization fitness, multi-tenant pattern detection, naming-convention adherence, with severity grading and cross-references to mariadb-core-storage-engines, mariadb-syntax-indexing, mariadb-impl-schema-design. Keywords: schema review, schema audit, review my schema, is this schema correct, schema checklist, design review, storage engine audit, index audit, primary key audit, normalization check, multi-tenant check, naming convention, DDL review, before I ship this schema, ENGINE=InnoDB, MyISAM, BIGINT AUTO_INCREMENT, UUI4license: MIT5---67# mariadb-agents-schema-reviewer89A deterministic procedure for reviewing a MariaDB schema (CREATE TABLE DDL, migration script, or existing schema dump) before it ships. This is an ORCHESTRATION skill : it does not teach syntax, it applies a fixed 10-dimension checklist and produces a graded findings report. Every check cites the canonical skill that explains the underlying rule.1011## Quick Reference1213- Run ALL 10 review dimensions in order. Never skip a dimension because the schema "looks fine".14- Grade every finding with one of three severities : BLOCKER, WARNING, SUGGESTION.15- **BLOCKER** : the schema must not ship. Examples : MyISAM on a transactional table, a table with no PRIMARY KEY, FLOAT used for a money column.16- **WARNING** : the schema works but carries a known cost or footgun. Examples : CHAR(36) UUID-text PK on InnoDB, `utf8` (utf8mb3) charset on text columns, a multi-tenant table with no leftmost `tenant_id` index.17- **SUGGESTION** : a stylistic or maintainability improvement. Examples : inconsistent naming case, oversized VARCHAR, TEXT where VARCHAR fits.18- Every finding cites the canonical skill that explains the rule. NEVER report a problem without a skill-ref.19- Output a single findings table : dimension, severity, location, problem, fix, skill-ref. Close with a verdict line.20- A clean schema still gets a report : the table has zero rows and the verdict is `PASS`.2122## The 10 Review Dimensions2324| # | Dimension | What it checks | Canonical skill |25|---|-----------|----------------|-----------------|26| 1 | Storage engine | InnoDB for transactional tables ; flag MyISAM | mariadb-core-storage-engines |27| 2 | Primary key | every table has a PK ; flag UUID-text PK | mariadb-impl-schema-design |28| 3 | Indexing | composite column-order, redundant indexes, FK indexes | mariadb-syntax-indexing |29| 4 | Charset / collation | utf8mb4 on text columns ; flag utf8 / latin1 | mariadb-errors-encoding-and-collation |30| 5 | Normalization | repeating groups, unjustified denormalization | mariadb-impl-schema-design |31| 6 | Multi-tenant | detect `tenant_id` ; flag missing leftmost tenant index | mariadb-impl-schema-design |32| 7 | Naming | case consistency, reserved words, Frappe `tab` pattern | mariadb-impl-schema-design |33| 8 | Constraints | missing CHECK / FK where invariants are implied | mariadb-syntax-check-constraints |34| 9 | Data types | DECIMAL for money, oversized VARCHAR, TEXT misuse | mariadb-syntax-sql-ddl |35| 10 | JSON | JSON column without `CHECK (JSON_VALID(col))` | mariadb-syntax-json |3637The full rule set per dimension (IF condition THEN severity) is in `references/methods.md`.3839## Review Decision Tree4041```42For each table in the schema :4344 1. ENGINE clause present ?45 absent -> NOTE : engine defaults to InnoDB (acceptable, 10.2+)46 MyISAM / MEMORY on a table with FK / transactional intent -> BLOCKER47 ARIA on user data -> WARNING48 -> ref mariadb-core-storage-engines4950 2. PRIMARY KEY present ?51 absent -> BLOCKER (InnoDB synthesises a hidden 6-byte PK, unindexable)52 CHAR(36) / VARCHAR(36) UUID-text PK -> WARNING (use BINARY(16))53 -> ref mariadb-impl-schema-design5455 3. Indexes :56 composite index leftmost column not the equality predicate -> WARNING57 two indexes where one is a prefix of the other -> SUGGESTION (redundant)58 FOREIGN KEY column with no index -> WARNING59 -> ref mariadb-syntax-indexing6061 4. CHARSET on text columns :62 utf8 / utf8mb3 -> WARNING (3-byte, no emoji, no full Unicode)63 latin1 with no explicit reason -> WARNING64 utf8mb4 -> PASS65 -> ref mariadb-errors-encoding-and-collation6667 5. Normalization :68 column names like addr1, addr2, addr3 (repeating group) -> WARNING69 comma-separated list stored in one column -> WARNING70 denormalized copy with no stated reason -> SUGGESTION71 -> ref mariadb-impl-schema-design7273 6. Multi-tenant :74 tenant_id / org_id / company column present ?75 YES and no index starts with it -> WARNING76 YES and PK does not lead with it (for tenant-scoped tables) -> SUGGESTION77 -> ref mariadb-impl-schema-design7879 7. Naming :80 mixed case across tables (Users + order_line) -> SUGGESTION81 reserved word as identifier without backticks -> BLOCKER82 tab<Doctype> prefix -> NOTE : Frappe/ERPNext schema, do not rename83 -> ref mariadb-impl-schema-design8485 8. Constraints :86 status / type column with finite value set, no CHECK -> SUGGESTION87 child table referencing a parent, no FOREIGN KEY -> WARNING88 -> ref mariadb-syntax-check-constraints8990 9. Data types :91 FLOAT / DOUBLE for a money / price / amount column -> BLOCKER92 VARCHAR(255) for a country code / boolean flag -> SUGGESTION93 TEXT for a column that is always short -> SUGGESTION94 -> ref mariadb-syntax-sql-ddl9596 10. JSON :97 JSON column without CHECK (JSON_VALID(col)) -> WARNING98 JSON column queried by path with no virtual-column index -> SUGGESTION99 -> ref mariadb-syntax-json100```101102## JSON Storage Caveat103104MariaDB JSON is a LONGTEXT alias, not native binary. Use `CHECK (JSON_VALID(col))` for structure ; use functional indexes on virtual columns for index access. A JSON column without that CHECK accepts `'not even json'` silently, so dimension 10 grades a missing CHECK as a WARNING, not a SUGGESTION.105106## Output Format107108Always produce a findings table, then a verdict. Severity sort order : BLOCKER first, then WARNING, then SUGGESTION.109110```111## Schema Review : <schema name or "supplied DDL">112113| Dimension | Severity | Location | Problem | Fix | Skill ref |114|-----------|----------|----------|---------|-----|-----------|115| Storage engine | BLOCKER | `orders` | ENGINE=MyISAM on a transactional table | ALTER TABLE orders ENGINE=InnoDB | mariadb-core-storage-engines |116| Primary key | WARNING | `users.id` | CHAR(36) UUID-text PK bloats secondary indexes | Use BINARY(16) with UUID_TO_BIN(uuid, 1) | mariadb-impl-schema-design |117| ... | ... | ... | ... | ... | ... |118119**Verdict** : FAIL (1 blocker, 1 warning) | Re-review after blockers are fixed.120```121122Verdict rules :123- Any BLOCKER -> `FAIL`. The schema must not ship.124- Zero BLOCKER, one or more WARNING -> `PASS WITH WARNINGS`. May ship, but warnings carry documented cost.125- Zero BLOCKER and zero WARNING -> `PASS`.126127## Cross-Reference Map128129This skill orchestrates and references the following skills. When a finding needs more depth than the fix column allows, point the user at the cited skill :130131- `mariadb-core-storage-engines` : engine selection, InnoDB vs MyISAM vs Aria.132- `mariadb-impl-schema-design` : PK strategy, normalization, multi-tenant pattern, naming.133- `mariadb-syntax-indexing` : leftmost-prefix rule, composite column order, FK indexes.134- `mariadb-errors-encoding-and-collation` : utf8mb3 vs utf8mb4, collation pitfalls.135- `mariadb-syntax-check-constraints` : CHECK syntax and JSON_VALID enforcement.136- `mariadb-syntax-json` : JSON-as-LONGTEXT, virtual-column functional indexes.137- `mariadb-syntax-sql-ddl` : column data types, VARCHAR vs TEXT, DECIMAL for money.138139## When NOT to Use This Skill140141- For tuning an individual slow query : use `mariadb-agents-query-optimizer`.142- For writing new DDL from scratch : use `mariadb-impl-schema-design` and `mariadb-syntax-sql-ddl` directly.143- This skill reviews structure, not data : it does not inspect row contents or run profiling.144145## References146147- `references/methods.md` : the complete 10-dimension review procedure, each check as a deterministic IF / THEN rule with severity and skill-ref.148- `references/examples.md` : 8 worked reviews including a MyISAM schema, a multi-tenant schema, a Frappe-style schema, a JSON-heavy schema, a clean schema, and a migration DDL.149- `references/anti-patterns.md` : 6 reviewer anti-patterns, why each one ships broken schemas, and the correct procedure.