mysql实操(一)—使用存储过程模拟实现用户登录

存储引擎

对于我来说常用的存储引擎有:InnoDB和MyISAM
InnoDB:支持外键和事务,事务性表(如用户付款、用户权限)应该使用InnoDB作为存储引擎
MyISAM:不支持外键和事务,频繁读取(如select操作频繁)应该使用MyISAM作为存储引擎
show ENGINES;来查看支持哪些存储引擎
show table status from 数据库名;来查看数据库下的各表的详细信息,其中包括存储引擎
一个数据库下的各表的存储引擎可以是MyISAM和InnoDB混合的


创建用户系统表,并初始化一百万条测试数据

创建user_sys表,为注册用户的主要信息表,用户登录时涉及到事务,所以存储引擎为InnoDB,表结构如下图

mysql实操(一)—使用存储过程模拟实现用户登录_第1张图片

因为用户名是不能重名的,所以为user_name字段设置唯一索引,这样在程序端插入新用户时就不用对用户名进行判断了

user_name唯一索引截图

创建存储过程sp_initdb,实现向user_sys表中灌入一百万条测试数据,来模拟百万用户

BEGIN
    #Routine body goes here...
    declare num int DEFAULT 1;
    while num<=1000000 DO
        insert into user_sys(user_name,user_pwd) values(concat('user',num),'123');
        set num = num +1;
    end while;
END

调用存储过程:call sp_initdb();会报[Err]1055错误,在mysql配置文件/etc/my.cnf中的最后添加 sql_mode=’NO_ENGINE_SUBSTITUTION’,再重启mysql服务service mysqld restart

执行完存储过程后,user_sys中就有了 一百万条测试数据,如下图为前10条记录

mysql实操(一)—使用存储过程模拟实现用户登录_第2张图片


实现用户登录

需求:
1.判断用户名和密码是否匹配,匹配则返回这行数据,不匹配则返回一个错误行
2.不管用户是否登录成功,都记录一次用户日志表

首先创建用户日志表user_log,并初始化五百万条测试数据,存储引擎为MyISAM,表结构如下
mysql实操(一)—使用存储过程模拟实现用户登录_第3张图片
最开始设计表的时候是没有user_name字段的,如果没有user_name字段,则需要通过user_sys和user_log两表通过user_id字段来关联才知道用户名和它的日志时间,现在是一个一百万数据的表和 五百万数据的表,进行关联是非常慢的,而随着注册用户的增多和用户登录次数的增多,关联只会越来越慢,为了解决这个问题,在user_log表中添加了user_name这个冗余字段, 而适当的添加冗余字段,虽然不符合三范式,但是可以减少表的关联,是数据库优化的常见方法
创建存储过程sp_initlog,实现向user_log表中灌入五百万条测试数据,来模拟一百万用户登录产生的五百万条测试数据

BEGIN
    #Routine body goes here...
    DECLARE num int DEFAULT 1;
    DECLARE id  int;
    while num <= 5000000 DO
        set id = FLOOR(RAND()*1000000);
        insert into user_log(user_id,user_name,log_type) values(id,concat('user',id),'success');
        set num = num+1;
    end WHILE;
END

调用存储过程:call sp_initlog();执行完存储过程后,user_log中就有了 五百万条测试数据,如下图为前10条记录

mysql实操(一)—使用存储过程模拟实现用户登录_第4张图片

创建存储过程sp_user_login来实现模拟的登录需求

BEGIN
    #Routine body goes here...
    DECLARE uid int DEFAULT 0;
    DECLARE uname varchar(30) DEFAULT '';
    DECLARE upwd varchar(30) DEFAULT '';
    DECLARE result varchar(20) DEFAULT 'success';
    select id,user_name,user_pwd into uid,uname,upwd from user_sys where user_name=_user_name;
    if uid=0 THEN
        set result='user_name error';
    ELSE
        if upwd!=_user_pwd THEN
            set result='user_pwd error';
        end if;
    end if;
    insert into user_log(user_id,user_name,log_type) VALUES(uid,uname,result);
    select * from (select result) a,(select uid,uname) b;
END
参数为In _user_name varchar(30),In _user_pwd varchar(30)

调用存储过程sp_user_login(‘user1’,’123’);来模拟用户成功登录
成功登录返回值截图
日志表
成功登录日志截图

call sp_user_login(‘user1’,’123456’)来模拟用户密码错误的情况
密码错误返回值截图
日志表
密码错误日志截图

call sp_user_login(‘xiaosa’,’123’)来模拟用户名错误的情况
用户名错误返回值截图
日志表
用户名错误日志截图

注:因为为本地学习实操,所有没有完全使用命令行,使用navicat管理工具和命令行相结合的方式操作数据库。

你可能感兴趣的:(mysql,mysql)