一、存储过程是非常有用滴。例如,在常见的登录场景中,需要记录用户的登入记录,你可以使用编程语言来实现:
db.connect( "db_host" ).execute_sql( "select count(*) from user_info_table where username = 'you' and pass='123' " );
db.connect( "db_host" ).execute_sql( "insert into login_table( user_name, log_time )values( 'you', '2017_01_05' ) " );
在这里,第1步首先判断用户存不存在,第2步记录用户登录日志。
存储过程实现:login_user_and_save_result()的功能是执行用户登录操作、并记录用户的登录日志。
db.connect( "db_host" ).execute_sql( "call login_user_and_save_result('you', '123') " );
区别在于,编程语言实现需要执行2次数据库连接connect操作、2次编译sql操作execute_sql;login_user_and_save_result()则只需要1次connect,0次编译execute_sql操作,因为存储过程在创建之初就已经编译好了,只需要传参数就可以了。
这样在用户量逐步增长的情况下,存储过程可以为服务器省很多带宽、系统资源消耗,优势会慢慢显示出来。
如果,你的boss让你再加一层逻辑,只允许用户3次登录尝试,3次失败后,不允许登录。在编程语言级别的数据库操作会变的更加复杂一点。
arr_result = db.connect( "db_host" ).execute_sql( "select count(*) from user_info_table where username = 'you' and pass='123' and enable_login = 1" ); //
if( arr_result != 1 ) { //更新登入失败次数
db.connect( "db_host" ).execute_sql( "insert user_login_fail(username, pass) values( 'you', 'pass' ) " );
}
fail_count = db.connect( 'db_host' ).execute_sql( "select count(*) from user_login_fail where username = 'you'" );
if( fail_count > 3 ) {
db.connect( "db_host" ).execute_sql( "update user_info_table set enable_login = 0" );
}
在这里,你可以发现编程语言需要频繁的连接db、或者说要和数据库保持长时间的网络连接。如果,你把这些登录逻辑都放在login_user_and_result()里实现,你要做的只是传入参数username、pass,系统也只需要做1次连接db、0次编译,简单很多。
二、存储过程的作用不只在资源消耗上。现在,你的程序有两种方式登录,一种是在web端登录,一种是原生client端登录。假设,web端是使用java web实现,client端是使用visual c++来实现。如果,java web 和 visual c++在登录的时候都调用login_user_and_result(),就可以保持用户一致的登录行为,避免开发人员分别实现导致其他问题。其实,你还可以给存储过程添加各种数据库级别的权限,统一控制登入权限。