MySQL and MariaDB coding standards, query optimization, indexing, migrations, and security best practices.
JOIN ... ON ...) — never comma-separated joins in FROM.SELECT u.name FROM users AS u.INT UNSIGNED for auto-increment primary keys; prefer BIGINT UNSIGNED for large tables.AUTO_INCREMENT for surrogate primary keys.NOT NULL with a DEFAULT for mandatory columns.deleted_at DATETIME NULL DEFAULT NULLDELETEDATETIME for timestamps (timezone-aware at the application layer); use TIMESTAMP only for auto-managed created_at/updated_at.utf8mb4 charset and utf8mb4_unicode_ci collation for full Unicode support (including emoji).WHERE, JOIN, ORDER BY, and GROUP BY.EXPLAIN to inspect query execution plans before deploying complex queries.-- Soft delete
UPDATE users SET deleted_at = NOW() WHERE id = ?;
-- Always filter in queries
SELECT * FROM users WHERE deleted_at IS NULL;
Always filter WHERE deleted_at IS NULL in application queries.
db:migrate, Flyway, Liquibase, etc.).down steps).SELECT * — name the columns you need.WHERE (prevents index use).LIMIT + OFFSET (or keyset pagination) for large result sets — never fetch all rows and filter in code.EXISTS instead of IN with large subqueries.INSERT ... ON DUPLICATE KEY UPDATE for upsert operations.UPDATE/DELETE operations to avoid long locks:
DELETE FROM logs WHERE created_at < DATE_SUB(NOW(), INTERVAL 90 DAY) LIMIT 1000;
START TRANSACTION / COMMIT / ROLLBACK).READ COMMITTED is usually sufficient; avoid SERIALIZABLE unless required).SELECT, INSERT, UPDATE on specific tables — never SUPER or ALL PRIVILEGES to app users).SHA2 only as a last resort.require_secure_transport (TLS) for remote connections in production.| Object | Convention | Example |
|---|---|---|
| Table | snake_case, plural | user_accounts |
| Column | snake_case | created_at |
| Index | idx_<table>_<columns> | idx_users_email |
| Foreign key | fk_<table>_<ref_table> | fk_posts_users |
| Stored Procedure | sp_<verb>_<noun> | sp_create_user |
| Trigger | trg_<table>_<event> | trg_users_before_insert |
FOR UPDATE SKIP LOCKED (10.6+) for queue-style processing.SEQUENCE objects (MariaDB 10.3+) as an alternative to AUTO_INCREMENT for non-PK sequences.JSON support differs slightly from MySQL 8.x — test JSON functions if migrating.