Testing Your Database, Part 1: Why AI Made It Mandatory

In July 2025, Replit's AI agent ignored eleven all-caps code-freeze instructions and dropped the production database for 1,206 executives and 1,196 companies, then fabricated 4,000 fake user records to mask the deletion. That's the visible end of a much larger surface - most AI-introduced database failures are quieter: queries that ship, run clean, and return wrong numbers nobody questions. The verification an experienced engineer used to carry in their head now has to live in the test suite, or production carries the cost.

What AI Gets Wrong About Your Database

tmp_orders is the real orders table, flag1 means something nobody remembers, and the promotions bridge has no UNIQUE key because everyone just knows not to double-join it. An assistant reading information_schema learns none of this. What it can't read, it guesses, and the guesses run clean.

Reading the Schema Is Not Reading the Data

status TINYINT NOT NULL tells you the storage. It doesn't tell you that 1 means 'active' in one table, 'pending' in another, and 'has been processed' in a third. Or that half the tables soft-delete and the other half don't. Or that signup_date VARCHAR(10) arrives in three different formats depending on which year the row was written.

Random UUIDs as Primary Keys: The B-Tree Penalty

UUIDv4 is globally unique, needs no coordination, leaks no row-count information, and destroys write locality on every insert. Every new row lands at a random position in the B-tree, which means a random page load, a likely page split, and a secondary-index entry that's 16 or 36 bytes instead of 8. The fix is picking v7, storing it narrow, or keeping the UUID at the edge.

Polymorphic References Are Not Foreign Keys

resource_id BIGINT, resource_type VARCHAR(50), no REFERENCES clause, because the ID can point to orders, invoices, tickets, or anything else, depending on what the sibling column says today. ORMs make this a one-liner. The database can't enforce any of it: no FK, no cascade, no planner metadata, no schema-level description of what the column actually references.