Тема: СРАВНЕНИЕ СРЕДСТВ УПРАВЛЕНИЯ ДАННЫМИ В NETWARE
ПРАКТИЧЕСКОЕ СРАВНЕНИЕ РАЗЛИЧНЫХ СРЕДСТВ УПРАВЛЕНИЯ ДАННЫМИ В СРЕДЕ СЕТЕВОЙ ОПЕРАЦИОННОЙ СИСТЕМЫ NETWARE ФИРМЫ NOVELL
В материале приведены практические результаты сравнения
различных популярных средств управления данными в информацион-
ных системах в среде сетевой ОС NetWare фирмы Novell.
Основной смысл документа, на наш взгляд, заключен в ин-
формации позволяющей пользователю, в зависимости от его пот-
ребностей и располагаемых ресурсов, выбрать средство для уп-
равления данными в его компьютерной системе.
Документ предназначен для лиц, имеющих злементарные зна-
ния в области управления данными в вычислительных системах.
Зимин Владимир Валерьевич является ведущим конструктором
НПО "Информатика" г. Иваново. Занимается проектированием и ре-
ализацией информационных и планирующих систем для промышленных
предприятий разной специализации.
СОДЕРЖАНИЕ
ВВЕДЕНИЕ ..............................................4
1. ПРАКТИЧЕСКОЕ СРАВНЕНИЕ СУБД.........................5
ВЫВОДЫ И ЗАМЕЧАНИЯ....................................40
СПИСОК ЛИТЕРАТУРЫ.....................................41
ПЕРЕЧЕНЬ РИСУНКОВ
Рисунок 1.1. Сравнительные характеристики
Paradox Engine, Btrieve и FoxBASE по добавлению
записей на одиночном компьютере.
Рисунок 1.2. Сравнительные характеристики
Paradox Engine, Btrieve и FoxBASE по обновлению
записей на одиночном компьютере.
Рисунок 1.3. Сравнительные характеристики Btrieve
и Clipper по доступу к разделяемым данным на сети
с числом рабочих станций до 8 шт.
Рисунок 1.4. Характеристики Paradox Engine
при разделении данных.
Рисунки 1.5 Характеристики Btrieve при разделении
данных.
Рисунок 1.6 Характеристики Btrieve и FoxPro
при поиске данных в "больших" таблицаx.
ВВЕДЕНИЕ
Этот материал представляет собой отчет о проведенных
экспериментах по сравнению различных средств управления данны-
ми в сетевой среде фирмы Novell.
1. ПРАКТИЧЕСКОЕ СРАВНЕНИЕ СУБД.
Для сравнения Btrieve, Paradox_Engine и FoxBASE по
функциям, нами были программы, добавления и обновления записей
в базе данных: Btr_io.c, PxE_io.c, Fox_io.prg и программы раз-
деления записи данных в сети Novell: Btr_sh_rec.c, PxE_sh_rec.
c, Clp_sh_rec.prg.
Укрупненно, алгоритм программ первого типа можно предста-
вить следующими шагами:
1) Создание таблиц(ы) данных и индексных файлов;
2) Добавление (1000, 2000,... 10000) записей в таблицы
данных с фиксацией времени добавления всех;
3) Обновление неключевых полей (1000, 2000,... 10000) за-
писей с фиксацией времени обновления всех.
4) Удаление индексных файлов и таблиц данных.
Тестовые прогоны проводились на компьютере ASI-386SX с
объемом ОЗУ 1 MB и тактовой частотой 16 MHz.
Исходные коды программ Btr_io.c, PxE_io.c и Fox_io.prg
приведены ниже.
/*
Ъ————————————————————————————————————————————————ї
і Тестовая программа добавления и обновления і
і записей - Btr_io.c. і
А——————————————— File BTR_IO.C ——————————————————Щ
*/
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <dos.h>
#include <time.h>
#define B_OPEN 0 /* Btrieve Operations */
#define B_CLOSE 1
#define B_INSERT 2
#define B_UPDATE 3
#define B_DELETE 4
#define B_GETEQUAL 5
#define B_GETNEXT 6
#define B_GETFRST 12
#define B_GETLAST 13
#define B_CREATE 14
#define LenIdn 22 /* Fields Lengths */
#define LenNam 20
#define LenKey 2
#define LenWkl 38
#define LenPrt 39
#define LenDat 4
#define LenTim 4
int RecNmb;
int Recrds[10];
char BlkDir[128];
int BReclen;
int Status;
struct stat Fl_Inf;
struct dosdate_t Sdate;
struct dostime_t Stime;
time_t start, finish;
/* File Path */
/* char * FileDir = "f:\\zimin\\btr_tst.dta";
char * FileDir = "c:\\owrwrk\\btr_tst.dta";
char * StrDir; /* File Structure */
char * IdnDir; /* Subject ID */
char * DatDir; /* Date */
char * TimDir; /* Time */
char * NamDir;
char * KeyDir;
char * WklDir;
char * PrtDir;
int Key;
char * Idn;
struct stat buf;
int _CDECL new_dirfile(void);
int _CDECL opn_dirfile(void);
int _CDECL cls_dirfile(void);
int _CDECL new_records(void);
int _CDECL upd_records(void);
int _CDECL cur_time(void);
main ()
{
extern int BRecLen;
int i;
StrDir = IdnDir = calloc(LenIdn + LenNam + LenKey +
LenWkl + LenPrt+ LenDat + LenTim, 1);
NamDir = IdnDir + LenIdn;
KeyDir = NamDir + LenNam;
WklDir = KeyDir + LenKey;
PrtDir = WklDir + LenWkl;
DatDir = PrtDir + LenPrt;
TimDir = DatDir + LenDat;
Idn = calloc(LenIdn, 1);
BRecLen = LenIdn + LenNam + LenKey + LenWkl + LenPrt +
LenDat + LenTim; /* Rec. Len. */
Recrds[0] = 1000;
Recrds[1] = 2000;wc
Recrds[2] = 3000;
Recrds[3] = 4000;
Recrds[4] = 5000;
Recrds[5] = 6000;
Recrds[6] = 7000;
Recrds[7] = 8000;
Recrds[8] = 9000;
Recrds[9] = 10000;
for ( i = 0; i <= 9 ; i++ )
{
ЖЖRecNmb = Recrds[i];
ЖЖprintf("\n\n\n Records Number is %d.", RecNmb);
ЖЖprintf("\n Programm START");
ЖЖif(stat(FileDir, &buf))
ЖЖЖ{
ЖЖЖ printf("\n File Creating. ");
ЖЖЖ new_dirfile(); /* File Crt */
ЖЖЖ} else
ЖЖЖ{
ЖЖЖ printf("\n File Opening. ");
ЖЖЖ opn_dirfile(); /* File Opn */
ЖЖЖ} /* if - else */
ЖЖprintf("\n Records Inserting. ");
ЖЖtime(&start);
ЖЖif( new_records()) return(-1);
ЖЖtime(&finish);
ЖЖtim_dif();
ЖЖprintf("\n Records Updating. ");
ЖЖtime(&start);
ЖЖif( upd_records()) return(-1);
ЖЖtime(&finish);
ЖЖtim_dif();
ЖЖif( cls_dirfile()) return(-1);
Ж } /* for */
exit(0);
} /* main */
int new_dirfile() /* File Creating */
{
int length;
extern int BRecLen;
struct KEY_SPEC
ЖЖ{
ЖЖ int KeyPos, KeyLen, KeyFlag;
ЖЖ char Notuse2 [4];
ЖЖ char KeyType;
ЖЖ char NullValue;
ЖЖ char Reserv2 [4];
ЖЖ};
struct FILE_SPEC
{
int RecLen, PageSize, NumIndex;
char Notuse1 [4];
int FileFlag;
char Reserv1 [2];
int PreAlloc;
struct KEY_SPEC KeyBuf[2];
} Filedef;
Filedef.RecLen = LenIdn + LenNam + LenKey + LenWkl +
LenPrt + LenDat + LenTim; /* Rec. Len. */
Filedef.PageSize = 4096;
Filedef.NumIndex = 2; /* Nmb of Keys */
Filedef.FileFlag = 4; /* Emp Pages */
Filedef.PreAlloc = 520; /* Nmb of Prealloc. Pgs */
memset( Filedef.Notuse1, 0, 4 );
memset( Filedef.Reserv1, 0, 2 );
Filedef.KeyBuf[0].KeyPos = 1; /* Key Pos. */
Filedef.KeyBuf[0].KeyLen = LenIdn; /* Key Len. */
Filedef.KeyBuf[0].KeyFlag = 0;
Filedef.KeyBuf[0].KeyType = 0;/* Key Type-String */
Filedef.KeyBuf[0].NullValue = 0;
memset( Filedef.KeyBuf[0].Notuse2, 0, 4 );
memset( Filedef.KeyBuf[0].Reserv2, 0, 4 );
Filedef.KeyBuf[1].KeyPos = LenIdn + LenNam + 1;
/* Key Pos. */
Filedef.KeyBuf[1].KeyLen = LenKey; /* Key Len. */
Filedef.KeyBuf[1].KeyFlag = 0;
Filedef.KeyBuf[1].KeyType = 1; /*Key Type-Integer */
Filedef.KeyBuf[1].NullValue = 0;
memset( Filedef.KeyBuf[1].Notuse2, 0, 4 );
memset( Filedef.KeyBuf[1].Reserv2, 0, 4 );
length = sizeof( Filedef );
if( Status = BTRV( B_CREATE, BlkDir, &Filedef, &length,
FileDir, 0 ))
{
printf("\nB_CRT Status is %d.",Status);
return(-1);
}
if( Status = BTRV( B_OPEN, BlkDir, StrDir, &BRecLen,
FileDir, -1 ) )
{
printf("\nB_OPN Status is %d.",Status);
return(-1);
}
return (0);
} /* new_dirfile */
int opn_dirfile() /* Fille Opening */
{
extern int BRecLen;
Status = BTRV( B_OPEN, BlkDir, StrDir, &BRecLen, FileDir,
-1 );
if(Status != 0)
{
printf("\nB_OPN Status is %d.",Status);
return(-1);
}
return(0); } /* opn_dirfile */
int cls_dirfile( void ) /* File Closing */
{
extern int BRecLen;
Status = BTRV( B_CLOSE, BlkDir, NULL, &BRecLen, NULL, 0);
if(Status != 0)
{
printf("\nB_CLS Status is %d.",Status);
return(-1); }
remove(FileDir);
return(0); } /* cls_dirfile */
int new_records() /* Record Inserting */
{
extern int BRecLen;
extern int Key = 1;
extern int BRecLen;
int i;
int radix = 10;
char *p;
for ( i = 1; i <= RecNmb ; i ++ )
{
memmove(KeyDir, &Key, LenKey);
memset(Idn, ' ', LenIdn);
memset(IdnDir, ' ', LenIdn);
p = itoa(Key, IdnDir, radix);
memmove(Idn, IdnDir, strlen(IdnDir));
memset(IdnDir + strlen(IdnDir), ' ', 1);
_dos_getdate (&Sdate); /* System Date to Buffer */
_dos_gettime (&Stime); /* System Time to Buffer */
memmove(DatDir, &Sdate.day, LenDat);
memmove(TimDir, &Stime.hour, LenTim);
Status = BTRV(B_INSERT, BlkDir, StrDir, &BRecLen,
Idn, 0);
if( Status != 0)
{
printf("\n Error inserting %d.",Status);
cls_dirfile();
return (-1);
} /* if */
Key ++;
} /* for */
return(0); } /* new_records */
int upd_records() /* Rec. Updating */
{
extern int BRecLen;
int radix = 10;
char *p;
for ( Key = 1; Key <= RecNmb ; Key++ )
{
memmove(KeyDir, &Key, LenKey);
memset(IdnDir, ' ', LenIdn);
p = itoa(Key, IdnDir, radix);
memset(IdnDir + strlen(IdnDir), ' ', 1);
memmove(Idn, IdnDir, LenIdn);
Status = BTRV(B_GETEQUAL, BlkDir, StrDir, &BRecLen,
Idn, 0);
if(Status != 0) /* Record wasn't Found */
{ printf("\nB_GEQ Status is %d.",Status);
ЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖ/* Reading Error
*/ cls_dirfile();
return (-1); }
_dos_getdate (&Sdate); /* System Date to Buffer */
_dos_gettime (&Stime); /* System Time to
Buffer */
memmove(DatDir, &Sdate.day, LenDat);
memmove(TimDir, &Stime.hour, LenTim);
if( Status = BTRV(B_UPDATE, BlkDir, StrDir, &BRecLen,
Idn, 0))
{ printf("\nB_UPDATE Status is %d.",Status); /* Reading
Error */
cls_dirfile();
return (-1); } } /* for */ return(0);
} /* upd_records */
int tim_dif() /* Time for Records
Processing */ { register num;
printf("\n Elapsed time - %f sec..",
difftime(finish, start));
printf("\n Average time for one record is %f sec..",
difftime(finish, start)/ RecNmb); }
/*
Ъ—————————————————————————————————————————————————————ї
і і
і Программа - тест добавления, поиска - обновления і
і системы управления данными Paradox Engine v2.0 і
і і
А————— Файл PxE_io.c ———————————————————————————————Щ
*/
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <dos.h>
#include <time.h>
#include <pxengine.h>
#define SUCCESS 0
#define MAXFIELDS 7
#define MAXFIELDSIZE 55
#define ACSNMB 100
RECORDHANDLE recHandle; /* record buffer */
TABLEHANDLE tblHandle; /* table handle */
FIELDHANDLE fld_key,
ЖЖЖЖЖЖfld_idn,
ЖЖЖЖЖЖfld_nam,
ЖЖЖЖЖЖfld_wkl,
ЖЖЖЖЖЖfld_prt,
ЖЖЖЖЖЖfld_dat,
ЖЖЖЖЖЖfld_tim;
int TableIsOpen = FALSE; /* table is open */
int nfields; /* number of fields */
char * FileDir = "px_tst"; /* File Path */
char * FieldNames[] = /* Field names
of PARADOX table */
{
"Key",
"Idn",
"Nam",
"Wkl",
"Prt",
"Dat",
"Tim"
};
/* Field types of PARADOX table */
char * FieldTypes[] =
{
"N", "A22","A20" , "A38", "A39", "D", "A11"
};
#define NBRFIELDS ( sizeof(FieldNames) / sizeof(*char) )
struct dosdate_t Sdate;
char Stime[9];
time_t start, finish;
char * Str;
char * Key; /* Ключ записи */
char * St1; /* Поля обработки станции 1
- 8 */
char * St2;
char * St3;
char * St4;
char * St5;
char * St6;
char * St7;
char * St8;
int Key = 1;
char Idn[23];
int LenIdn = 22;
int Recrds[5];
int RecNmb ;
int status;
int new_dirfile(void);
int init_flds(void);
int cls_dirfile(void);
int new_records(void);
int upd_records(void);
int cur_time(void);
main ()
{
int i;
/* Initializa the Engine */
if ( status = PXInit())
{
printf ( "\n Error Init\n" );
exit(1);
}
Recrds[0] = 1000;
Recrds[1] = 2000;
Recrds[2] = 3000;
Recrds[3] = 4000;
Recrds[4] = 5000;
/* Recrds[5] = 6000;
Recrds[6] = 7000;
Recrds[7] = 8000;
Recrds[8] = 9000;
Recrds[9] = 10000;*/
for ( i = 0; i <= 4 ; i++ )
Ж {
ЖЖЖRecNmb = Recrds[i];
printf("\n\n\n Records Number is %d.", RecNmb);
printf("\n Programm START");
printf("\n File Creating. ");
if (new_dirfile()) exit(-1); /* Создание файла */
if (init_flds()) exit(-1);
printf("\n Records Inserting. ");
time(&start);
if( new_records())
{
PXExit();
exit(-1);
}
time(&finish);
tim_dif();
printf("\n Records Updating. ");
time(&start);
if( upd_records())
{
end_prg();
exit(-1);
}
time(&finish);
tim_dif();
if( cls_dirfile()) exit(-1);
} /* for */
PXExit();
exit(0);
} /* main */
new_dirfile() /* File Creating */
{
FIELDHANDLE keybuf[7];
if (status = PXTblCreate ( FileDir, 7, FieldNames,
FieldTypes ))
{
Ж printf ( "\n Error Create %d", status );
return (FALSE);
}
keybuf[1] = 2;
if (status = PXKeyAdd ( FileDir, 2, keybuf, PRIMARY ))
{
Ж printf ( "\n Error ADD 2 %d", status );
Ж return (FALSE);
}
if (status = PXTblOpen( FileDir, &tblHandle, 0, 0 ))
{
Ж printf ( "\n Error Open %d", status );
Ж return (FALSE);
}
return (0);
} /* new_dirfile */
int cls_dirfile() /* File Closing */
{
PXRecBufClose (recHandle);
if ( status = PXTblClose (tblHandle))
{
Ж printf ( "\n Error Close %d", status );
Ж return (FALSE);
}
remove(FileDir);
return (0);
}
int init_flds()
{
if ( status = PXFldHandle (tblHandle, "Idn", &fld_idn))
{
Ж printf ( "\n Error Init 1 %d", status );
return (FALSE);
}
if ( status = PXFldHandle (tblHandle, "Key", &fld_key))
{
Ж printf ( "\n Error Init 2 %d", status );
return (FALSE);
}
if ( status = PXFldHandle (tblHandle, "Nam", &fld_nam))
{
Ж printf ( "\n Error Init 3 %d", status );
return (FALSE);
}
if ( status = PXFldHandle (tblHandle, "Wkl", &fld_wkl))
{
Ж printf ( "\n Error Init 4 %d", status );
return (FALSE);
}
if ( status = PXFldHandle (tblHandle, "Prt", &fld_prt))
{
Ж printf ( "\n Error Init 5 %d", status );
return (FALSE);
}
if ( status = PXFldHandle (tblHandle, "Dat", &fld_dat))
{
Ж printf ( "\n Error Init 6 %d", status );
return (FALSE);
}
if ( status = PXFldHandle (tblHandle, "Tim", &fld_tim))
{
Ж printf ( "\n Error Init 7 %d", status );
return (FALSE);
}
Жreturn (0); }
int new_records() /* Record Inserting */
{
int i;
int radix = 10;
char *p;
DATE Px_date;
Key = 1;
status = PXRecBufOpen ( tblHandle, &recHandle);
if (status)
Ж{
ЖЖprintf ("\n Error RecBufOpen %d", status);
ЖЖreturn(-1);
Ж}
for ( i = 1; i <= RecNmb ; i ++ )
Ж {
ЖЖmemset(Idn, ' ', LenIdn);
ЖЖp = itoa(Key, Idn, radix);
ЖЖ_dos_getdate (&Sdate); /* System Date to Buffer
*/
ЖЖ_strtime (Stime); /* System Time to Buffer
*/
ЖЖif(status = PXDateEncode ( Sdate.month, Sdate.day,
Sdate.year, &Px_date ))
ЖЖ {
ЖЖЖ printf ("\n Error DateEncode %d", status);
ЖЖЖ return(-1);
ЖЖ }
ЖЖif (status = PXPutAlpha( recHandle, fld_idn, Idn ))
ЖЖ{
ЖЖЖ printf ("\n Error PutIdn %d", status);
ЖЖЖ return(-1); }
ЖЖif (status = PXPutAlpha( recHandle, fld_tim, Stime ))
ЖЖ{
ЖЖЖ printf ("\n Error PutTime %d", status);
ЖЖЖ return(-1); }
ЖЖif (status = PXPutLong( recHandle, fld_key, (long)Key ))
ЖЖ{
ЖЖЖ printf ("\n Error PutKey %d", status);
ЖЖЖ return(-1); }
ЖЖif (status = PXPutDate( recHandle, fld_dat, Px_date ))
ЖЖ{
ЖЖЖ printf ("\n Error PutDate %d", status);
ЖЖЖ return(-1); }
ЖЖif (status = PXRecInsert( tblHandle, recHandle ))
ЖЖ{
ЖЖЖ printf ("\n Error RecInsert %d", status);
ЖЖЖ return(-1); }
Key ++;
} /* for */
return(0);
} /* new_records */
int upd_records() /* Read Updating */
{
extern int BRecLen;
int radix = 10;
char *p;
DATE Px_date;
status = PXRecBufOpen ( tblHandle, &recHandle);
for ( Key = 1; Key <= RecNmb ; Key++ )
{
memset(Idn, ' ', LenIdn);
p = itoa(Key, Idn, radix);
if (status = PXPutLong( recHandle, fld_key, (long)Key ))
{
printf ("\n Error PutKey %d", status);
return(-1); }
if (status = PXPutAlpha( recHandle, fld_idn, Idn ))
{
printf ("\n Error PutIdn %d", status);
return(-1); }
if (status = PXSrchKey(tblHandle, recHandle, 1,
SEARCHFIRST ))
{
printf ("\n Error srchkey %d", status);
return(-1); }
if (status = PXRecGet(tblHandle, recHandle ))
{
printf ("\n Error Get %d", status);
return(-1); }
_dos_getdate (&Sdate); /* System Date to Buffer
*/
_strtime (Stime); /* System Time to Buffer
*/