Mysql Best Practices

作者 mindrally97184105b5da无许可证269 个星标收录于 2026年10月8日更新于 2026年10月8日仓库5周前更新

MySQL development best practices for schema design, query optimization, and database administration

AI 生成的概览

关于 MySQL 架构设计、索引、查询优化、事务、复制、安全与维护的参考指南。

功能
提供 MySQL 开发最佳实践,涵盖存储引擎选择、数据类型、主键、索引策略、使用 EXPLAIN 的查询优化、JSON 支持、事务管理、复制、安全以及日常维护。其中给出 SQL 示例和配置建议,供智能体在数据库相关咨询或审查时参考。该技能仅包含说明,不生成文件或脚本。
适用场景
适用于设计或审查 MySQL 架构、索引或查询,以及就 MySQL 管理、复制、安全加固或配置提供建议的场景。更适合数据库性能与维护类问题,而非一般应用开发。
运行要求
不包含脚本或工具,仅为指导性说明。若要实际运行示例 SQL,需要可访问的 MySQL 服务器和客户端,但阅读说明本身无需任何依赖。

MySQL Best Practices

Core Principles

  • Design schemas with appropriate storage engines (InnoDB for most use cases)
  • Optimize queries using EXPLAIN and proper indexing
  • Use proper data types to minimize storage and improve performance
  • Implement connection pooling and query caching appropriately
  • Follow MySQL-specific security hardening practices

Schema Design

Storage Engine Selection

  • Use InnoDB as the default engine (ACID compliant, row-level locking)
  • Consider MyISAM only for read-heavy, non-transactional workloads
  • Use MEMORY engine for temporary tables with high-speed requirements
sql
CREATE TABLE orders (    order_id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,    customer_id INT UNSIGNED NOT NULL,    order_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,    total_amount DECIMAL(12, 2) NOT NULL,    status ENUM('pending', 'processing', 'shipped', 'delivered', 'cancelled')        NOT NULL DEFAULT 'pending',    INDEX idx_customer (customer_id),    INDEX idx_date_status (order_date, status),    FOREIGN KEY (customer_id) REFERENCES customers(customer_id)        ON DELETE RESTRICT ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Data Types

  • Use smallest data type that fits your needs
  • Prefer INT UNSIGNED over BIGINT when possible
  • Use DECIMAL for financial calculations, not FLOAT/DOUBLE
  • Use ENUM for fixed sets of values
  • Use VARCHAR for variable-length strings, CHAR for fixed-length
  • Always use utf8mb4 charset for full Unicode support
sql
-- Appropriate data type selectionCREATE TABLE products (    product_id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,    sku VARCHAR(50) NOT NULL,    name VARCHAR(255) NOT NULL,    description TEXT,    price DECIMAL(10, 2) NOT NULL,    quantity SMALLINT UNSIGNED NOT NULL DEFAULT 0,    weight DECIMAL(8, 3),    is_active TINYINT(1) NOT NULL DEFAULT 1,    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,    UNIQUE KEY uk_sku (sku)) ENGINE=InnoDB;

Primary Keys

  • Use AUTO_INCREMENT integer primary keys for InnoDB tables
  • Consider UUIDs stored as BINARY(16) for distributed systems
  • Avoid composite primary keys when possible
sql
-- UUID storage optimizationCREATE TABLE distributed_events (    event_id BINARY(16) PRIMARY KEY,    event_type VARCHAR(50) NOT NULL,    payload JSON,    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
-- Insert with UUIDINSERT INTO distributed_events (event_id, event_type, payload)VALUES (UUID_TO_BIN(UUID()), 'user_signup', '{"user_id": 123}');
-- Query with UUIDSELECT * FROM distributed_eventsWHERE event_id = UUID_TO_BIN('550e8400-e29b-41d4-a716-446655440000');

Indexing Strategies

Index Types

  • Use B-tree indexes (default) for most queries
  • Use FULLTEXT indexes for text search
  • Use SPATIAL indexes for geographic data
  • Consider covering indexes for frequently executed queries
sql
-- Composite index for common query patternsCREATE INDEX idx_orders_customer_date ON orders(customer_id, order_date);
-- Covering indexCREATE INDEX idx_orders_covering ON orders(customer_id, order_date, status, total_amount);
-- Fulltext index for searchALTER TABLE products ADD FULLTEXT INDEX ft_name_desc (name, description);
-- Search using fulltextSELECT * FROM productsWHERE MATCH(name, description) AGAINST('wireless bluetooth' IN NATURAL LANGUAGE MODE);

Index Guidelines

  • Index columns used in WHERE, JOIN, ORDER BY, and GROUP BY
  • Place most selective columns first in composite indexes
  • Avoid indexing low-cardinality columns alone
  • Monitor and remove unused indexes
sql
-- Check index usageSELECT    table_schema, table_name, index_name,    seq_in_index, column_name, cardinalityFROM information_schema.STATISTICSWHERE table_schema = 'your_database'ORDER BY table_name, index_name, seq_in_index;

Query Optimization

EXPLAIN Analysis

  • Use EXPLAIN to analyze query execution plans
  • Look for full table scans (type: ALL)
  • Check for proper index usage
  • Monitor rows examined vs rows returned
sql
EXPLAIN FORMAT=JSONSELECT c.name, COUNT(o.order_id) AS order_countFROM customers cLEFT JOIN orders o ON c.customer_id = o.customer_idWHERE c.created_at > '2024-01-01'GROUP BY c.customer_id;

Query Best Practices

  • Avoid SELECT * in production code
  • Use LIMIT for pagination
  • Prefer JOINs over subqueries when possible
  • Use prepared statements for repeated queries
sql
-- Efficient paginationSELECT order_id, order_date, total_amountFROM ordersWHERE customer_id = ?ORDER BY order_date DESCLIMIT 20 OFFSET 0;
-- Keyset pagination (more efficient for large offsets)SELECT order_id, order_date, total_amountFROM ordersWHERE customer_id = ?    AND (order_date, order_id) < (?, ?)ORDER BY order_date DESC, order_id DESCLIMIT 20;

Avoiding Common Pitfalls

sql
-- Avoid: Function on indexed columnSELECT * FROM orders WHERE YEAR(order_date) = 2024;
-- Preferred: Range comparisonSELECT * FROM ordersWHERE order_date >= '2024-01-01' AND order_date < '2025-01-01';
-- Avoid: Implicit type conversionSELECT * FROM users WHERE user_id = '123';  -- user_id is INT
-- Preferred: Proper typesSELECT * FROM users WHERE user_id = 123;
-- Avoid: LIKE with leading wildcardSELECT * FROM products WHERE name LIKE '%phone%';
-- Preferred: Fulltext search for text matchingSELECT * FROM products WHERE MATCH(name) AGAINST('phone');

JSON Support

  • Use JSON data type for semi-structured data (MySQL 5.7+)
  • Create generated columns for frequently accessed JSON fields
  • Use appropriate JSON functions for queries
sql
CREATE TABLE events (    event_id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,    event_type VARCHAR(50) NOT NULL,    payload JSON NOT NULL,    -- Generated column for indexing    user_id INT UNSIGNED AS (payload->>'$.user_id') STORED,    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,    INDEX idx_user_id (user_id));
-- Query JSON dataSELECT event_id, event_type,       JSON_EXTRACT(payload, '$.action') AS actionFROM eventsWHERE JSON_EXTRACT(payload, '$.user_id') = 123;
-- Or using -> operatorSELECT * FROM events WHERE payload->'$.user_id' = 123;

Transaction Management

  • Use InnoDB for transactional tables
  • Keep transactions short to minimize lock contention
  • Choose appropriate isolation level
  • Handle deadlocks gracefully
sql
-- Transaction with error handlingSTART TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
-- Check for errors and commit or rollbackCOMMIT;
-- Set isolation levelSET TRANSACTION ISOLATION LEVEL READ COMMITTED;

Replication and High Availability

Read Replicas

  • Direct read queries to replicas
  • Use connection pooling with read/write splitting
  • Monitor replication lag
sql
-- Check replication statusSHOW SLAVE STATUS\G
-- Check replication lagSELECT TIMESTAMPDIFF(SECOND,    MAX(LAST_APPLIED_TRANSACTION_END_APPLY_TIMESTAMP),    NOW()) AS lag_secondsFROM performance_schema.replication_applier_status_by_worker;

Security

  • Use strong passwords and secure connections (SSL/TLS)
  • Apply principle of least privilege
  • Use prepared statements to prevent SQL injection
  • Audit sensitive operations
sql
-- Create user with limited privilegesCREATE USER 'app_user'@'%' IDENTIFIED BY 'secure_password';GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.* TO 'app_user'@'%';FLUSH PRIVILEGES;
-- Require SSLALTER USER 'app_user'@'%' REQUIRE SSL;
-- View user privilegesSHOW GRANTS FOR 'app_user'@'%';

Maintenance

Regular Maintenance Tasks

sql
-- Analyze tables for optimizer statisticsANALYZE TABLE orders, customers, products;
-- Optimize tables (reclaim space, defragment)OPTIMIZE TABLE orders;
-- Check table integrityCHECK TABLE orders;

Monitoring Queries

sql
-- Find slow queriesSELECT * FROM mysql.slow_log ORDER BY query_time DESC LIMIT 10;
-- Current process listSHOW FULL PROCESSLIST;
-- InnoDB statusSHOW ENGINE INNODB STATUS;
-- Table sizesSELECT    table_name,    ROUND(data_length / 1024 / 1024, 2) AS data_mb,    ROUND(index_length / 1024 / 1024, 2) AS index_mb,    table_rowsFROM information_schema.TABLESWHERE table_schema = 'your_database'ORDER BY data_length DESC;

Configuration Recommendations

ini
# my.cnf recommended settings
[mysqld]# InnoDB settingsinnodb_buffer_pool_size = 70%_of_RAMinnodb_log_file_size = 256Minnodb_flush_log_at_trx_commit = 1innodb_flush_method = O_DIRECT
# Connection settingsmax_connections = 500wait_timeout = 300interactive_timeout = 300
# Query cache (disabled in MySQL 8.0+)query_cache_type = 0
# Slow query logslow_query_log = 1slow_query_log_file = /var/log/mysql/slow.loglong_query_time = 2

来源与署名

来源:mindrally/skills位于mysql-best-practices提交9718410

许可证: 无许可证

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架