对于我来说常用的存储引擎有:InnoDB和MyISAM
InnoDB:支持外键和事务,事务性表(如用户付款、用户权限)应该使用InnoDB作为存储引擎
MyISAM:不支持外键和事务,频繁读取(如select操作频繁)应该使用MyISAM作为存储引擎
show ENGINES;来查看支持哪些存储引擎
show table status from 数据库名;来查看数据库下的各表的详细信息,其中包括存储引擎
一个数据库下的各表的存储引擎可以是MyISAM和InnoDB混合的
创建user_sys表,为注册用户的主要信息表,用户登录时涉及到事务,所以存储引擎为InnoDB,表结构如下图
因为用户名是不能重名的,所以为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条记录
需求:
1.判断用户名和密码是否匹配,匹配则返回这行数据,不匹配则返回一个错误行
2.不管用户是否登录成功,都记录一次用户日志表
首先创建用户日志表user_log,并初始化五百万条测试数据,存储引擎为MyISAM,表结构如下
最开始设计表的时候是没有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条记录
创建存储过程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管理工具和命令行相结合的方式操作数据库。