MySQL报错"Table 'xxx' doesn't exist"解决

前言

查询数据库时报错:Table 'xxx' doesn't exist,明明表就在那,为什么说不存在?本文排查常见原因。

报错长什么样

SELECT * FROM users;

报错:

ERROR 1146 (42S02): Table 'mydb.users' doesn't exist

常见原因

原因1:数据库选错了

当前在别的库里,所以找不到表。

排查: 先看当前在哪个库:

SELECT DATABASE();

如果显示的不是你要的库,就切换:

USE mydb;

再查一次。

原因2:表名写错了

拼错了,或者大小写不对。

排查: 看看库里到底有哪些表:

SHOW TABLES;

确认表名是不是和你写的一模一样。

注意: Linux下MySQL表名区分大小写,Users 和 users 是两个表。

原因3:表真的被删了

表确实不存在了,可能被误删了。

排查: 用SHOW TABLES确认。如果真没有,从备份恢复。

原因4:字符集导致的问题

表名里有特殊字符,编码不对导致识别不出来。

排查: 用 SHOW TABLES LIKE 'xxx%'; 模糊匹配一下。

原因5:MySQL升级后表损坏

升级MySQL后,某些表报错不存在,但文件还在。

原因: 表引擎损坏,或者frm文件丢了。

排查: 看数据目录下有没有对应文件:

ls /var/lib/mysql/mydb/

原因6:用户没有权限

虽然报错是"不存在",但有时候权限不够也会这么报。

排查: 用root用户登录试试,如果root能看到,就是权限问题。

排查步骤

第一步:确认当前数据库

SELECT DATABASE();

第二步:查看所有表

SHOW TABLES;

第三步:模糊搜索表名

SHOW TABLES LIKE '%user%';

第四步:确认表文件是否存在

ls /var/lib/mysql/你的库名/ | grep 表名

常见坑

坑1:Linux下表名区分大小写

Windows开发没问题,上传到Linux服务器就报错。

解决: 表名统一用小写,或者在my.cnf加:

lower_case_table_names = 1

注意: 这个参数只能在初始化MySQL前设置,已经用了再改会出问题。

坑2:分表了忘了加表名

用了分表,代码里查的是 users,实际表名是 users_0、users_1。

解决: 确认分表规则,代码里拼对表名。

坑3:视图报错

查视图时报"表不存在",可能是视图依赖的表被删了。

排查: 看视图定义:

SHOW CREATE VIEW 视图名;

坑4:临时表

会话结束临时表就没了,新开一个连接查就报错。

解决: 临时表只在当前会话有效,别跨连接用。

坑5:误删了库

整个库都没了,当然找不到表。

排查:

SHOW DATABASES;

看你的库还在不在。

总结

排查顺序:

  1. 先看当前在哪个库
  2. 再SHOW TABLES看表在不在
  3. 确认表名大小写对不对
  4. 最后看数据目录下文件在不在

记住: 90%的情况都是库选错了或者表名写错了。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-8 07:41 

MySQL查看表结构,desc和show create table

前言

接手别人的项目,不知道表有哪些字段、什么类型、有没有索引,全靠DESC和SHOW CREATE TABLE。

一、查看表有哪些字段

方法1:DESC(最常用)

DESC users;

或者:

DESCRIBE users;

输出:

Field Type Null Key Default Extra
id int(11) NO PRI NULL auto_increment
name varchar(50) YES NULL
age int(11) YES NULL

每列含义:

  • Field:字段名
  • Type:字段类型
  • Null:能不能为NULL
  • Key:有没有索引
  • Default:默认值
  • Extra:额外属性(自增等)

方法2:SHOW COLUMNS

SHOW COLUMNS FROM users;

和DESC效果一样,写法不同而已。

二、查看建表语句

SHOW CREATE TABLE

SHOW CREATE TABLE users;

输出:

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

这个命令能看到:

  • 完整的建表SQL
  • 所有字段和类型
  • 主键、索引
  • 表引擎、字符集
  • 默认值、自增等

三、查看表状态

SHOW TABLE STATUS LIKE 'users'\G

能看到:

  • 表行数
  • 数据大小
  • 索引大小
  • 更新时间
  • 引擎类型
  • 字符集

四、查看表的所有索引

SHOW INDEX FROM users;

或者:

SHOW KEYS FROM users;

五、查看数据库里所有表

SHOW TABLES;

六、实用组合

查看所有表的表名

SHOW TABLES;

查看某库的表

USE 数据库名;
SHOW TABLES;

或者:

SHOW TABLES FROM 数据库名;

七、从information_schema查

更灵活的方式,从系统表查:

查表的字段信息

SELECT * FROM information_schema.COLUMNS 
WHERE TABLE_SCHEMA = 'mydb' 
AND TABLE_NAME = 'users';

查表的索引信息

SELECT * FROM information_schema.STATISTICS 
WHERE TABLE_SCHEMA = 'mydb' 
AND TABLE_NAME = 'users';

常见坑

坑1:DESC看不到索引详细信息

DESC只告诉你Key列是啥,但不知道索引名。

解决: 用 SHOW INDEX FROM 表名;

坑2:SHOW CREATE TABLE输出太长

直接看会换行很乱。

解决: 加 \G 按行显示:

SHOW CREATE TABLE users\G

坑3:不知道当前在哪个库

查的时候报错说表不存在。

解决: 先 SELECT DATABASE(); 看当前库。

坑4:表名大小写问题

Linux下MySQL表名区分大小写,Windows不区分。

解决: 表名小写,开发时注意。

总结

常用命令总结:

命令 作用
DESC 表名 看字段列表
SHOW CREATE TABLE 表名 看完整建表语句
SHOW INDEX FROM 表名 看索引
SHOW TABLES 看所有表
SHOW TABLE STATUS 看表状态

记住: 看表结构首选DESC,要看完整建表语句用SHOW CREATE TABLE。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-8 07:40 

MySQL备份数据库,mysqldump定时备份

前言

数据库不备份,出事就完蛋。本文讲用mysqldump备份MySQL,再配crontab定时自动备份。

一、mysqldump基本用法

备份单个数据库

mysqldump -u root -p mydb > /backup/mydb.sql

输入密码后,就把mydb库备份到mydb.sql了。

备份多个数据库

mysqldump -u root -p --databases db1 db2 > /backup/mydbs.sql

备份所有数据库

mysqldump -u root -p --all-databases > /backup/all.sql

备份单个表

mysqldump -u root -p mydb users > /backup/users.sql

二、常用参数

参数 说明
--single-transaction InnoDB一致性备份,不锁表
--routines 备份存储过程和函数
--triggers 备份触发器
--events 备份事件调度器
--master-data=2 记录binlog位置,用于主从
--default-character-set=utf8mb4 指定字符集

推荐完整命令

mysqldump -u root -p \
  --single-transaction \
  --routines \
  --triggers \
  --events \
  --default-character-set=utf8mb4 \
  mydb > /backup/mydb_$(date +%Y%m%d).sql

三、压缩备份

备份完太大,直接压缩:

mysqldump -u root -p mydb | gzip > /backup/mydb.sql.gz

恢复的时候:

gunzip < /backup/mydb.sql.gz | mysql -u root -p mydb

四、定时备份脚本

创建备份脚本:

vi /usr/local/bin/mysql_backup.sh

内容:

#!/bin/bash

# 备份目录
BACKUP_DIR=/backup/mysql

# 数据库配置
DB_USER=root
DB_PASS=你的密码
DB_NAME=mydb

# 创建备份目录
mkdir -p $BACKUP_DIR

# 备份文件名(带日期)
DATE=$(date +%Y%m%d_%H%M%S)
FILE=$BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz

# 执行备份
mysqldump -u$DB_USER -p$DB_PASS \
  --single-transaction \
  --routines \
  --triggers \
  --default-character-set=utf8mb4 \
  $DB_NAME | gzip > $FILE

# 删除7天前的备份
find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete

echo "备份完成:$FILE"

加执行权限:

chmod +x /usr/local/bin/mysql_backup.sh

五、配置crontab定时任务

编辑crontab:

crontab -e

加上:

# 每天凌晨2点备份
0 2 * * * /usr/local/bin/mysql_backup.sh >> /var/log/mysql_backup.log 2>&1

六、恢复备份

恢复普通备份

mysql -u root -p mydb < /backup/mydb.sql

恢复压缩备份

gunzip < /backup/mydb.sql.gz | mysql -u root -p mydb

常见坑

坑1:密码写在命令行里不安全

mysqldump -u root -p123456 mydb > xxx.sql

这样密码会出现在进程列表里。

安全做法: 用配置文件存密码。

# /root/.my.cnf
[mysqldump]
user=root
password=你的密码

权限设600:

chmod 600 /root/.my.cnf

以后备份就不用输密码了:

mysqldump mydb > xxx.sql

坑2:备份时锁表

大库备份的时候,业务卡住了。

原因: 没加 --single-transaction。

解决: InnoDB库一定要加这个参数。

坑3:备份文件是空的

备份完一看,文件0字节。

原因: 密码错了,或者数据库名错了。

解决: 先手动执行一次,看报错。

坑4:备份没包含存储过程

备份后恢复,发现存储过程没了。

原因: mysqldump默认不备份存储过程。

解决: 加 --routines 参数。

总结

三步搞定自动备份:

  1. 写备份脚本
  2. 配crontab定时执行
  3. 定期清理旧备份

记住: 备份了不算数,能恢复才算数。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-8 07:39 

MySQL创建数据库、创建用户、授权完整命令

前言

新装MySQL,要创建数据库、创建用户、授权,一套操作下来经常懵。本文整理完整命令,照着抄就行。

第一步:登录MySQL

mysql -u root -p

输入root密码登录。

第二步:创建数据库

CREATE DATABASE mydb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

说明:

  • mydb 是数据库名,自己改
  • utf8mb4 支持emoji,推荐用
  • utf8mb4_general_ci 是排序规则

第三步:创建用户

MySQL 5.7及以前

CREATE USER 'myuser'@'localhost' IDENTIFIED BY '你的密码';

MySQL 8.0

CREATE USER 'myuser'@'localhost' IDENTIFIED BY '你的密码';

允许远程登录

CREATE USER 'myuser'@'%' IDENTIFIED BY '你的密码';

% 表示所有IP都能连,生产环境建议指定具体IP。

第四步:授权

授权所有权限(常用)

GRANT ALL PRIVILEGES ON mydb.* TO 'myuser'@'localhost';

说明:

  • mydb.* 表示mydb库下所有表
  • 要授权所有库就写 *.*

只授权查询权限

GRANT SELECT ON mydb.* TO 'myuser'@'localhost';

授权指定权限

GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.* TO 'myuser'@'localhost';

授权远程用户

GRANT ALL PRIVILEGES ON mydb.* TO 'myuser'@'%';

第五步:刷新权限

FLUSH PRIVILEGES;

这步必须做! 不然授权不生效。

查看和撤销权限

查看用户权限

SHOW GRANTS FOR 'myuser'@'localhost';

撤销权限

REVOKE ALL PRIVILEGES ON mydb.* FROM 'myuser'@'localhost';

删除用户

DROP USER 'myuser'@'localhost';

常见坑

坑1:创建了用户但没授权

用户登录上了,但什么都做不了。

原因: 只创建了用户,没授权。

解决: 创建用户后一定要 GRANT。

坑2:改了密码不生效

改完密码还是旧密码能登。

原因: 没 FLUSH PRIVILEGES。

解决: 执行 FLUSH PRIVILEGES;

坑3:远程连接不上

本地能登,远程连不上。

原因: 用户只允许localhost登录。

解决: 创建 '用户'@'%' 的远程用户,或者授权。

坑4:密码太简单报错

创建用户时报密码不符合策略。

原因: MySQL 5.6以后有密码强度校验。

解决: 用复杂点的密码,或者关掉密码校验。

坑5:MySQL 8.0密码加密方式变了

老客户端连不上MySQL 8.0。

原因: MySQL 8.0默认用caching_sha2_password,老客户端不支持。

解决: 创建用户时指定老的加密方式:

CREATE USER 'myuser'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码';

完整一键脚本

-- 登录MySQL后执行
CREATE DATABASE mydb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER 'myuser'@'localhost' IDENTIFIED BY '你的密码';
GRANT ALL PRIVILEGES ON mydb.* TO 'myuser'@'localhost';
FLUSH PRIVILEGES;

总结

三步走:

  1. 建库 CREATE DATABASE
  2. 建用户 CREATE USER
  3. 授权 GRANT + FLUSH PRIVILEGES

记住: 授权完一定要刷新!

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-8 07:38 

MySQL大表分页越查越慢,优化方案

前言

大表分页查询,第一页很快,第十页就慢,第一百页直接卡死。这是MySQL分页的经典问题,本文讲怎么优化。

为什么越往后越慢

普通分页:

SELECT * FROM orders ORDER BY id LIMIT 100000, 10;

MySQL 会先扫描前100010条,然后丢掉前100000条,只返回最后10条。

越往后翻,扫描的行越多,当然越慢。

优化方案一:子查询优化

先查出起始位置的id,再用id做条件:

SELECT * FROM orders 
WHERE id >= (SELECT id FROM orders ORDER BY id LIMIT 100000, 1)
LIMIT 10;

原理: 子查询走索引,只查id列,很快。然后外层用id直接定位,不用扫那么多行。

优化方案二:游标分页(推荐)

记住上一页最后一条的id,下次从这个id之后查:

-- 第一页
SELECT * FROM orders ORDER BY id LIMIT 10;

-- 第二页(假设上一页最后id是100)
SELECT * FROM orders WHERE id > 100 ORDER BY id LIMIT 10;

-- 第三页(假设上一页最后id是110)
SELECT * FROM orders WHERE id > 110 ORDER BY id LIMIT 10;

优点: 不管翻到第几页,都是直接定位,速度一样快。

缺点: 不能跳页,只能上一页下一页。

优化方案三:覆盖索引

只查需要的列,不要 SELECT *:

SELECT id, title, create_time FROM orders ORDER BY id LIMIT 100000, 10;

如果查询的列都在索引里,MySQL直接从索引返回数据,不用回表,快很多。

优化方案四:业务上限制深分页

根本解决: 不让用户翻到那么深。

  1. 搜索结果只显示前100页
  2. 用条件过滤,不要全表翻
  3. 用搜索引擎(ES)代替深分页

常见坑

坑1:用了offset就一定慢

其实offset小的时候(比如前10页),差别不大。

结论: 数据量不大的时候,普通分页就行,不用过度优化。

坑2:游标分页不能用排序

游标分页只能按主键或唯一索引排序。

解决: 如果按其他字段排序,先查出对应的id列表,再用id定位。

坑3:子查询效率也不高

子查询在MySQL 5.6以前有优化器问题。

解决: MySQL 5.6以后子查询优化得很好了,放心用。

坑4:没加where条件

深分页没加where,全表扫描。

解决: 尽量加上时间范围、状态等过滤条件。

性能对比

方案 第1页 第100页 第1000页
普通分页 快 慢 很慢
子查询优化 快 中 慢
游标分页 快 快 快
搜索引擎 快 快 快

总结

大表分页优化三板斧:

  1. 小数据量:普通分页就行
  2. 中等数据量:子查询优化
  3. 大数据量:游标分页 + 搜索引擎

记住: 深分页不是MySQL擅长的事,数据量大了就上ES。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-8 07:36 

MySQL数据库导入sql文件报错解决

前言

导入SQL文件到MySQL,经常报各种错。本文总结最常见的导入报错和解决方法。

常用导入命令

mysql -u root -p 数据库名 < xxx.sql

或者登录MySQL后:

source /路径/xxx.sql;

常见报错及解决

报错1:Unknown database

ERROR 1049 (42000): Unknown database 'xxx'

原因: 数据库不存在。

解决: 先创建数据库:

CREATE DATABASE xxx DEFAULT CHARSET utf8mb4;

然后再导入。

报错2:Access denied

ERROR 1044 (42000): Access denied for user

原因: 用户没权限。

解决: 用root用户导入,或者给用户授权。

报错3:File not found

ERROR 1045 (28000): Access denied

或者文件找不到。

原因: 文件路径不对,或者文件权限不对。

解决:

  1. 确认文件存在:ls -l /路径/xxx.sql
  2. 确认文件可读:chmod 644 /路径/xxx.sql
  3. 用绝对路径,别用相对路径

报错4:Table already exists

ERROR 1050 (42S01): Table 'xxx' already exists

原因: 表已经存在了。

解决: 两种方法:

  1. 先删表再导入:DROP TABLE xxx;
  2. SQL文件里加 DROP TABLE IF EXISTS xxx;

报错5:Duplicate entry

ERROR 1062 (23000): Duplicate entry 'xxx' for key

原因: 主键重复。

解决:

  1. 先清空表再导入
  2. 或者用 INSERT IGNORE 跳过重复

报错6:字符集乱码

导入后中文变成乱码。

原因: 字符集不对。

解决: 导入前设置字符集:

SET NAMES utf8mb4;
source /路径/xxx.sql;

或者命令行指定:

mysql -u root -p --default-character-set=utf8mb4 数据库名 < xxx.sql

报错7:max_allowed_packet太小

ERROR 2006 (HY000): MySQL server has gone away

原因: SQL文件太大,MySQL接收不了。

解决: 修改my.cnf,加大max_allowed_packet:

[mysqld]
max_allowed_packet = 64M

重启MySQL生效。

导入大文件技巧

方法1:分卷压缩

把大SQL文件拆成小的:

split -b 10M xxx.sql small_

然后逐个导入。

方法2:跳过外键检查

导入时临时关闭外键检查,更快:

SET FOREIGN_KEY_CHECKS = 0;
source /路径/xxx.sql;
SET FOREIGN_KEY_CHECKS = 1;

常见坑

坑1:用错用户名密码

导入时一直提示密码错误。

解决: 确认用户名密码,或者用 mysql -u root -p 交互式输入密码。

坑2:SQL文件不是UTF-8编码

导入后中文乱码。

解决: 用 file 命令查看文件编码:

file -i xxx.sql

坑3:没选对数据库

导入后数据不知道导到哪去了。

解决: 命令行一定要指定数据库名,或者先 USE 数据库名;

总结

导入SQL文件三步走:

  1. 先确认数据库存在
  2. 用正确的字符集导入
  3. 大文件就调大max_allowed_packet

记住: 报错信息一定要看清楚,别瞎试。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-8 07:35 

MySQL忘记root密码重置(Linux环境)

前言

忘记MySQL root密码是常见问题,不用慌,本文教你一步步重置。

重置步骤

第一步:停止MySQL服务

systemctl stop mysqld

第二步:以跳过权限模式启动

mysqld_safe --skip-grant-tables &

或者用这个方式:

systemctl set-environment MYSQLD_OPTS="--skip-grant-tables"
systemctl start mysqld

第三步:无密码登录MySQL

mysql -u root

现在不需要密码就能直接进了。

第四步:修改密码

-- 刷新权限
FLUSH PRIVILEGES;

-- 修改密码(MySQL 5.7)
ALTER USER 'root'@'localhost' IDENTIFIED BY '你的新密码';

-- 如果上面不行,用这个
UPDATE mysql.user SET authentication_string=PASSWORD('你的新密码') WHERE User='root' AND Host='localhost';

-- 刷新权限
FLUSH PRIVILEGES;

第五步:退出,正常重启MySQL

exit
systemctl stop mysqld
systemctl start mysqld

第六步:用新密码登录测试

mysql -u root -p

输入新密码,能进去就成功了。

常见坑

坑1:MySQL 8.0和5.7语法不一样

MySQL 8.0 不能用 PASSWORD() 函数了。

解决: 用 ALTER USER 语句。

坑2:skip-grant-tables没生效

启动后还是要密码。

原因: 可能MySQL已经在跑了,新启动的没生效。

解决: 先彻底停掉MySQL:

systemctl stop mysqld
pkill -9 mysqld

再重新启动。

坑3:改完密码忘记FLUSH PRIVILEGES

改完密码直接退出,结果还是不能用新密码登录。

解决: 改完密码一定要执行 FLUSH PRIVILEGES;

坑4:远程登录还是不行

本地改完密码,远程连接还是连不上。

原因: root用户只允许本地登录。

解决: 需要单独授权远程登录:

CREATE USER 'root'@'%' IDENTIFIED BY '密码';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;

总结

六步重置root密码:

  1. 停MySQL
  2. 跳过权限启动
  3. 无密码登录
  4. 改密码
  5. 正常重启
  6. 测试登录

记住: 改完密码一定要 FLUSH PRIVILEGES;

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-8 07:34 

MySQL 事务隔离级别

MySQL 事务隔离级别

事务隔离是数据库的重要概念,搞懂4种级别很有必要。

1. 事务的ACID

  • 原子性(Atomicity): 要么全成功,要么全失败
  • 一致性(Consistency): 事务前后数据一致
  • 隔离性(Isolation): 多个事务互不影响
  • 持久性(Durability): 提交后永久保存

2. 4种隔离级别

1)读未提交(Read Uncommitted)

  • 能读到未提交的数据
  • 有脏读、不可重复读、幻读问题
  • 性能最好

2)读提交(Read Committed)

  • 只能读到已提交的数据
  • 解决脏读
  • 有不可重复读、幻读问题
  • Oracle默认级别

3)可重复读(Repeatable Read)

  • 同一个事务里读多次结果一样
  • 解决脏读、不可重复读
  • 有幻读问题
  • MySQL默认级别

4)串行化(Serializable)

  • 事务排队执行
  • 解决所有问题
  • 性能最差

3. 三种问题

脏读:

  • 读到另一个事务未提交的数据
  • 对方回滚了,你读的就是脏数据

不可重复读:

  • 同一个事务里,两次读同一行结果不一样
  • 中间被其他事务修改了

幻读:

  • 同一个事务里,两次查询行数不一样
  • 中间被其他事务插入了

4. 查看和设置

-- 查看当前隔离级别
SELECT @@transaction_isolation;

-- 设置隔离级别
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

5. 实际使用

  • 一般用默认的可重复读就够了
  • 对一致性要求高的用串行化
  • 不要随便改隔离级别

总结

MySQL事务隔离级别要点:

  • 读未提交:性能最好,问题最多
  • 读提交:解决脏读
  • 可重复读:MySQL默认,解决不可重复读
  • 串行化:最安全,性能最差
  • 理解脏读、不可重复读、幻读

做数据库开发,事务隔离一定要懂。


emer 发布于  2026-10-8 07:30 

Redis 常用数据类型

Redis 常用数据类型

Redis 不只是简单的 key-value,有5种常用数据类型,每种适合不同场景。

1. String(字符串)

最基础的类型,存字符串、数字都可以。

# 设置
set name "张三"

# 获取
get name

# 自增
incr age

# 设置过期时间
set token "abc" ex 3600

适用场景: 缓存、计数器、Session。

2. Hash(哈希)

存对象,比如用户信息。

# 设置单个字段
hset user:1 name "张三"

# 获取单个字段
hget user:1 name

# 设置多个字段
hmset user:1 name "张三" age 20 city "北京"

# 获取所有字段
hgetall user:1

适用场景: 存储对象(用户信息、商品信息)。

3. List(列表)

有序列表,可以做消息队列。

# 左侧添加
lpush list "a" "b" "c"

# 右侧添加
rpush list "d"

# 左侧弹出
lpop list

# 查看范围
lrange list 0 -1

适用场景: 消息队列、最新列表。

4. Set(集合)

无序,不重复,做去重。

# 添加
sadd set "a" "b" "c"

# 查看所有
smembers set

# 判断是否存在
sismember set "a"

# 交集
sinter set1 set2

适用场景: 去重、共同好友、标签。

5. ZSet(有序集合)

有序,带分数排序。

# 添加
zadd rank 100 "张三" 90 "李四" 80 "王五"

# 查看排名(从高到低)
zrevrank rank "张三"

# 查看分数
zscore rank "张三"

# 查看排行榜
zrevrange rank 0 9

适用场景: 排行榜、分数排序。

总结

Redis 5种数据类型:

  • String:缓存、计数器
  • Hash:存对象
  • List:消息队列
  • Set:去重、标签
  • ZSet:排行榜

根据场景选对数据类型,用起来才高效。


emer 发布于  2026-10-8 07:29 

PHP 字符串处理函数

PHP 字符串处理函数

字符串处理是 PHP 最常用的操作,这些函数一定要会。

1. 截取字符串

// 截取前n个字符
substr("hello world", 0, 5); // hello

// 中文截取(用mb_substr)
mb_substr("你好世界", 0, 2, "utf-8"); // 你好

2. 替换字符串

//  str_replace 替换
str_replace("world", "PHP", "hello world"); // hello PHP

// 只替换第一次出现
str_replace("a", "b", "aaa", $count);

3. 查找字符串

// 查找位置(找不到返回false)
strpos("hello world", "world"); // 6

// 注意:用 === 0 判断开头
if (strpos($str, "hello") === 0) {
    echo "以hello开头";
}

4. 大小写转换

// 转小写
strtolower("Hello"); // hello

// 转大写
strtoupper("hello"); // HELLO

// 首字母大写
ucfirst("hello"); // Hello

// 每个单词首字母大写
ucwords("hello world"); // Hello World

5. 去除空白

// 去除两边空格
trim("  hello  "); // hello

// 去左边
ltrim("  hello  "); // hello  

// 去右边
rtrim("  hello  "); //   hello

6. 字符串拼接

// 用点拼接
$str = "hello" . " " . "world";

// 多变量拼接
$a = "hello";
$b = "world";
$c = "$a $b"; // hello world

7. 分割和合并

// 分割成数组
$arr = explode(",", "a,b,c"); // ["a", "b", "c"]

// 数组合并成字符串
$str = implode(",", $arr); // a,b,c

8. 常用技巧

1)判断是否包含字符串:

if (strpos($str, "hello") !== false) {
    echo "包含hello";
}

2)反转字符串:

strrev("hello"); // olleh

3)字符串长度:

strlen("hello"); // 5
mb_strlen("你好", "utf-8"); // 2

总结

PHP 字符串处理要点:

  • substr 截取,注意中文用 mb_substr
  • str_replace 替换
  • strpos 查找,用 !== false 判断
  • trim 去空格
  • explode/implode 分割合并
  • 注意中文编码问题,用 mb 开头的函数

写 PHP,字符串函数天天用。


emer 发布于  2026-10-8 07:28 

MySQL 索引优化技巧

MySQL 索引优化技巧

索引是数据库性能的关键,用对了查询快很多。

1. 索引类型

  • 主键索引: 主键自带,唯一且非空
  • 普通索引: 最基本的索引
  • 唯一索引: 字段值不能重复
  • 联合索引: 多个字段组成的索引
  • 全文索引: 全文搜索用

2. 创建索引

-- 普通索引
CREATE INDEX idx_name ON users(name);

-- 唯一索引
CREATE UNIQUE INDEX idx_phone ON users(phone);

-- 联合索引
CREATE INDEX idx_name_age ON users(name, age);

3. 索引失效情况

1)不要在索引字段上做运算:

-- 失效
SELECT * FROM users WHERE age + 1 = 20;

-- 生效
SELECT * FROM users WHERE age = 19;

2)like 左模糊:

-- 失效
SELECT * FROM users WHERE name LIKE '%张';

-- 生效
SELECT * FROM users WHERE name LIKE '张%';

3)联合索引不满足最左前缀:

-- 索引:(name, age)
-- 生效(从name开始)
SELECT * FROM users WHERE name = '张三' AND age = 20;

-- 失效(跳过name直接查age)
SELECT * FROM users WHERE age = 20;

4)用 or 连接:

  • or 两边有一个没索引就全表扫描

4. 优化原则

  • 频繁查询的字段加索引
  • 区分度高的字段适合做索引
  • 不要加太多索引(影响写入性能)
  • 联合索引注意最左前缀
  • 尽量扩展索引,不要新建索引

5. 查看索引

-- 查看表的索引
SHOW INDEX FROM users;

6. 常见问题

  • 索引加了还是慢?检查是不是失效了
  • 查询还是慢?用 EXPLAIN 分析
  • 写入慢?索引太多了

总结

MySQL 索引优化要点:

  • 常用查询字段加索引
  • 注意索引失效情况
  • 联合索引最左前缀
  • 不要加太多索引
  • EXPLAIN 分析执行计划

数据库性能优化,索引是第一步。


emer 发布于  2026-10-8 07:27 

Linux 文件权限详解

Linux 文件权限详解

Linux 权限是基础,搞不懂经常出问题。

1. 查看权限

ls -l

输出:

-rw-r--r-- 1 root root 1000 Oct 8 10:00 test.txt

2. 权限含义

第一位:文件类型

    • 普通文件
  • d 目录
  • l 软链接

后面9位:分3组

  • 第1组:所有者权限
  • 第2组:所属组权限
  • 第3组:其他人权限

3个字母:

  • r 读(4)
  • w 写(2)
  • x 执行(1)

比如 rw-r--r--:

  • 所有者:读写(6)
  • 组:只读(4)
  • 其他人:只读(4)

3. 修改权限 chmod

数字方式:

# 所有者读写执行,组读执行,其他人读执行
chmod 755 test.sh

# 所有人只读
chmod 444 test.txt

字母方式:

# 给所有者加执行权限
chmod u+x test.sh

# 给组加写权限
chmod g+w test.txt

# 去掉其他人的读权限
chmod o-r test.txt

4. 修改所有者 chown

# 修改所有者
chown www:www test.txt

# 递归修改目录
chown -R www:www /www/wwwroot

5. 常用权限

  • 目录:755(所有者读写执行,其他人读执行)
  • 普通文件:644(所有者读写,其他人只读)
  • 脚本文件:755

6. 常见问题

1)网站打不开:

  • 检查目录权限是不是 755
  • 检查文件权限是不是 644
  • 检查所有者是不是 www

2)上传不了文件:

  • 检查目录有没有写权限

3)脚本执行不了:

  • 检查有没有执行权限

总结

Linux 文件权限要点:

  • r=4, w=2, x=1
  • chmod 修改权限
  • chown 修改所有者
  • 目录 755,文件 644
  • 权限不对经常出问题

做运维,权限一定要搞懂。


emer 发布于  2026-10-8 07:26 

Nginx 负载均衡配置

Nginx 负载均衡配置

多台服务器分流,提高网站并发能力,Nginx 负载均衡很常用。

1. 什么是负载均衡

  • 多台服务器做同样的服务
  • Nginx 把请求分发给不同服务器
  • 提高并发能力,一台挂了其他还能用

2. 基础配置

upstream myserver {
    server 127.0.0.1:8080;
    server 127.0.0.1:8081;
    server 127.0.0.1:8082;
}

server {
    listen 80;
    server_name www.example.com;

    location / {
        proxy_pass http://myserver;
    }
}

3. 常用分发策略

1)轮询(默认)

  • 一个接一个轮流分
    upstream myserver {
    server 127.0.0.1:8080;
    server 127.0.0.1:8081;
    }

2)加权轮询

  • 性能好的服务器多分点
    upstream myserver {
    server 127.0.0.1:8080 weight=3;
    server 127.0.0.1:8081 weight=1;
    }

3)ip_hash

  • 同一个IP固定访问同一台
    upstream myserver {
    ip_hash;
    server 127.0.0.1:8080;
    server 127.0.0.1:8081;
    }

4. 健康检查

upstream myserver {
    server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
    server 127.0.0.1:8081 max_fails=3 fail_timeout=30s;
}
  • max_fails:失败几次标记为挂掉
  • fail_timeout:多久后重试

5. 常用参数

upstream myserver {
    # 备用服务器,其他都挂了才用
    server 127.0.0.1:8080 backup;

    # 不参与负载均衡
    server 127.0.0.1:8081 down;
}

6. 注意事项

  • 多台服务器数据要同步(Session、数据库)
  • Session 共享用 Redis
  • 文件上传用共享存储

总结

Nginx 负载均衡要点:

  • upstream 定义服务器组
  • proxy_pass 转发到组
  • 轮询、加权、ip_hash 策略
  • 健康检查自动剔除挂掉的服务
  • 注意 Session 共享

做大并发网站,负载均衡是必备的。


emer 发布于  2026-10-8 07:25 

PHP 常用设计模式

PHP 常用设计模式

设计模式是写好代码的经验总结,常用的几种要掌握。

1. 单例模式

整个项目只有一个实例,比如数据库连接。

class Db
{
    private static $instance = null;

    private function __construct() {}

    public static function getInstance()
    {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }
}

$db = Db::getInstance();

2. 工厂模式

根据参数创建不同的对象。

class Factory
{
    public static function make($type)
    {
        $class = ucfirst($type);
        return new $class();
    }
}

$user = Factory::make('user');
$order = Factory::make('order');

3. 观察者模式

一个对象状态变化,通知所有观察者。

interface Observer
{
    public function update($event);
}

class Event
{
    private $observers = [];

    public function add(Observer $observer)
    {
        $this->observers[] = $observer;
    }

    public function trigger($event)
    {
        foreach ($this->observers as $ob) {
            $ob->update($event);
        }
    }
}

4. 常用场景

  • 单例: 数据库、日志、配置
  • 工厂: 创建不同类的对象
  • 观察者: 事件触发、消息通知
  • 策略: 不同支付方式
  • 适配器: 兼容不同接口

5. 设计原则

  • 单一职责:一个类只做一件事
  • 开闭原则:对扩展开放,对修改关闭
  • 依赖倒置:依赖抽象不依赖具体

总结

PHP 常用设计模式要点:

  • 单例模式:只创建一个实例
  • 工厂模式:统一创建对象
  • 观察者:事件通知
  • 理解设计原则
  • 不要为了模式而模式

设计模式是工具,解决问题才是目的。


emer 发布于  2026-10-8 07:24 

Redis 缓存穿透解决

Redis 缓存穿透解决

缓存穿透是指查询不存在的数据,请求都打到数据库,可能被攻击。

1. 什么是缓存穿透

  • 缓存里没有这个数据
  • 数据库里也没有
  • 每次请求都查数据库
  • 有人恶意攻击数据库就挂了

2. 和其他问题的区别

  • 穿透: 查不存在的数据
  • 击穿: 热点key过期
  • 雪崩: 大量key同时过期

3. 解决方案

方案一:缓存空值

function getUser($id) {
    global $redis, $db;

    $key = "user:".$id;
    $user = $redis->get($key);

    if ($user !== false) {
        return json_decode($user, true);
    }

    // 查数据库
    $user = $db->query("SELECT * FROM users WHERE id=$id");

    if ($user) {
        // 存正常数据
        $redis->setex($key, 3600, json_encode($user));
    } else {
        // 存空值,短时间过期
        $redis->setex($key, 60, "null");
    }

    return $user;
}

方案二:布隆过滤器

  • 所有存在的数据存在布隆过滤器里
  • 查询前先过布隆过滤器
  • 不存在直接返回,不查数据库

方案三:接口校验

  • 前端做参数校验
  • 比如id必须大于0
  • 不合法的直接拒绝

4. 代码示例

// 简单防穿透
if ($id <= 0) {
    return null;
}

// 先查缓存
$user = $redis->get("user:".$id);

if ($user === "null") {
    return null;
}

if ($user) {
    return json_decode($user, true);
}

// 查数据库
$user = $db->query("SELECT * FROM users WHERE id=$id");

// 存缓存
if ($user) {
    $redis->setex("user:".$id, 3600, json_encode($user));
} else {
    $redis->setex("user:".$id, 60, "null");
}

return $user;

5. 最佳实践

  • 空值缓存,短时间过期
  • 重要接口加布隆过滤器
  • 前端做参数校验
  • 数据库做限流保护

总结

缓存穿透解决要点:

  • 查不到也存空值
  • 空值过期时间短
  • 用布隆过滤器
  • 做好接口校验

高并发系统,缓存穿透一定要防。


emer 发布于  2026-10-8 07:23 

Linux 防火墙配置详解

Linux 防火墙配置详解

服务器安全第一步就是防火墙,学会配置很重要。

1. firewalld(CentOS 7+)

查看状态:

systemctl status firewalld

开启/关闭:

# 开启
systemctl start firewalld

# 关闭
systemctl stop firewalld

# 开机自启
systemctl enable firewalld

2. 开放端口

开放单个端口:

firewall-cmd --zone=public --add-port=80/tcp --permanent

开放多个端口:

firewall-cmd --zone=public --add-port=80-90/tcp --permanent

重新加载生效:

firewall-cmd --reload

3. 查看端口

# 查看所有开放端口
firewall-cmd --list-ports

# 查看某个端口是否开放
firewall-cmd --query-port=80/tcp

4. 关闭端口

firewall-cmd --zone=public --remove-port=80/tcp --permanent
firewall-cmd --reload

5. iptables(旧版)

查看规则:

iptables -L -n

开放端口:

iptables -I INPUT -p tcp --dport 80 -j ACCEPT

保存规则:

service iptables save

6. 常用端口

# 常用端口
22      SSH
80      HTTP
443     HTTPS
3306    MySQL
6379    Redis
8080    Tomcat

7. 常见问题

1)端口开了还是访问不了:

  • 检查云服务商安全组
  • 检查服务器内部防火墙

2)远程连接不上:

  • 检查 22 端口是否开放
  • 检查 sshd 是否启动

总结

Linux 防火墙要点:

  • firewalld 管理端口
  • --permanent 永久生效
  • --reload 重新加载
  • 记得开放安全组
  • 常用端口按需开放

做运维,防火墙是基本功。


emer 发布于  2026-10-8 07:22 

PHP Composer 使用指南

PHP Composer 使用指南

Composer 是 PHP 的依赖管理工具,做开发必备。

1. 安装 Composer

# 下载安装
curl -sS https://getcomposer.org/installer | php

# 移动到全局
mv composer.phar /usr/local/bin/composer

# 验证
composer -V

2. 国内镜像加速

# 阿里镜像
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

3. 常用命令

1)初始化项目:

composer init

2)安装依赖:

# 安装所有依赖
composer install

# 安装指定包
composer require monolog/monolog

# 安装开发依赖
composer require --dev phpunit/phpunit

3)更新依赖:

# 更新所有依赖
composer update

# 更新指定包
composer update monolog/monolog

4)删除依赖:

composer remove monolog/monolog

4. composer.json 说明

{
    "name": "test/project",
    "description": "测试项目",
    "require": {
        "php": ">=7.0",
        "monolog/monolog": "^2.0"
    },
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    }
}

5. 自动加载

// 引入自动加载
require __DIR__ . '/vendor/autoload.php';

// 使用类
$log = new Monolog\Logger('name');

6. 常用操作

  • composer install:根据 lock 文件安装
  • composer update:更新依赖
  • composer dump-autoload:重新生成自动加载

总结

Composer 使用要点:

  • 安装 Composer
  • 配置国内镜像
  • require 安装依赖
  • autoload 自动加载
  • install/update 管理依赖

做 PHP 开发,Composer 一定要会用。


emer 发布于  2026-10-8 07:20 

MySQL 慢查询优化实战

MySQL 慢查询优化实战

数据库慢查询是性能瓶颈的常见原因,学会优化很重要。

1. 开启慢查询日志

-- 查看是否开启
SHOW VARIABLES LIKE 'slow_query_log';

-- 开启慢查询
SET GLOBAL slow_query_log = ON;

-- 设置慢查询时间(秒)
SET GLOBAL long_query_time = 1;

2. 分析慢查询

用 EXPLAIN 分析:

EXPLAIN SELECT * FROM users WHERE name = '张三';

重点看:

  • type:访问类型,ALL 是全表扫描,要优化
  • key:用了哪个索引
  • rows:扫描行数

3. 常见优化方法

1)加索引:

-- 加索引
ALTER TABLE users ADD INDEX idx_name(name);

*2)避免 SELECT :**

-- 不好
SELECT * FROM users;

-- 好
SELECT id, name FROM users;

3)避免在索引字段上做运算:

-- 不好
SELECT * FROM users WHERE YEAR(create_time) = 2026;

-- 好
SELECT * FROM users WHERE create_time >= '2026-01-01' AND create_time < '2027-01-01';

4)避免 LIKE 左模糊:

-- 不好(用不到索引)
SELECT * FROM users WHERE name LIKE '%张%';

-- 好
SELECT * FROM users WHERE name LIKE '张%';

4. 分页优化

-- 不好(大偏移量慢)
SELECT * FROM users LIMIT 100000, 10;

-- 好(用子查询)
SELECT * FROM users WHERE id >= (
    SELECT id FROM users LIMIT 100000, 1
) LIMIT 10;

5. 常见慢查询原因

  • 没加索引
  • 索引失效
  • 关联查询太多
  • 数据量太大
  • 大表分页

总结

MySQL 慢查询优化要点:

  • 开启慢查询日志
  • 用 EXPLAIN 分析
  • 合理加索引
  • 避免全表扫描
  • 优化分页查询

数据库优化是个细活,多分析多测试。


emer 发布于  2026-10-8 07:19 

Nginx 日志分析技巧

Nginx 日志分析技巧

Nginx 日志是排查问题的重要工具,学会分析日志很重要。

1. 日志位置

默认日志路径:

# 访问日志
/var/log/nginx/access.log

# 错误日志
/var/log/nginx/error.log

2. 日志格式

默认日志格式:

log_format access '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent"';

3. 常用分析命令

1)查看访问量最多的IP:

awk '{print $1}' access.log | sort | uniq -c | sort -nr | head 10

2)查看访问最多的页面:

awk '{print $7}' access.log | sort | uniq -c | sort -nr | head 10

3)查看状态码分布:

awk '{print $9}' access.log | sort | uniq -c | sort -nr

4)查看404错误:

awk '$9 == 404 {print $7}' access.log | sort | uniq -c | sort -nr

4. 排查常用

1)查看哪个IP访问频繁:

grep "127.0.0.1" access.log

2)查看某个时间段日志:

grep "08/Oct/2026:07" access.log

3)查看错误日志:

tail -f error.log

5. 日志切割

用 logrotate 自动切割:

# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
    daily
    missingok
    rotate 30
    compress
    notifempty
    create 0640 nginx adm
    postrotate
        systemctl reload nginx
    endscript
}

6. 常用场景

  • 被攻击了:查访问量最多的IP
  • 页面报错:查404/500
  • 流量突增:查访问最多的页面
  • 爬虫多:查 User-Agent

总结

Nginx 日志分析要点:

  • 访问日志查访问情况
  • 错误日志排查问题
  • awk 统计数据
  • 日志自动切割
  • 定期分析日志

做运维,看日志是基本功。


emer 发布于  2026-10-8 07:18 

Git 常用命令大全

Git 常用命令大全

Git 是开发必备工具,这些常用命令一定要会。

1. 初始化和克隆

# 初始化仓库
git init

# 克隆远程仓库
git clone https://github.com/user/repo.git

2. 提交代码

# 查看状态
git status

# 添加所有文件到暂存区
git add .

# 添加指定文件
git add index.html

# 提交到本地仓库
git commit -m "提交说明"

# 提交并添加所有修改
git commit -am "提交说明"

3. 远程操作

# 推送到远程分支
git push origin master

# 拉取远程更新
git pull origin master

# 查看远程仓库
git remote -v

4. 分支操作

# 查看所有分支
git branch

# 创建新分支
git branch dev

# 切换分支
git checkout dev

# 创建并切换分支
git checkout -b dev

# 合并分支
git merge dev

# 删除分支
git branch -d dev

5. 版本回退

# 查看提交历史
git log

# 查看简化日志
git log --oneline

# 回退到上一个版本
git reset --hard HEAD^

# 回退到指定版本
git reset --hard 版本号

# 查看操作记录
git reflog

6. 撤销操作

# 撤销工作区修改
git checkout -- 文件

# 撤销暂存区
git reset HEAD 文件

# 删除文件
git rm 文件

7. 常用技巧

1)查看差异:

git diff

2)暂存修改:

# 临时保存
git stash

# 恢复暂存
git stash pop

3)打标签:

git tag v1.0
git push origin v1.0

8. 配置用户信息

# 全局配置
git config --global user.name "用户名"
git config --global user.email "邮箱"

总结

Git 常用命令要点:

  • add 添加文件
  • commit 提交代码
  • push 推送到远程
  • pull 拉取更新
  • branch 分支管理
  • log 查看历史
  • reset 版本回退

做开发,Git 一定要熟练用。


emer 发布于  2026-10-8 07:17 
'); })();