2014年年初的时候,接到运营部老大给的一个游戏数据库数据管理的系统,pm把rp图画好之后,就让我自己做了,所有的让我一个人用14个工作日昨开发完。

下面就把这个小系统的开发体会记录一下,免得以后忘记了。

一、总体规划

时间计划:

2014-2-15 ~ 2014-3-6,共14个工作日,开发时间为10个工作日,调试和修改时间为4个工作日。时间比较紧张,而且pm总是催来催去,时不时来一句:做到哪里了,搞得我心烦意乱。

功能模块:

主要:系统由前台和后台两个部分组成,前台是经分人员和产品研发人员使用的基本界面,后台是系统配置管理部分,主要有管理员和epr同事操作,用于对游戏业务和数据库/表进行相关授权。

这两个部分主要区分方式是权限控制,系统中有一张用户类型数据表,根据用户类型区分用户操作后台或前台的权限。而对于业务表的操作(增删查改),则必须由特定人员给某用户进行授权之后,该用户才可以操作。

基本组成:业务类、用户操作类(用户授权查询,用户授权,权限类型、用户列表、业务数据表配置与显示、业务数据库配置与显示),日志记录类(前台操作记录、后台操作记录)。

二、详细设计

日志记录类:

1、前台操作记录,即“经分人员和产品研发人员”和后台操作人员使用前台的时候,产生的日志记录。
2、后台操作记录,即系统管理员和epr同事进行后台操作产生的日志记录。

日志记录类使用两个相同数据结构的数据表,使用同一个方法进行入库:

/**操作记录*type:1后台操作记录,2:前台操作记录**/function opeartionLog($type,$opName,$opDescription,$sql){$c=new CommonModel();if($type==1){$data=array('vAdmName'=>cookie('username')?cookie('username'):'test用户','vAdmOpName'=>$opName,'vAdmOpDescription'=>$opDescription,'sqlType'=>$sql,'date'=>date("Y-m-d H:i:s"));$c->c_insert('tbadmoplog',$data);}else if($type==2){$data=array('vUserName'=>cookie('username')?cookie('username'):'test用户','vUserOpName'=>$opName,'iUserOpDescription'=>$opDescription,'sqlType'=>$sql,'date'=>date("Y-m-d H:i:s"));$c->c_insert('tbuseroplog',$data);}}

用户操作类:

用户操作类整TMD是个烦人的事情,因为游戏业务、数据库列表、数据表列表、我都需要通过API获取,而且返回的数据结构还经常会变化,也不告诉我(我们不在同一地点办公),后面还有更烦人的呢。

基本流程:

游戏业务授权--->业务数据库授权--->业务数据表授权(根据用户名进行授权,权限类型包括:查询、更新、删除、新增、上传、下载等)

游戏业务授权和业务数据库授权以及用户授权还都很简单,直接通过api拉取游戏业务或业务数据库列表,授权入库即可。

权限控制:

程序中的每一个操作模块在类中都是一个独立的方法,所以授权的时候,我直接在类初始化的时候,获取请求方法名称,然后strtolower()操作下,再根据配置中配置的信息,查询该用户是否有本方法的某些操作权限,有的话,进行后续操作,没有的话直接返回错误信息。其实之前也考虑过设计成类似linux的分组管理,对组进行授权,但后来发现不能满足我们的需求,也可能是我对linux的权限管理理解的不够深刻。

下面是代码:

控制其中的初始化方法:

<?php
ini_set('memory_limit','2024M');
ini_set('max_execution_time',-1);
set_time_limit(0);
header("Content-type:text/html;charset=utf-8");/*****************************************************************************
*功能:业务类控制方法
*作者:byu
*时间:2012-02-08
*****************************************************************************/class ServiceAction extends Action {/*初始化方法,权限控制方法*/public function _initialize(){if(ACTION_NAME=="downloadtabledata"){$post=$_GET;}else{$post=$_POST;}$authList=C('AUTH');$public=array("downloadtabledata","uploadedit","getdatabynum","ajax_upload","ajax_adddata","editonedataview","deleteone");if(in_array(ACTION_NAME,$public)){$authType=$authList['service'][ACTION_NAME];/************业务和表-start***************8****/$id=explode("@",$post['id']);$table=$post['table'];/************业务和表-end*******************///dump($iSerID."&".$table."&".$authType);$permit=auth($id[0],$id[1],$table,$authType);if(!$permit){if($this->isAjax()){echo "";}else{echo "对不起,权限不足,请向管理员申请";}exit();}else{}}else{}}

综合权限控制方法:

/**综合性权限控制方法*参数:业务ID,表名称,权限类型(英文)*返回:boolean*/function auth($iSerID,$dataSourceID,$table,$authType){$c=new CommonModel();$sql="select iAuthID from tbauthlist where vAuthName='{$authType}'";$result=$c->c_sql($sql);$username=cookie("username");$iAuthID=$result[0]['iAuthID'];$where=array('iUserName'=>$username,'iAuthID'=>$iAuthID,'iSerID'=>$iSerID,'dataSource'=>$dataSourceID,'table'=>$table);$permit=$c->c_getCount($table="tbuserauth",$where);if($permit){return true;}else{return false;}}

配置文件中配置的信息:

/***********************配置权限***********************************/'AUTH'=>array('service'=>array('uploadEdit'=>'upload','index'=>'select','ajax_adddata'=>'insert','getdatabynum'=>'select','ajax_upload'=>'upload','uploadtabledata'=>'download','editonedataview'=>'update','deleteone'=>'delete','downloadtabledata'=>'download'))

另外,数据库中的权限表还记录着一些信息,就不贴出来了。

业务类:

业务类真TMD烦人,耗费了我好长时间,其实大部分时间不是在开发商,都TMD耗费在交流上了,为啥呢?因为他们那边的业务都没有跟我说说清楚,让PM去问清楚啊,又问的不明不白,搞得我浪费了大把的时间。

下面把详细设计、开发记录一下。

概况:本模块中使用jquery的树形结构设计,显示的数据是登陆用户有权限的游戏业务、业务数据库、业务表。

树状结构中都是一步步的异步获取,没什么可说的。下面说说对游戏数据表的操作。

游戏数据表操作:

根据表,会获取表结构,然后显示在右侧的特定区域,获取数据表,因为之前说的之后npsSQL数据库,后来,又来了个mysql数据库,再后来,连sql server 、oracle、sqlite也都出来了,好吧,我要写一个方法,根据不同的数据库类型获取不同的查询表结构的语句,以及后来的“增删查改”都要修改成不同的语句,真TMD之前信息不通畅,我以为很简单的,搞得程序太耦合,后来花了大把的时间修改。

部分代码:

/**根据数据库类型提取查询表结构的语句*@param $DbType string*@param $tableName string*@return string*/function getSqlForStructureByDB($DbType,$tableName){$DbType=strtolower($DbType);$sql=array('mysql'=>'show columns from %s','sqlite'=>NULL,'sqlserver'=>NULL,'oracle'=>NULL,'npgsql'=>"SELECT * from information_schema.columns where table_name = '%s'"// column_name, data_type);foreach($sql as $k => $v){if($DbType==$k){$sql=sprintf($v,$tableName);return $sql;}}}
/**查询表数据*@param $iSerID*@param $methodName string*@param $sql string or array*@return array*/function getTableData($iSerID,$dataSourecID,$methodName="GetDataSet",$sql){//第一步获取数据源$db = getDataSourceBySerID($iSerID);$db = filterDataSourceByDataSourecID($dataSourecID,$db);$result = execute($methodName,$db,$sql);//解析$result = simplexml_load_string($result);$result = objectToArray($result);//$result = getTableName($result);//处理数据$date=array();$fix='';foreach($result['Tables']['DataTable']['Columns']['DataColumn'] as $k => $v){$data['title'][$k]=$v['Name'];if($v['Name']=='id'){$fix=$k;}}//dump($data['title']);//$data['title'][]="操作";foreach($result['Tables']['DataTable']['Rows']['DataRow'] as $k => $v){foreach($v['ItemArray']['DataItem'] as $k1 => $v1){//dump($data['title'][$k1]);$data['data'][$k][$data['title'][$k1]]=$v1['Value'];if($k1==$fix){$del_id=$v1['Value'];}}$data['del'][$k]=$del_id;}return $data;}/**获取一条数据的信息*@param $iSerID int*@param $methodName string*@param $sql string or array*@return array*/function getOneDataInfo($iSerID,$dataSourecID,$methodName="GetDataSet",$sql){//第一步获取数据源$db = getDataSourceBySerID($iSerID);$db = filterDataSourceByDataSourecID($dataSourecID,$db);$result = execute($methodName,$db,$sql);//解析$result = simplexml_load_string($result);$result = objectToArray($result);//dump($sql);$data=array();foreach($result['Tables']['DataTable']["Rows"]["DataRow"]["ItemArray"]["DataItem"] as $k => $v){$data[$k]['columnName']=$v['ColumnName'];$data[$k]['value']=$v['Value'];}return $data;//dump($data);//dump($result['Tables']['DataTable']["Rows"]["DataRow"]["ItemArray"]["DataItem"]);}/**新增数据*@param $iSerID int*@param $methodName string*@param $sql string or array*@return 返回的数据类型与$methodName的类型有关 默认返回int*/function add($iSerID,$dataSourecID,$methodName="GetDataSet",$sql){//第一步获取数据源$db = getDataSourceBySerID($iSerID);$db = filterDataSourceByDataSourecID($dataSourecID,$db);//dump($sql);$result = execute($methodName,$db,$sql);//dump($result);return $result;//dump($result);}/**公共执行方法*@param $iSerID int*@param $methodName string*@param $sql string or array*@return 返回的数据类型与$methodName的类型有关 默认返回int*/function common($iSerID,$dataSourecID,$methodName="GetDataSet",$sql){//第一步获取数据源$db = getDataSourceBySerID($iSerID);$db = filterDataSourceByDataSourecID($dataSourecID,$db);//dump($dataSourecID);$result = execute($methodName,$db,$sql);return $result;}/**通过接口执行sql方法*$MethodName:MethodName类型,字符串。ExecuteNonQuery  执行第一条sql,返回影响行数。GetDataSet  执行第一条,返回结果集。ExecuteScalar  执行第一条,返回单个值,第一个字段的值。ExecuteSql  执行所有sql,返回影响行数*$db:数据库连接信息,数组*$Sqls:sql语句,数组*/function execute($MethodName="ExecuteNonQuery",$db,$Sqls){$requestparam = array("MethodName"=>$MethodName);$requestparam['DB'] = array("DBType"=>getDBType($db['DbType']),//数据库类型,1=mysql,2=sqlite,3=sqlserver,4=oracle,5=npgsql"ConnectionString"=>"server={$db['serverip']};database={$db['DbName']};user id={$db['UserName']};password={$db['UserPwd']};port={$db['Port']}",//数据库连接串);//dump($requestparam);if(!is_array($Sqls)){$requestparam["Sqls"] = array($Sqls);}else{foreach($Sqls as $v){$requestparam["Sqls"][]=$v;}}//$requestparam["Sqls"] = array("update tbname set a=a where id=xxx","insert tbname() values()");$dbproxyurl = "http://epr.dbproxy.qq.com/DBProxy.ashx";//dump($requestparam);$par = json_encode($requestparam);$result=httpPostRequest($dbproxyurl,$par);//dump($result);return $result;}/*** 发送http post请求* @param $url string* @param $date json* @param $method string * @param $timeout int* @return int 是否成功*/function httpPostRequest($url,$data,$method="POST",$timeout=120){$opts = array('http'=>array('method'=>$method,'header'=>'Content-Type:application/x-www-form-urlencoded','content'=>$data,'timeout'=>$timeout));//dump($data);$context = stream_context_create($opts);$result = file_get_contents($url,false,$context);return $result;}
/**复合型对象数组转化成对象*@param $str object or array*@return array*/function objectToArray($str){if(is_object($str)){$str=get_object_vars($str);$str=objectToArray($str);}else if(is_array($str)){if(count($str)>0){foreach($str as $k => $v){$str[$k]=objectToArray($v);}}}return $str;}/***判断是否二维数组*/function isTwoArray($array){/*判断是否为二维数组*/$isTwoArray;if(is_array($array)){foreach($array as $v){if(is_array($v)){$isTwoArray=true;}else{$isTwoArray=false;}}}return $isTwoArray;}

以上是一些基本的代码。

数据表操作:

主要包括:查询,单条新增,批量追加新增,全量覆盖新增,删除,编辑等部分。

查询的话,就是,获取游戏业务ID,获取数据库连接信息,配置sql语句,调用方法,

返回数据,处理数据,前台展示。

批量追加新增和全量覆盖新增都是先上传excel表格,在读取,组合成sql语句数组,

调用方法。全量覆盖新增会先删除表中的所有数据,在insert上去。

删除和查询类此,就sql语句不同。

编辑的话,把我折腾的,哎。编辑和查询类似,只是sql语句不同。

由于这个小系统要进行分布式部署,每个业务数据结构都不一样,

创建的主键、索引等等,所以要做成自动化的,不管是什么数据表结构,

都能进行自动识别。所以编辑的时候,会根据全部字段去查询,

但是一旦有时间类型(time、date等),就查不出来,后来发现是编码问题

,他们那边调好之后,就可以了,后来发现,一旦条件中有中文,又不行了,这个也可能是编码问题,但是,拖拖拉拉,到现在还没有人帮我解决。我感到好凄凉。。。


到目前为止,已经部署了五个系统上。

这个小破系统,我还以为做的多好,真TMD的傻技术含量都没有。

上次到博雅互动面试,我怎么就说这个系统好了,我应该说我参与开发了元数据系统的,哎,我真的太。。。

游戏数据库数据管理系统开发体会相关推荐

  1. 心音数据库_心音数据库综合管理系统开发与应用

    摘要:心音信号是由于心脏的周而复始地跳动以及血液对心室壁的冲击等因素综合作用产生的,包含了人体生理状态等信息,是最为重要的人体信号之一.心音信号中同时含有大量关于心脏病理状况的相关信息,反映了心脏及心 ...

  2. InfoQ —— 腾讯游戏大数据服务场景与应用

    简介 周东祥,本人从2010年毕业进入腾讯互动娱乐部门工作,一直致力在腾讯游戏运营开发工作.先后负责SAP业务受理系统,盗号自助系统,元数据系统以及近2年在腾讯游戏大数据运营开发中积累大量的大数据开发 ...

  3. javaWeb基于SSM框架开发的社区医疗数据管理系统【项目源码+数据库脚本+报告】

    一.项目简介 本项目是一套基于SSM框架开发的社区医疗数据管理系统,主要针对计算机相关专业的正在做bishe的学生和需要项目实战练习的Java学习者. 包含:项目源码.数据库脚本等,该项目可以直接作为 ...

  4. 计算机毕业设计Java智慧社区信息管理系统开发(源码+系统+mysql数据库+lw文档)

    计算机毕业设计Java智慧社区信息管理系统开发(源码+系统+mysql数据库+lw文档) 计算机毕业设计Java智慧社区信息管理系统开发(源码+系统+mysql数据库+lw文档) 本源码技术栈: 项目 ...

  5. Java计算机毕业设计体育馆数据管理系统源码+系统+数据库+lw文档

    Java计算机毕业设计体育馆数据管理系统源码+系统+数据库+lw文档 Java计算机毕业设计体育馆数据管理系统源码+系统+数据库+lw文档 本源码技术栈: 项目架构:B/S架构 开发语言:Java语言 ...

  6. java毕业设计大学生体测数据管理系统Mybatis+系统+数据库+调试部署

    java毕业设计大学生体测数据管理系统Mybatis+系统+数据库+调试部署 java毕业设计大学生体测数据管理系统Mybatis+系统+数据库+调试部署 本源码技术栈: 项目架构:B/S架构 开发语 ...

  7. 开发医院管理系统心得体会_如何开发医院内容管理系统

    开发医院管理系统心得体会 入门 对于医院来说,在其在线站点上提供出色的患者和医师体验非常重要. 如果您为医师提供有用的在线工具,则医师很有可能会将患者转介至您的医院. 患者也是如此. 如果您通过向他们 ...

  8. 「数据管理系统」顶级数据库管理系统供应商

    确定哪种类型的数据库或数据库服务最适合您的企业的最佳方法是什么?这完全取决于您需要什么类型的用例.在本文中了解更多信息. 基本上,我们每天使用的所有数字信息都在世界某处的数据库管理系统或存储阵列中.这 ...

  9. 管理系统开发一: winform连接sql数据库

    Winform连接SqlServel数据库进行居民管理系统开发. 最近负责了一项居民管理系统,开始的我是懵的,因为除了大学学的那一点后,我之后就没怎么接触而且连大学学的那点也基本上还给老师了,但是开发 ...

  10. 数据库数据规范化看不懂_数据库管理系统中的规范化

    数据库数据规范化看不懂 DBMS中的规范化 (Normalization in DBMS) Every table must have a single idea. The method by whi ...

最新文章

  1. smartcrop.js智能图片裁剪库
  2. Sql Server2005 Transact-SQL 新兵器学习总结之-数据类型
  3. SVM中的Karush-Kuhn-Tucker条件和对偶问题
  4. 叙述计算机网络拓扑结构的定义,计算机网络拓扑结构的定义
  5. mongodb 启动脚本和配置
  6. cvMat结构体详解
  7. java.io.tmpdir
  8. Onvif学习笔记(1)ONVIF Test Tool 的使用
  9. 驾驭synchronize的方法
  10. 只有1kb的清理软件_1kb文件夹快捷方式病毒专杀工具下载
  11. 打开office报错提示向程序发送命令时出现问题
  12. 高盛报告:人工智能、机器学习和数据将推动未来生产力的发展
  13. html5跳动的心电图,jquery制作心电图跳动特效
  14. 键盘win键和alt互换了怎么办
  15. python程序扩展名 py、pyc、pyo、pyd文件区别
  16. 【Vue.js】Vue.js中常用的UI组件库和Vue Router
  17. 通识~FIR数字滤波器设计讲解
  18. Linux 文字转语音
  19. BS 476-7 常做的产品有哪些?纤维板适用这个标准吗?
  20. 电脑端上面完成转换的CAD转DWF格式如何进行分享?

热门文章

  1. 快播将关闭QVOD服务器 清理低俗和盗版内容
  2. 帝国CMS灵动标签如何调用父子栏目连接和名称导航
  3. 发那科syst178_南京发那科机器人示教器维修芯片级维修{苏州机器人维修}
  4. postgresql中DROP OWNED BY user_name对普通用户和只读用户的区别
  5. Ibeacon一维小项目
  6. Applet 小应用程序查看器 乱码(小方块)
  7. Java 进阶 hello world! - 中级程序员之路
  8. python中print打印输出
  9. rtx web 分级管理系统 二次开发
  10. Guarded Blocks 保护块