平时做开发,偶尔会遇到需要直接在数据库改会员字段的情况,这里说下我自己踩过坑之后的操作习惯,只讲实操,不搞虚的。
先说一句最重要的:能在后台程序里改,就尽量别直接跑 SQL 改库。程序里面一般都有校验逻辑,状态、时间、关联数据都会自动处理。直接操作数据库,跳过校验,很容易出问题。只有后台功能满足不了、紧急修复的时候,我才会动手改。
动手之前,我必做两件事。
第一,先备份。要么整表备份,要么单独把要修改的这条或者这批数据先查出来,导出一份。我习惯先执行 select,把要改的数据先看一遍,核对会员 ID、手机号、要改的字段值,确认就是目标数据,避免改错人。
第二,看清楚字段类型。是 int、varchar、datetime 还是 tinyint,类型不对,改完数据直接异常。比如状态字段,有的地方 0 代表禁用,1 代表正常,不能凭印象乱填,先看表注释或者拿一条正常数据对比一下。
写 update 语句的时候,条件一定要写准,优先用唯一主键 id,尽量不要用手机号这类条件。手机号有可能重复,或者有空格,一不小心就批量更新错。
错误示范:`update member set status=1 where phone='138xxxxxxx'`
稳妥写法:`update member set status=1 where id=10086`
平时做开发,偶尔会遇到需要直接在数据库改会员字段的情况,这里说下我自己踩过坑之后的操作习惯,顺带把我项目里一直在用的会员表结构和常用 SQL 贴出来,只讲实操,不搞虚的。
先说一句最重要的:**能在后台程序里改,就尽量别直接跑 SQL 改库**。程序里面一般都有校验逻辑,状态、时间、关联数据都会自动处理。直接操作数据库,跳过校验,很容易出问题。只有后台功能满足不了、紧急修复的时候,我才会动手改。
动手之前,我必做两件事。
第一,先备份。要么整表备份,要么单独把要修改的这条或者这批数据先查出来,导出一份。我习惯先执行 select,把要改的数据先看一遍,核对会员 ID、手机号、要改的字段值,确认就是目标数据,避免改错人。
第二,看清楚字段类型。是 int、varchar、datetime 还是 tinyint,类型不对,改完数据直接异常。比如状态字段,有的地方 0 代表禁用,1 代表正常,不能凭印象乱填,先看表注释或者拿一条正常数据对比一下。
下面是我线上项目一直在用的会员主表,MySQL5.7、8.0 都能跑,字段都是会员管理高频用到的,按需删减就行。
-- 会员主表 member
CREATE TABLE `member` (
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '会员主键ID',
`nickname` varchar(50) NOT NULL DEFAULT '' COMMENT '昵称',
`avatar` varchar(255) NOT NULL DEFAULT '' COMMENT '头像地址',
`phone` varchar(20) NOT NULL DEFAULT '' COMMENT '手机号',
`password` varchar(64) NOT NULL DEFAULT '' COMMENT '加密密码(不要明文)',
`salt` varchar(32) NOT NULL DEFAULT '' COMMENT '密码盐值',
`email` varchar(100) NOT NULL DEFAULT '' COMMENT '邮箱',
`real_name` varchar(20) NOT NULL DEFAULT '' COMMENT '真实姓名',
`id_card` varchar(20) NOT NULL DEFAULT '' COMMENT '身份证号',
`gender` tinyint NOT NULL DEFAULT '0' COMMENT '性别 0未知 1男 2女',
`birthday` date DEFAULT NULL COMMENT '生日',
`province` varchar(20) NOT NULL DEFAULT '' COMMENT '省份',
`city` varchar(20) NOT NULL DEFAULT '' COMMENT '城市',
`address` varchar(255) NOT NULL DEFAULT '' COMMENT '详细地址',
`level` tinyint NOT NULL DEFAULT '1' COMMENT '会员等级 1普通会员',
`points` int NOT NULL DEFAULT '0' COMMENT '积分',
`balance` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '账户余额',
`freeze_balance` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '冻结余额',
`status` tinyint NOT NULL DEFAULT '1' COMMENT '状态 0禁用 1正常 2待审核',
`openid` varchar(100) NOT NULL DEFAULT '' COMMENT '微信openid',
`unionid` varchar(100) NOT NULL DEFAULT '' COMMENT '微信unionid',
`invite_id` int unsigned NOT NULL DEFAULT '0' COMMENT '推荐人ID',
`register_ip` varchar(50) NOT NULL DEFAULT '' COMMENT '注册IP',
`last_login_ip` varchar(50) NOT NULL DEFAULT '' COMMENT '最后登录IP',
`last_login_time` int NOT NULL DEFAULT '0' COMMENT '最后登录时间戳',
`register_time` int NOT NULL DEFAULT '0' COMMENT '注册时间戳',
`update_time` int NOT NULL DEFAULT '0' COMMENT '信息更新时间戳',
PRIMARY KEY (`id`),
KEY `idx_phone` (`phone`),
KEY `idx_openid` (`openid`),
KEY `idx_invite_id` (`invite_id`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='会员主表';
-- 1、查询单个会员(按主键,最稳)
SELECT * FROM member WHERE id = 1001;
-- 2、根据手机号查会员
SELECT * FROM member WHERE phone = '13800138000';
-- 3、新增会员
INSERT INTO member (nickname,phone,password,salt,level,status,register_ip,register_time,update_time)
VALUES ('测试用户','13800138000','这里存加密后的密码','随机盐',1,1,'127.0.0.1',UNIX_TIMESTAMP(),UNIX_TIMESTAMP());
-- 4、修改会员基础信息(重点:条件带上id)
UPDATE member SET nickname='新昵称',points=200,update_time=UNIX_TIMESTAMP() WHERE id=1001;
-- 5、禁用会员账号
UPDATE member SET status=0,update_time=UNIX_TIMESTAMP() WHERE id=1001;
-- 6、批量修改会员等级(改之前一定要先select核对数量!)
SELECT id,level FROM member WHERE level=1;
-- 确认没问题再执行update
UPDATE member SET level=2,update_time=UNIX_TIMESTAMP() WHERE level=1;
-- 7、查询正常状态会员列表,分页
SELECT id,nickname,phone,level,points,balance,register_time
FROM member
WHERE status=1
ORDER BY id DESC
LIMIT 0,20;
-- 8、统计会员总数、正常会员数量
SELECT COUNT(*) AS all_num,
SUM(IF(status=1,1,0)) AS normal_num
FROM member;
写 update 语句的时候,条件一定要写准,优先用唯一主键 id,尽量不要用手机号这类条件。手机号有可能重复,或者有空格,一不小心就批量更新错。
错误示范:`update member set status=1 where phone='138xxxxxxx'`
稳妥写法:`update member set status=1 where id=10086`
如果是批量修改,我不会直接执行 update。先拿 select 把 where 条件跑一遍,看看返回多少条,确认数量和预期一致,再换成 update。之前吃过亏,where 条件漏写一个,一下子把全表会员状态改掉,回滚折腾很久。
改完之后不能直接完事。
先在数据库里 select 再查一遍,确认值已经更新成功。然后去前端、后台页面看这个会员账号,登录试试,看看权限、页面显示有没有异常。有些会员数据会同步到缓存、Redis,数据库改完,缓存没清,页面还是旧数据,这个坑很常见,很多人改完以为没生效,其实是缓存挡住了。
还有关联表这块也要留意。会员表单独改了,但是积分表、订单表、附属信息表里面有联动字段,只改主表,数据不一致,后续统计、对账全乱。遇到这种联动数据,要一次性把关联的都处理好。
最后说下权限和日志。生产库,不要随便拿高权限账号操作。改的时候最好有人协同,或者自己记录操作时间、SQL 语句、修改内容,方便后面排查。线上操作,尽量避开高峰时段。