使用数组实现快速数据查找

在很多数据库应用程序中,需要通过一个关键字段找出对应的其它字段数据,并且要求查找速度快。如在大多数的监控程序中,从终端获得一个标识后,需要通过这个标识将数据表中的其它数据查询出来,并显示在程序界面上。一般的做法是直接使用SQL查询返回查询结果。其实如果这个标识是唯一有序的,并且返回的结果也是唯一的,就没必要频繁地查询数据库。应该将数据首先存入内存,当然数据行上万就有难度。我要讲的存入内存其实是采用最为简单的方式,也就是记录(结构)类型作元素的数组。

具休做法是,先定义一个记录类型,用于保存在界面中要显示的结果数据,再定义一个数组,将所有数据从数据表是查询并排序存入这个数组。在查找时使用二分法得到对应的数组元素。

具体代码如下:

unit u_MyData;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
  Dialogs, StdCtrls, DB;

type
  PMyData = ^TMyData;
  TMyData = record
    CardNo: Integer;
    EmpNo, EmpName, ClassName: String;
  end;

  TMySearch = class
  private
    { Private declarations }
    List: Array of TMyData;
    function Search(iBegin, iEnd, ACardNo: Integer): Integer;
  public
    { Public declarations }
    destructor Destroy; override;
    function Clear: Boolean;
    function LoadValue(Items: TStrings): Boolean; overload;
    function LoadValue(DataSet: TDataSet): Boolean; overload;
    function SearchFor(ACardNo: Integer): TMyData; overload;
  end;

var
  NULL_DATA: TMyData;

implementation

{ TMySearch }

function TMySearch.Clear: Boolean;
begin
  Result:= False;
  try
    SetLength(List, 0);
    Result:= True;
  except
    // Can't free the element.
  end;
end;

destructor TMySearch.Destroy;
begin
  Clear;
  inherited;
end;

function TMySearch.LoadValue(DataSet: TDataSet): Boolean;
var
  i: integer;
begin
  Result:= False;
  try
    Clear;      // Clear the old value first.

    with DataSet do
    begin
      if Active then
      begin
        DisableControls;
        try
          SetLength(List, RecordCount);

          First;
          for i:= 0 to RecordCount -1 do
          begin
            List[i].CardNo:= Fields[0].AsInteger;
            List[i].EmpNo:= Fields[1].AsString;
            List[i].EmpName:= Fields[2].AsString;
            List[i].ClassName:= Fields[3].AsString;
            Next;
          end;
        finally
          EnableControls;
        end;
      end;
    end;
  except
    // Can't load value from dataset.
  end;
end;

function TMySearch.LoadValue(Items: TStrings): Boolean;
var
  i: integer;
begin
  Result:= False;
  try
    Clear;      // Clear the old value first.
   
    SetLength(List, Items.Count);
    for i:= 0 to Items.Count -1 do
    begin
      List[i].CardNo:= StrToInt(Items[i]);
    end;
    Result:= True;
  except
    // Can't load value from strings.
  end;
end;

function TMySearch.Search(iBegin, iEnd, ACardNo: Integer): Integer;
var
  Mid: Integer;
begin
  Result:= -1;
  try
    if iBegin <= iEnd then
    begin
      Mid:= (iBegin + iEnd) div 2;
      if List[Mid].CardNo = ACardNo then
        Result:= Mid
      else if List[Mid].CardNo > ACardNo then
        Result:= Search(iBegin, Mid -1, ACardNo)
      else
        Result:= Search(Mid + 1, iEnd, ACardNo);
    end;
  except
    // Can't search the value.
  end;
end;

function TMySearch.SearchFor(ACardNo: Integer): TMyData;
var
  i: integer;
begin
  Result:= NULL_DATA;
  try
    if Length(List) > 0 then
    begin
      i:= Search(0, Length(List) -1, ACardNo);
      if (i >= 0) and (i < Length(List)) then
        Result:= List[i];
    end;
  except
    // Can't find a value.
  end;
end;

end.

{ 以一个类实现 } 
以上代码经测试,只是感觉上比查询数据库快,实际还得设定相同条件进行比较。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值