APP下载

基于排队的数据库表数据插入方法的设计与实现

2017-01-16顾保磊

武汉轻工大学学报 2016年4期
关键词:数组字段数据表

顾保磊,吴 云

(武汉工程科技学院,武汉 430200)

基于排队的数据库表数据插入方法的设计与实现

顾保磊,吴 云

(武汉工程科技学院,武汉 430200)

目前网络版的软件越来越多,这些软件都需要使用数据库,都存在多个用户同时访问数据库表,特别是对数据库表进行插入操作时,由于操作的并行性,容易获得相同的编号。主要针对获取相同编号的问题,提出了一种数据库操作并行度较高的方法,即采用公共动态数组存储插入信息,排队获取编号,从而避免了同一编号的多次获取。

数据库表; 数据插入方法; 动态数组;排队

1 引言

随着计算机硬件及网络的飞速发展,单机版的软件需求越来越少;但网络版的软件需求却越来越多。无论是B/S、C/S模式的网站,还是Android手机的应用APP,都要使用数据库,且存在多个用户同时访问数据库,甚至对数据库几乎同时进行增、删、改、查等操作[1]。

几乎每个数据表中都有编号(id)字段,且该字段是整型类型、记录内容具有不相同的特征:

(1)通过SQL语句“select max(id) from tablename”获取当前数据表的id字段最大的值[2],再令其加1,这种做法的算法复杂度较低,但在频繁删除、插入记录的表中,容易出现由于大量未使用的编号而使插入记录的编号急剧上升的问题。

(2)通过各种算法检测有、无由于删除记录而产生未使用的编号。若有,确定其中一个未使用的编号,若无,则获取最大编号并加1,这种做法虽然解决了表中编号急剧上升的问题,但算法复杂度明显增加,系统开销也增加。

上述两种做法都先进行一次或多次查询和数据处理,再将结果和相关数据插入表中。在多个用户同时进行增、删、改、查、操作时,将出现异常错误。

2 解决异常错误的思路

出现上述异常主要是由于多个用户同时对数据库进行插入和特殊的查询造成的,属数据库并发操作问题[3],即出现A用户对数据表T执行查询语句,获得编号后,执行相应的插入语句之前,B用户也对数据表T执行查询语句获得了相同的编号;此时,如果数据表T的编号字段有唯一性检查,B用户进行插入操作时,将出现异常错误。

针对该问题,很多数据库软件本身提供一种解决方案,即锁。一般需要在事务中对数据表加“X锁”,待使用查询语句并处理获得数据表id的值插入数据以后,再解锁[4]。锁属于数据库的高级应用,这种做法需要的步骤比较多,也较麻烦,且并发性不好[5]。

有没有简单且比较容易实现的做法呢?排队是一个常见的解决方法。

排队,即如果有用户正在对数据库表进行插入操作,包括为插入语句服务的查询操作时,任何其他对数据库表进行插入操作及相关操作全部暂停,并按请求的先后顺序排队等候;如果当前的插入操作结束,则按排队的先后,唤醒等候的插入操作。算法的流程图如图1所示。对数据库的所有数据表进行插入排队,虽然算法简单且解决了上述问题,但却降低了数据库操作的并行性,使数据库操作效率严重降低。

图1 对数据库所有的表进行插入操作排队流程图

为提高并行操作的效率,经研究发现,如果不同的用户同时对不同的数据库表进行插入操作,不会产生重复编号的问题,即无需排队。只有不同用户对同一数据库表同时进行插入操作时才需要排队,虽在一定程度上增加了算法的复杂度[6],但在数据库操作的并行性方面有明显的提高。算法的流程图如图2所示。

图2 对同一数据库表同时进行插入操作排队流程图

经进一步研究发现,插入记录的操作分为编号的查询获取和数据插入两个阶段。不同用户对同一个数据表的同时插入操作产生问题主要是因为编号。不能获取同一编号,即只需通过一定的算法确保不同的用户插入操作获取不同的编号,且在数据插入后,整个数据库表中的编号具有唯一性。算法的流程图如图3所示。

图3 对同一数据库表同时进行获取编号的操作排队流程图

该算法进一步提高了数据库插入操作的并行性,且算法的复杂程度没有明显的增加。

3 具体的实现步骤

为了能以最快的速度获得唯一的编号,这里对同一数据库表的插入请求采用排队获取编号的方法,具体算法流程如图4所示。

图4 对同一数据库表同时进行获取编号的操作排队流程图

上述算法中,创建了一个公共的动态数组,在用户请求对数据库表进行插入数据时,增加一个元素(自定义insertstate类对象),包括排队的编号,发出插入请求的用户名,需要插入数据的数据库表名称、插入的SQL语句,获取的插入编号,操作状态等;插入操作完成后,删除动态数组中相应记录。

3.1 动态数组ArrayList类

ArrayList类是C#.NET处理的动态数组,可封装集合类[7];这是一个由包含单一数据值的数据项组成的集合, 具有动态增加和减少元素的优点。ArrayList中数据项是通过Add()方法添加的,通过RemoveAt()方法删除。定义创建一个公共的动态数组insertarray的代码如下:

public static ArrayListinsertarray

= new ArrayList();

下面是insertstate类的定义,其对象是insertarray的元素:

public class insertstate

{ publicinsertstate(){}

publicinsertstate(int id, String username,

Stringtabelname,String strsql,inttableid,intopstate)

{ this.id = id;this.username= username;this.tabelname = tabelname;

this.strsql = strsql;this.tableid = tableid; this. opstate= opstate;

}

private intid; //排队的编号

private String username; //发出插入请求的用户名

private String tabelname; //需要插入数据的表名称

private String strsql; //插入的SQL语句

private inttableid; //获取的编号

private intopstate; //操作状态

}

当G用户对表T1发出插入数据请求时,动态数组内容如表1,可采用:

int x1=getnum(”T1”);//获取排队的状态,-2表示已获取,-1表示正在执行获取操作,大于等于1的值表示排队的序号。

insertstatetemp = new insertstate

(7,“G”,”T1”,”……”,-2,x1);

insertarray.Add(temp);

语句将获取编号的请求送入动态数组进行排队,并用while等语句不断对状态检测,直至执行完获取编号的操作,排队结束。

表1 动态数组内容

编号用户名表名插入语句获取的编号状态1AT1……31-22BT2……41-23CT1……-2-14DT1……-215ET2……-2-16FT2……-21

while(x1> 0) { Thread.Sleep(50);

//暂停50毫秒

x1 = checkstate(temp);//获取状态

}

设对表T1执行获取编号操作结束,在将获取的编号值写入动态数组的同时,必须也将排队中的同一表的状态都减1,此时用户D的执行状态为0,表示处于执行的就绪状态。

if(x1==0) {plusstate(temp);//将处于就绪状态的状态减1,表示进入执行状态

//执行获取编号操作

}

获取编号后,排队即结束,可以并行执行插入语句。插入操作完成后,采用

insertarray.RemoveAt(count);//将第count个元素移除

语句将相应元素删除。

3.2 获取插入编号

针对某数据表进行获取编号(id字段)操作,首先用SQL语句“select max(id) from tablename”和“select count (*) from tablename”[8]获取当前数据库表的最大编号和记录个数,如果记录数小于最大编号,如表2所示,即存在未使用的编号2,5;如果记录数等于最大编号,如表3所示,即不存在未使用的编号。

表2 数据库表T1

表3 数据库表T2

(1)如表2所示,存在没有使用过的id编号2和5,首先确定并返回编号2,到公共的动态数组insertarray(如表4所示)中检测,发现存在表T1且编号为2的元素,则以编号2为开始,重新查找新的未使用的编号,确定并返回编号5,到公共的动态数组insertarray中再检测,动态数组insertarray中不存在表T1且编号为2的元素,则将该数值写入相应的元素中,如表5所示。

(2)如表3所示不存在没有使用过的编号,返回表中id字段的最大值4,将最大值4加1得到编号5,再到公共的动态数组insertarray(如表4所示)中检测,发现存在表T2且编号为5的元素,则以5再加1得到编号6,再次到公共的动态数组insertarray中检测,动态数组insertarray中不存在表T2且编号为6的元素,则将该数值写入相应的元素中,如表5所示。

表4 公共的动态数组insertarray

编号用户名表名插入语句获取的编号状态1AT1……2-22CT2……5-23ET1……-2-14FT2……-2-1

表5 公共的动态数组insertarray

编号用户名表名插入语句获取的编号状态1AT1……2-22CT2……5-23ET1……5-14FT2……6-1

4 总结

本文主要以具有惟一性的编号(id)字段为例来讨论数据库表查询和插入并行操作的过程,对于可能多次获取同一个编号而产生错误的原因,以及解决该问题的思路及其具体的实现方法。这种解决问题的思路也适用于实时性较高的字段,如注册账户的名称等,是一个较常见的问题,具有一定的通用性。

[1] 于亮.异地并行数据库设计应用——餐饮管理系统[J].神州,2012(18):180.

[2] mysql插入记录后获取插入数据的id值[EB/OL].[ 2014-05-08].http://www.ddvip.com/tech/100020696.html.

[3] 赵永霞,高翠芬,熊燕,等.数据库原理与应用技术[M].武汉:华中科技大学出版社,2013.

[4] 张小志,吴庆双.SQL Server2008 数据库应用教程[M].北京:人民邮电出版社,2016.

[5] 袁晓洁,孙国荣.数据库原理和实践教程GBase 8t Based on Information剖析与应用[M].北京:电子工业出版社,2016.

[6] 严蔚敏,陈文博.数据结构及应用算法教程(修订版)[M].北京:清华大学出版社,2011.

[7] 胡秋霞,田杰.浅谈asp.net中ArrayList类的使用[J].电脑知识与技术(学术交流),2007(20):422-447.

[8] Ryan Stephens,Ron Plew,Arie D.Jones著. SQL入门经典(第5版)[M].井中月,郝记生译.北京:人民邮电出版社,2015.

Research on queuing based data insertion method of the database Table

GU Bao-lei,WU Yun

(Wuhan University of Engineering Science,Wuhan 430200,China)

At present, more and more software are network version, and all of these require the database. There are many users to access the database table at the same time especially when the database table inserting operation. So it is very access to the same number because of operational parallelism. This paper mainly aims at the problem of getting the same number, and proposes a higher degree of parallelism database operational way which can avoid multiple accessing to the same number by using public dynamic array to store insert data on the same database table.

database; the insertion method of database table; dynamic array; queue

2016-06-30.

2016-11-04.

顾保磊(1952-),男,教授,E-mail:dz_gubaolei@126.com.

2095-7386(2016)04-0078-04

10.3969/j.issn.2095-7386.2016.04.015

TP311

A

猜你喜欢

数组字段数据表
图书馆中文图书编目外包数据质量控制分析
JAVA稀疏矩阵算法
JAVA玩转数学之二维数组排序
湖北省新冠肺炎疫情数据表(2.26-3.25)
湖北省新冠肺炎疫情数据表
基于列控工程数据表建立线路拓扑关系的研究
Excel数组公式在林业多条件求和中的应用
寻找勾股数组的历程
CNMARC304字段和314字段责任附注方式解析
图表