我发现很多教科书,数据库教程视频都涉及到了存储过程,但是我看过很多开源的php项目,里面几乎就没有用到存储过程啊,我看过java项目倒是有部分项目用到过存储过程,这是为什么呢?
已经从业或者开发过大型项目的程序员们你们在实际工作中用到过他吗?
还有就是存储过程里面的逻辑几乎我都可以用程序(java,php)写,为什么还要直接在数据库里面写呢?(换句话说:存储过程的意义是什么?)
ringa_lee
一、存储过程是非常有用滴。例如,在常见的登录场景中,需要记录用户的登入记录,你可以使用编程语言来实现:
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(),就可以保持用户一致的登录行为,避免开发人员分别实现导致其他问题。其实,你还可以给存储过程添加各种数据库级别的权限,统一控制登入权限。
我觉得存储过程主要有两个优势。一是在数据库端执行,避免网络通讯开销,从而效率较高。二是存储过程可以直接利用数据库提供的一些高级抽象,比如事务、触发器、重写规则等。
如果完全不用存储过程,数据库只是一个提供增删改的存储后端罢了,它提供的高级功能就浪费了。可以用存储过程构建业务功能,前端只是调用这些功能,类似于API的效果。
实施,运维可以自己改,不然屁大点业务都要返回到开发这边改代码,编译,发补丁
我的项目中,没有使用到存储过程。倒是用过视图!项目大些的公司可能有些需要,有专门Dba的单位!
ods,数据仓库等传统数据中心的数据批处理,或者olap还是会用存储过程的
有DBA用存储过程或者简单的逻辑用,日志写到数据库中...个人觉得写到代码里简单些
效率高,有时候职责分得很细的时候后端未必能随意访问数据库
我所在的项目里存储过程是用得比较多,特别是报表,大部分用存储过程。除了上面的几个优点,还有就是存储过程的扩展性会比较好,比如说跨库、分表union,一些动态拼接sql的,存储过程方便,也直观,对于日后分布式,也只是在存储过程内拼接修改。
我一般用来做数据整理,迁移。比如网站整改,数据结构变了,某某表被拆了,某某表合并了,某某字段数据格式有变等等情况,反正我只在站点升级的时候需要用到。其他查询一般能用代码实现的都不想用存储过程实现
有逼格的公司,会专门有DBA这样一个职位,才看不上程序员写的SQL,复杂的业务写个几千行存储过程实现。存储过程本身的优点就不具体说了。
一、存储过程是非常有用滴。例如,在常见的登录场景中,需要记录用户的登入记录,你可以使用编程语言来实现:
在这里,第1步首先判断用户存不存在,第2步记录用户登录日志。
存储过程实现:login_user_and_save_result()的功能是执行用户登录操作、并记录用户的登录日志。
区别在于,编程语言实现需要执行2次数据库连接connect操作、2次编译sql操作execute_sql;login_user_and_save_result()则只需要1次connect,0次编译execute_sql操作,因为存储过程在创建之初就已经编译好了,只需要传参数就可以了。
这样在用户量逐步增长的情况下,存储过程可以为服务器省很多带宽、系统资源消耗,优势会慢慢显示出来。
如果,你的boss让你再加一层逻辑,只允许用户3次登录尝试,3次失败后,不允许登录。在编程语言级别的数据库操作会变的更加复杂一点。
在这里,你可以发现编程语言需要频繁的连接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(),就可以保持用户一致的登录行为,避免开发人员分别实现导致其他问题。其实,你还可以给存储过程添加各种数据库级别的权限,统一控制登入权限。
我觉得存储过程主要有两个优势。一是在数据库端执行,避免网络通讯开销,从而效率较高。二是存储过程可以直接利用数据库提供的一些高级抽象,比如事务、触发器、重写规则等。
如果完全不用存储过程,数据库只是一个提供增删改的存储后端罢了,它提供的高级功能就浪费了。可以用存储过程构建业务功能,前端只是调用这些功能,类似于API的效果。
实施,运维可以自己改,不然屁大点业务都要返回到开发这边改代码,编译,发补丁
我的项目中,没有使用到存储过程。倒是用过视图!项目大些的公司可能有些需要,有专门Dba的单位!
ods,数据仓库等传统数据中心的数据批处理,或者olap还是会用存储过程的
有DBA用存储过程或者简单的逻辑用,日志写到数据库中...个人觉得写到代码里简单些
效率高,有时候职责分得很细的时候后端未必能随意访问数据库
我所在的项目里存储过程是用得比较多,特别是报表,大部分用存储过程。
除了上面的几个优点,还有就是存储过程的扩展性会比较好,比如说跨库、分表union,一些动态拼接sql的,存储过程方便,也直观,对于日后分布式,也只是在存储过程内拼接修改。
我一般用来做数据整理,迁移。比如网站整改,数据结构变了,某某表被拆了,某某表合并了,某某字段数据格式有变等等情况,反正我只在站点升级的时候需要用到。其他查询一般能用代码实现的都不想用存储过程实现
有逼格的公司,会专门有DBA这样一个职位,才看不上程序员写的SQL,复杂的业务写个几千行存储过程实现。
存储过程本身的优点就不具体说了。