1. 为什么选择MariaDB/MySQL作为你的第一个数据库
在数据驱动的时代,数据库已经成为开发者必备的核心技能。作为关系型数据库的代表,MySQL和它的分支MariaDB凭借其开源、高性能和易用性,成为了全球最受欢迎的数据库系统之一。我第一次接触MySQL是在2008年,当时为了搭建一个简单的博客系统,从此便与数据库结下了不解之缘。
MySQL由瑞典公司MySQL AB开发,后被Sun公司收购,最终归于Oracle旗下。而MariaDB则是MySQL创始人Michael Widenius在Oracle收购Sun后,因担心MySQL的未来而创建的分支项目。两者在语法和功能上高度兼容,但MariaDB在性能优化和新特性引入上更为激进。
提示:对于新项目,我个人更推荐使用MariaDB,它完全兼容MySQL,同时提供了更好的性能和更多创新功能,而且避免了Oracle可能带来的商业风险。
2. 环境准备与安装指南
2.1 选择适合你的安装方式
在Ubuntu系统上安装MariaDB/MySQL有多种方式,每种方式适合不同的使用场景:
使用系统包管理器安装(最简单):
sudo apt update sudo apt install mariadb-server这种方式安装的是系统仓库中的稳定版本,适合大多数生产环境。
源码编译安装(最灵活):
wget https://downloads.mariadb.org/interstitial/mariadb-10.6.7/source/mariadb-10.6.7.tar.gz tar -xvzf mariadb-10.6.7.tar.gz cd mariadb-10.6.7/ cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mariadb make && sudo make install源码安装可以自定义编译选项,获得最佳性能,但过程较为复杂,适合高级用户。
使用官方仓库安装(获取最新版本):
sudo apt-get install software-properties-common sudo apt-key adv --fetch-keys 'https://mariadb.org/mariadb_release_signing_key.asc' sudo add-apt-repository 'deb [arch=amd64,arm64,ppc64el] https://mirrors.aliyun.com/mariadb/repo/10.6/ubuntu focal main' sudo apt update sudo apt install mariadb-server
2.2 安装后的基本配置
安装完成后,首次使用前必须运行安全脚本:
sudo mysql_secure_installation这个脚本会引导你完成以下设置:
- 设置root密码(生产环境必须设置强密码)
- 移除匿名用户(提高安全性)
- 禁止root远程登录(防止暴力破解)
- 移除测试数据库(减少攻击面)
- 重新加载权限表(使更改立即生效)
注意:在Ubuntu系统中,默认情况下MariaDB使用UNIX auth_socket插件认证root用户,这意味着你可以直接使用
sudo mysql登录而无需密码。这在开发环境中很方便,但在生产环境中应该禁用。
3. 数据库基础操作实战
3.1 连接数据库的多种方式
命令行客户端(最常用):
mysql -u username -p输入密码后即可进入交互式环境。
使用管理员权限登录(无需密码):
sudo mysql指定主机和端口连接远程数据库:
mysql -h hostname -P 3306 -u username -p
3.2 数据库和表的创建与管理
创建你的第一个数据库:
CREATE DATABASE my_first_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;选择使用该数据库:
USE my_first_db;创建第一个表(用户表):
CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, email VARCHAR(100) NOT NULL UNIQUE, password_hash CHAR(60) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) ENGINE=InnoDB;查看表结构:
DESCRIBE users;3.3 基本CRUD操作
插入数据:
INSERT INTO users (username, email, password_hash) VALUES ('john_doe', 'john@example.com', '$2y$10$N9qo8uLOickgx2ZMRZoMy.MQRqQz6W6NA');查询数据:
-- 查询所有用户 SELECT * FROM users; -- 条件查询 SELECT username, email FROM users WHERE id = 1; -- 分页查询 SELECT * FROM users ORDER BY created_at DESC LIMIT 10 OFFSET 0;更新数据:
UPDATE users SET email = 'new_email@example.com' WHERE id = 1;删除数据:
DELETE FROM users WHERE id = 1;4. 高级功能与性能优化
4.1 存储过程与函数
存储过程是预编译的SQL语句集合,可以提高性能并减少网络传输:
创建简单的存储过程:
DELIMITER // CREATE PROCEDURE get_user_by_id(IN user_id INT) BEGIN SELECT * FROM users WHERE id = user_id; END // DELIMITER ;调用存储过程:
CALL get_user_by_id(1);创建函数(计算用户年龄):
DELIMITER // CREATE FUNCTION calculate_age(birth_date DATE) RETURNS INT DETERMINISTIC BEGIN RETURN TIMESTAMPDIFF(YEAR, birth_date, CURDATE()); END // DELIMITER ;使用函数:
SELECT username, calculate_age(birth_date) AS age FROM users;4.2 索引优化实战
没有索引的数据库就像没有目录的书籍。为users表添加索引:
-- 单列索引 CREATE INDEX idx_username ON users(username); -- 复合索引(常用于多条件查询) CREATE INDEX idx_email_status ON users(email, status); -- 查看表索引 SHOW INDEX FROM users;经验分享:我曾经优化过一个查询,从5秒降到0.01秒,仅仅是因为添加了正确的复合索引。记住:索引不是越多越好,每个索引都会增加写入开销。只为高频查询条件创建索引。
4.3 事务处理与ACID特性
事务是数据库操作的逻辑单元,具有原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability):
START TRANSACTION; -- 转账操作:从A账户扣除,向B账户增加 UPDATE accounts SET balance = balance - 100 WHERE user_id = 1; UPDATE accounts SET balance = balance + 100 WHERE user_id = 2; -- 如果执行到这里没有问题 COMMIT; -- 如果出现错误 -- ROLLBACK;5. 安全与备份策略
5.1 用户权限管理
永远不要使用root账户进行日常操作!创建专用用户并授予最小必要权限:
-- 创建只读用户 CREATE USER 'report_user'@'localhost' IDENTIFIED BY 'strong_password'; GRANT SELECT ON my_first_db.* TO 'report_user'@'localhost'; -- 创建应用用户(只有特定表的CRUD权限) CREATE USER 'app_user'@'%' IDENTIFIED BY 'another_strong_password'; GRANT SELECT, INSERT, UPDATE, DELETE ON my_first_db.users TO 'app_user'@'%'; GRANT SELECT ON my_first_db.products TO 'app_user'@'%'; -- 刷新权限 FLUSH PRIVILEGES;查看用户权限:
SHOW GRANTS FOR 'app_user'@'%';5.2 数据库备份与恢复
使用mysqldump进行逻辑备份:
# 备份整个数据库 mysqldump -u root -p --single-transaction --routines --triggers my_first_db > backup.sql # 仅备份结构 mysqldump -u root -p --no-data my_first_db > schema.sql # 仅备份数据 mysqldump -u root -p --no-create-info my_first_db > data.sql恢复数据库:
mysql -u root -p my_first_db < backup.sql二进制日志增量备份:
-- 查看当前二进制日志状态 SHOW MASTER STATUS; -- 在备份后刷新日志 FLUSH LOGS;灾难恢复经验:曾经因为硬盘故障丢失了生产数据库,幸好有完整的备份策略:每日全备+二进制日志增量备份。最终只丢失了不到1分钟的数据。记住:没有备份的数据库就像走钢丝没有安全网。
6. MySQL与MariaDB的选择与对比
6.1 技术特性对比
| 特性 | MySQL 8.0 | MariaDB 10.6 |
|---|---|---|
| 默认存储引擎 | InnoDB | InnoDB |
| 窗口函数 | 支持 | 支持 |
| JSON支持 | 完善 | 完善 |
| 并行复制 | 支持 | 支持更好 |
| 线程池 | 企业版支持 | 社区版支持 |
| 动态列 | 不支持 | 支持 |
| 存储引擎可插拔性 | 一般 | 更强 |
| 社区活跃度 | 由Oracle主导 | 完全开源社区驱动 |
6.2 迁移注意事项
从MySQL迁移到MariaDB通常很平滑,因为MariaDB设计为二进制兼容。但需要注意:
- 某些MySQL特有功能可能在MariaDB中表现不同
- 企业版特有的功能在MariaDB社区版中不可用
- 使用
mysql_upgrade工具升级系统表
迁移步骤:
# 1. 备份MySQL数据库 mysqldump --all-databases > full_backup.sql # 2. 卸载MySQL sudo apt remove --purge mysql-server mysql-client # 3. 安装MariaDB sudo apt install mariadb-server # 4. 恢复数据 mysql < full_backup.sql # 5. 运行升级工具 sudo mysql_upgrade7. 常见问题排查与性能调优
7.1 慢查询分析与优化
启用慢查询日志:
SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 1; -- 超过1秒的查询 SET GLOBAL slow_query_log_file = '/var/log/mysql/mariadb-slow.log';分析慢查询日志:
mysqldumpslow -s t /var/log/mysql/mariadb-slow.log使用EXPLAIN分析查询:
EXPLAIN SELECT * FROM users WHERE username LIKE 'john%';关键指标解读:
- type: 最好到最差依次为 system > const > eq_ref > ref > range > index > ALL
- possible_keys: 可能使用的索引
- key: 实际使用的索引
- rows: 预估需要检查的行数
7.2 连接数问题排查
查看当前连接状态:
SHOW STATUS LIKE 'Threads_connected'; SHOW PROCESSLIST;调整最大连接数(在/etc/mysql/mariadb.conf.d/50-server.cnf中):
[mysqld] max_connections = 200实战技巧:当遇到"Too many connections"错误时,可以临时增加连接数(无需重启):
SET GLOBAL max_connections = 300;但这只是临时解决方案,应该找出连接泄漏的根本原因。
8. 生产环境最佳实践
8.1 配置优化建议
关键配置参数(根据服务器内存调整):
[mysqld] innodb_buffer_pool_size = 4G # 通常分配70-80%的可用内存 innodb_log_file_size = 256M innodb_flush_log_at_trx_commit = 1 # 保证持久性,对性能有影响 sync_binlog = 1 query_cache_type = 0 # MySQL 8+已移除查询缓存 table_open_cache = 40008.2 监控与维护
常用监控命令:
-- 查看运行状态 SHOW ENGINE INNODB STATUS; -- 查看变量设置 SHOW VARIABLES LIKE '%buffer%'; -- 查看表空间使用情况 SELECT table_schema "Database", ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) "Size (MB)" FROM information_schema.tables GROUP BY table_schema;定期维护任务:
- 每周检查并优化碎片化严重的表
OPTIMIZE TABLE large_table; - 每月备份并验证备份完整性
- 监控磁盘空间使用情况
- 定期检查错误日志
sudo tail -f /var/log/mysql/error.log
8.3 高可用方案
主从复制:
-- 在主服务器上 CREATE USER 'replica_user'@'%' IDENTIFIED BY 'password'; GRANT REPLICATION SLAVE ON *.* TO 'replica_user'@'%'; SHOW MASTER STATUS; -- 在从服务器上 CHANGE MASTER TO MASTER_HOST='master_ip', MASTER_USER='replica_user', MASTER_PASSWORD='password', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=123456; START SLAVE;Galera集群(MariaDB特有):
- 提供真正的多主同步复制
- 自动成员控制
- 自动故障转移
- 需要至少3个节点以获得最佳效果
使用ProxySQL实现读写分离:
- 将读操作分发到从服务器
- 写操作发送到主服务器
- 自动故障检测和切换
在实际项目中,我通常会根据业务需求选择不同的方案。对于关键业务系统,Galera集群提供了很好的高可用性;而对于读多写少的应用,主从复制+ProxySQL的组合既经济又高效。