邹同浩 许学添
(广东司法警官职业学院 广东省广州市 510520)
在数据库设计的过程中,经常遇到对于同类事物需要的信息不一样,为解决这一问题,需要针对不同的事物设计不同的数据表,数据表之间通过关键字段确定多种内联关系。如果把不同的事物放在同一张数据表中,不同的事物有不同的属性,这样创建一张表就很难进行输入和管理。例如,把人和物存在同一张表格内,人的属性有“性别”,而物没有这样的属性,存在同一张表中,很多字段对于彼此都是无效字段,增加了计算机处理负荷,从而暴露出数据库设计的庞大和复杂性。本文指出用split()函数减少数据库设计中的多表性和内联性,降低数据库设计的复杂性 ,尽最大可能的把不同的信息存储设计在同一张数据表中,减少表的数据表的数量和降低数据之间关联性,提高数据的设计效率,降低数据库的管理复杂度。
Split 函数是编程语言中使用于分割字符串一种函数,它返回一个下标从零开始的一维数组。它是在逻辑上对输入数据进行的分割,并不会在磁盘上将其切割成片存储[1]。
Split 函数格式:Split(expression[,delimiter [,count[, ompare]]])。如果用“.”作为分隔的话,必须写法,String.split("\."),这样才能正确的分隔开,不能用String.split(".");如果用“|”作为分隔的话,写法,String.split("\|"),这样才能正确的分隔开;“.”和“|”都是转义字符,必须得加"\";如果在一个字符串中有多个分隔符,可以用“|”作为连字符,比如,“acount=? and uu =? or n=?”,把三个都分隔出来,可以用String.split("and|or");
使用String.split 方法分隔字符串时,分隔符如果用到一些特殊字符,可能会得不到我们预期的结果。
在数据库设计的过程中,程序开发人员结合数据库的设计和程序设计中Split()函数特点,取长补短,优化数据库的设计,目标是降低数据库设计的复杂性和内联性。
程序员在数据库设计过程中,遇到同一个物品,数据表需要的字段不一样,给数据表的建立增加非常多的统计表格。或者物品较多,但统计量有很少,增加数据表的设计数量,又显得多余。还要通过设置主键和外键进行关联,这样会增加数据库的复杂度。我们试想,能否把数据放在一张数据表中,一张数据表能把所有物品的数据信息存储下来,共查询和统计。数据库设计时能否利用split()函数的字符分割功能解决这些问题。
在开发固定资产管理系统时,物品种类几千种,属性参数各不相同,在建立数据库时可能要几千个数据表。例如,台式计算机的参数有系统、CPU 型号、内存、主板等;办公椅的参数有类别、扶手类型、五星脚材质等,如果把这样的物品放在同一张数据表中,会出这样的情况,如表1 所示。
表1:汇总表
表2:拆分表1
表3:拆分表2
表4:改造后的汇总表
表5:成绩表
这样设计出来的数据表,冗余量太大,对于同一物品无效字段太多、数据表字段太多等一系列问题。查询物品的信息相互关联时,是否能够合并作为一个字段,需要统计的公用信息可以单列字段,这样就减少数据表的设计复杂性。假设对不同类物品单列一张数据表如表2、表3 所示。
这样精炼了数据表中的字段项,但增加了数据表的数量。后期会增加程序设计的复杂性。因此,我们考虑,根据用户的需求,比如一键查询出某个物品的所有信息,而不是单个信息。或者说,查询某个物品的单个信息和整个信息时等价的,或者没有实在意义,是否能通过程序设计,可以使数据库的表的数量最少,还能满足系统需求。
例如,在固定资产管理系统中,注重的是产品的存在及价值,对于具体参数不是统计重点,我们是否考虑不同的物品的参数仅仅用一个字段表示,如“参数说明”。数据表可以设计如表4 所示。
这样的数据库设计方法应用必须满足两个条件。第一该物品字段统计字段次不齐或无统计价值;第二可以大大降低数据库中数据表的数量。数据表这样的设计,会出现统计量统计的问题,我们通过程序设计中Split()函数可以解觉数据表数量与程序设计的问题[2]。例如通过split()函数可以吧表4 中的“参数说明”的字段信息通过split()函数进行拆分提取,分别以“:”和“;”进行拆分。当然我们可以根据统计需要以不同的符号代表进行多次拆分。利用String 类中的split 函数进行分割,同时将结果存放在一个二维数组中。问题在于怎么利用两次split 分割后放在数组的两个维度中,过程不再撰述。数组为引用型,需要申请内存。
通过程序设计中split()函数字符串的分割功能,可以吧数据表的存储有固定格式的字段内容提取后根据需要进行拆分,提取需要的内容。完成统计功能。对于学生成绩管理系统,这种功能更能体现出来。一张数据表就可以解决。例如表5 如下,统计一下“张三”的总成绩。
以上两种通过程序设计中Split()的函数来解决数据库的设计问题及统计量的问题,从而大大的降低了数据库设计的复杂度,尤其在数据表的数量上会大大的减少,减少了数据库的维护性[3]。仅仅在录入数据库时,程序上一定要做格式上的验证,防止输入不能被split()函数识别的问题,这点在程序设计之初,必须要考虑的。
Split()函数在数据库设计查询过程中,显示其优越性。例如,全校不同专业的学生可以放在同一张表格内,三个字段:学号、姓名、成绩,在成绩这个字段中,可以把学生各科成绩放在同一个字段中,比如:语文:90;数学:96;英语:98;通过冒号和分号区别门课和成绩。如果学生查询总的成绩时,直接查询,如果学生查询“语文”成绩时,调用Split()函数直接单独显示语文成绩。如统计总成绩、平均成绩等都可以通过Split()函数进行实现。虽然用Split()函数可以提高数据的设计效率,但其的开销比较大,因此Split()函数比较适合较小规模的数据库设计,而且对服务器的要求比较高。
Split()函数的在数据库设计的应用必然会增加程序的计算效率。程序中用到for 循环嵌套,时间复杂度达到O(n2)。文中提到split()函数在计算机上仅仅是逻辑分割,并不会在磁盘上将其切割成片存储这样对服务器的性能要求就会提高,增加了服务器的符合。如果通过增加数据表的方法来开发,程序的复杂度可以达到O(n),但数据库的维护复杂度就会增加[4]。
在字符串截取字符串应用方面,Split()函数没有其优越性,StringTokenizer 在截取字符串中效率最高,不论数据量大小,几乎持平。SubString 则要次之,数据量增加耗时也要随之增加。Split()函数则是表现一般,究其原因,split 的实现方式是采用正则表达式实现,所以其性能会比较低。
在字符串拆分应用方面,以看出Split()方法比StringTokenizer类的拆分方法更加简洁和方便后续处理。Split()方法可以匹配正则表达式,而StringTokenizer 则不行。且大多数时候拆分得到的子字符串是要进行操作的,而StringTokenizer 类操作子字符串是靠遍历进行的,比较繁琐,相比之下运用数组进行下标操作就方便多了,事实上官方也不推荐用StringTokenizer 类生成对象的方法来进行字符串的拆分操作了。
根据用户规模和实际需求,寻求数据库设计方法,重效率还是重管理,数据库有不同的设计方法。同一张数据表中,关联性强的属性可以合并后存入同一字段中,需要统计字段可以单列出来建立字段,这样只要折中找出一个最优点,就可以减少数据表内冗余,减少数据库中数据表的数量和数据表间的关联程度。对于合并项,可以利用Split()函数进行分割提取,因Split()函数开销较大,但目前随着服务器性能的提高及云服务能力的急速提升,开销已不是主要考虑的问题,降低数据库设计的复杂度和内联性是我们考虑的重点问题。