SQLite verilənlər bazasını optimallaşdırmağın 12 yolu – Onları İndi sınayın!

Açıqlama: Dəstəyiniz saytın işini davam etdirməyə kömək edir! Bu səhifədə tövsiyə etdiyimiz bəzi xidmətlər üçün bir müraciət haqqı qazanırıq.


SQLite, SQL əsaslı əlaqəli verilənlər bazası idarəetmə sistemidir (RDBMS), quraşdırılmış kitabxana kimi tətbiq olunur. Məlumat bazalarını müştəri-server modelinə güvənmək əvəzinə diskret sənəd kimi saxlayır.

SQLite adətən üç şəkildə istifadə olunur:

  • İstifadəsi rahatlığı, bazalı dəstəklənən tətbiqləri sınaqdan keçirmək və protoyping üçün idealdır.
  • Hər şey yerli olaraq saxlanıldığından və kitabxananın özü bir tətbiqə yerləşdirilə bildiyindən SQLite tez-tez bir istifadəçi tərəfindən yerli olaraq idarə olunan kiçik tətbiqlər üçün əsas məlumat anbarı kimi də istifadə olunur. Buraya ünvan kitabları, ediləcək siyahılar və ya e-poçt oxucuları kimi proqramlar daxildir.
  • Nəhayət, SQLite verilənlər bazası tez-tez bir tətbiq üçün xüsusi bir fayl formatı olaraq istifadə olunur. Bu, nisbətən sadə bir sənəddən daha çox, qeyd olunan bir sənədin mürəkkəb bir layihə olduğu tətbiqlərdə faydalıdır. Bu vəziyyətdə tətbiqetmənin yaratdığı hər bir fayl əslində bütün bir SQLite verilənlər bazasıdır.

Optimallaşdırmaya ehtiyac

Çox vaxt sınaq və prototipləmə üçün istifadə edildikdə, sürət üçün optimallaşdırılması o qədər də vacib deyildir. Bu hallarda bunu etmək həmişə mümkün olmur, çünki tətbiqinizi istehsalatda fərqli bir verilənlər bazası ilə işə salmağı planlaşdıra bilərsiniz. SQLite burada sadəcə PostgreSQL və ya MySQL kimi başqa bir şey üçün stand-in olaraq istifadə olunur.

Ancaq SQLite ikinci iki vəziyyətdə olduğu kimi “istehsalda” istifadə edildikdə, performans vacibdir. Bir neçə sadə texnikanın tətbiqi həqiqətən verilənlər bazası yeniləmələri və sorğuların sürətinə təsir göstərə bilər.

Tətbiqlərinizdə SQLite performansını yaxşılaşdırmaq üçün bəzi praktik tövsiyələr. Bəziləri SQL verilənlər bazası sistemini sürətləndirməyə kömək edəcək SQL sorğu optimallaşdırmasıdır. Digərləri, SQLite’nin optimallaşdırılması üçün xüsusidir.

SQLite Android tətbiqetmələrində çox populyar bir məlumat bazası olduğundan, SQLite-in fəaliyyətini Android-də optimallaşdırmaq üçün bəzi tövsiyələri daxil etdik..

Bir əməliyyatdan istifadə edin

SQLite’nin sürətlənməsi üçün hər kəsin verdiyi ilk məsləhət parçası “əməliyyatdan istifadə edin”.

Hamı bunu həqiqətən yaxşı bir fikir olduğu üçün söyləyir. Ancaq SQL-də bir əməliyyatdan necə istifadə edəcəyinizi düşünə bilərsiniz.

Deyək ki, siyahı və ya serial kimi bəzi iterable strukturda bir dəstə məlumat topladınız. Verilənlərinizlə döngə etmək və döngənin hər bir iterasyonuna SQLite verilənlər bazasına daxil etmək istəyiniz ola bilər..

/ ************************************************* ***
Sekmeli ayrılmış bir fayldan ilk və son adları alın.
Sonra onları SQLlite verilənlər bazasına daxil edin.
************************************************** ** /

/ * bunları real həyatda müəyyənləşdirdiyinizə əmin olun…
#define DATABASE = // verilənlər bazasının adı //
#define FILE_OF_NAMES = // fayla gediş yolu //
#define CREATE_TABLE = // Adlar cədvəlini yaratmaq üçün SQL ifadəsi //
* /

sqlite3_open (DATABASE, &db);
sqlite3_exec (db, CREATE_TABLE, NULL, NULL), &sErrMsg);

pFile = fopen (FILE_OF_NAMES),"r");
while (! feof (pFile)) {

hədəflər (sInputBuf, BUFFER_SIZE, pFile);

sFirstName = strtok (sInputBuf), "t");
sLastName = strtok (NULL), "t");

sprintf (sSQL), "INSERT INTO Adların dəyərləri (NULL, ‘% s’, ‘% s’,)", sFirstName, sLastName, s);
sqlite3_exec (db, sSQL, NULL, NULL), &sErrMsg);

n ++;
}
fclose (pFile);
sqlite3_close (db);

Bu pis bir fikirdir. Bu hər bir əlavə bir əməliyyata atomizasiya edir – hər biri öz yerüstü dəyəri ilə. Yalnız bir neçə giriş varsa, o qədər də böyük bir şey deyil, hətta sürətlə işləyən C kodu da bu, bir saniyədə 100 girişi ləngidə bilər. SQLite’yi bir tətbiq sənəd formatı olaraq istifadə edirsinizsə, bu, istifadəçilər mürəkkəb bir sənəd və ya layihə saxladıqları zaman hər iki saniyə geridə qalması deməkdir..

Məlumatlarınızı ayrı-ayrılıqda daxil etmək əvəzinə, bütün yazılarınızı bir əməliyyata yığın. Bu, əlavələrinizi əhəmiyyətli dərəcədə sürətləndirəcəkdir. Və etmək çox asan bir dəyişiklikdir.

/ * loopdan əvvəl – əməliyyata başlayın * /
sqlite3_exec (db.), "ƏMƏLİYYATA başlayın", NULL, NULL, &sErrMsg);

pFile = fopen (FILE_OF_NAMES),"r");
while (! feof (pFile)) {
.
.
.
}

fclose (pFile);

/ * döngədən sonra – əməliyyatı sonlandır * /
sqlite3_exec (db.), "ƏMƏLİYYAT", NULL, NULL, &sErrMsg);

Döngənin içərisində hələ də INSERT ifadəsini icra edirsiniz, lakin hər iterasiya üzrə verilənlər bazasını yeniləmirlər. Bunun əvəzinə, SQLite bütün ifadələrinizi bir önbelleğe saxlayır və sonra SƏNƏDLƏNİB bitirdikdə hamısını vahid əməliyyat olaraq işə salır.

Əlavələr hamısı önbellekdə saxlanıldığı üçün əməliyyatların bu şəkildə istifadə edilməsinin sürət üstünlüyü əldə etmək üçün önbellek ölçüsünüzü artırmağınız lazım ola bilər..

/ * db bağlantısı açıldıqdan sonra,
əməliyyat başlamazdan əvvəl * /
sqlite3_exec (db.), "PRAGMA cache_size = 10000", NULL, NULL, &sErrMsg);

Android-də əməliyyatlar

Android SQLite API əməliyyatların istifadəsini daha da asanlaşdırır.

bir əməliyyata başlamaq üçün
db.beginTransaction ();

// bir əməliyyatı bitirmək
db.endTransaction ();

Əməliyyatı etməzdən əvvəl istisnaların olub olmadığını yoxlamaq və bir problem varsa səhvini daxil etmək istəyə bilərsiniz. Bu Android-də də asandır.

cəhd {
db.beginTransaction ();

/ * Bir döngədə işlər edin. * /

db.setTerkansiyonUğurlu (); // İstisnalar olmadıqda bu əməliyyatı yerinə yetirir

} tutmaq (İstisna e) {
Log.w ("İstisna:", e);
} nəhayət {
db.endTransaction ();
}

Hazırlayın və bağlayın

Son nümunədə SQL ifadəsi hər bir döngənin icrası zamanı yenidən yaradıldı. Bu, hər dəfə SQLite tərəfindən təhlil edildiyi deməkdir. Bu təhlil bəzi itələmə ilə işləri yavaşlatan bəzi hesablama yerüstü xüsusiyyətinə malikdir.

SQL ifadənizi döngədən kənarda hazırlayaraq işinizi sürətləndirə bilərsiniz və sonra istifadə etdiyiniz hər dəfə məlumatlarınızı ona bağlaya bilərsiniz.

/ * əməliyyata başlamazdan əvvəl * /
sprintf (sSQL), "INSERT INTO Adlar dəyərləri (NULL, @FirstName, @LastName)");
sqlite3_ hazırlamaq_v2 (db, sSQL, BUFFER_SIZE, &stmt, &quyruq);

sqlite3_exec (db.), "ƏMƏLİYYATA başlayın", NULL, NULL, &sErrMsg);

pFile = fopen (FILE_OF_NAMES),"r");
while (! feof (pFile)) {

hədəflər (sInputBuf, BUFFER_SIZE, pFile);

sFirstName = strtok (sInputBuf), "t");
sLastName = strtok (NULL), "t");

sqlite3_bind_text (stmt, 1, sFirstName, -1, SQLITE_STATIC);
sqlite3_bind_text (stmt, 2, sLastName, -1, SQLITE_STATIC);

sqlite3_step (stmt);

sqlite3_clear_bindings (stmt);
sqlite3_reset (stmt);

n ++;
}
fclose (pFile);
sqlite3_exec (db.), "ƏMƏLİYYAT", NULL, NULL, &sErrMsg);
sqlite3_close (db);

Bu strategiya, loop xaricində də istifadə edilə bilər. Bir funksiyanın içərisində bir sorğunuz varsa, bir dəfə hazırlaya və hər dəfə istifadə edildikdə bağlaya bilərsiniz.

Android-də hazırlanan hesabatlar

Android SQLite API asanlıqla bunu etmək üçün SQLiteStatement sinifini təmin edir.

// sorğu yaz, ilə? daxil dəyərlər üçün
String sql = "INSERT INTO Adlar dəyərləri (?,?)";

// ifadəni tərtib etmək
SQLiteStatement ifadəsi = db.compileStatement (sql);

/ ** qeydlər vasitəsilə döngə ** /

/ ** fayldakı adları götürün və ilk ad və familiyaya təyin edin ** /

// bağlamaq
bəyanat.bindString (1, ad);
bəyanat.bindString (2, familiya);

// icra
Uzun sıra_id = bəyanat.executeInsert ();

Hər əlavə etdikdən sonra Disklə Sinxronlaşdırma

SQLite, bir qayda olaraq, bu yazıların hər birini verdikdən sonra OS-nin diskə yazmasını gözləyir. Bu fasiləni sadə bir əmrlə söndürə bilərsiniz.

sqlite3_exec (db.), "PRAGMA sinxron = OFF", NULL, NULL, &sErrMsg);

Bazaya bağlantı açdıqdan sonra yerləşdirin, lakin əməliyyatı başlamazdan əvvəl. Həm də bilməlisiniz ki, bu qəza və ya elektrik enerjisinin kəsilməsi halında verilənlər bazasının pozulmasına səbəb ola bilər. Beləliklə, artan sürəti hər hansı bir potensial riskə qarşı ölçmək istəyərsiniz.

Rollback Journal-ı yaddaşda saxlayın

Əgər siz artıq PRAGMA sinxron = OFF ilə təhlükəli yaşayırsınızsa və bütün əlavə millisaniyələri çıxartmağa çalışırsınızsa, geri çevirmə jurnalını yaddaşa saxlaya bilərsiniz. Əvvəlki optimallaşdırma ilə birlikdə bu bir az risklidir.

sqlite3_exec (db.), "PRAGMA jurnal_mode = Yaddaş", NULL, NULL, &sErrMsg);

Sürətli bir yarış qazanmaq və ya başqa bir şey qazanmaq istəsəniz, jurnal_mode-u OFF-ə də quraşdıra bilərsiniz. (Bu real həyatda istifadə üçün tövsiyə edilmir.)

Android üçün jurnal rejimi xəbərdarlığı

SQLite-nin Jurnal rejimi Android’in EnableWriteAheadLogging () metodu tərəfindən idarə olunur. Buna görə xam SQL əmrlərini yerinə yetirmək üçün sənədləşmə dediyi kimi:

Istifadə jurnal_mode təyin etməyin "PRAGMA jurnal_mode" Tətbiqiniz EnableWriteAheadLogging () istifadə edirsə.

Həqiqətən ehtiyacınız olduqda yalnız indeks

Sadəlövh verilənlər bazası inkişaf etdiriciləri “işlərini sürətləndirmək” üçün bir çox indeks yaratmaq istəyirlər. Ancaq bunu bədbəxtliklə etmək və ya sözün həqiqi mənasında hər şey əksikdir. Cədvəlin məzmununu müəyyən bir sətirlə indeksləşdirmək oxumağı daha sürətli edir və daha yavaş yazır. Və yalnız o sütuna əsasən axtarış aparan sorğuları daha sürətli oxuyur.

Beləliklə, istifadəçilər heç bir cədvəlin məzmununu müəyyən bir sütuna əsasən axtarmağa getməsələr, onu indeksləşdirməyin. Bundan əlavə, istifadəçilər yalnız müəyyən bir sütununda nadir hallarda axtarış aparırlarsa, onu indeksləşdirməyin. Tez-tez axtarma ehtimalı olsa da, cədvəlin daha tez-tez yazılıb-yazılmayacağını düşünməlisiniz. Axtarılanlardan daha çox yazılacaqsa və ya yazma sürəti xüsusilə kritikdirsə, onu indeksləşdirməyin.

Çox vaxt tətbiq növü bu ehtiyacları diktə edəcəkdir. SQLite geniş çeşidli əməliyyatları dəstəkləməsi lazım olan böyük məlumat mağazalarında çox istifadə edilmir. Tətbiq faylı növü kimi istifadə olunursa, məsələn, bir istifadəçinin işləyərkən bir layihəni tez bir zamanda qurtarma qabiliyyəti, iş sənədinin məzmununu mümkün qədər tez axtara bilməkdən daha vacibdir. Digər tərəfdən, adətən əl ilə, tək girişli yeniləmələrə (bir əlaqə qovluğu və ya işlər siyahısı kimi) sahib olan məlumat saxlama tətbiqi, yəqin ki, biraz daha yavaş yazmağa dayana bilər, lakin çox sürətli axtarışa dəstək olmalıdır.

Toplu əlavə edildikdən sonra indeks

Bir masada bir indeks yaratdıqdan sonra hər bir əlavə yeni məzmunu indeksləşdirmək üçün vaxt aparacaqdır. Cədvəliniz böyük bir toplu məlumat daxil edilsə (bəlkə də ilk dəfə yeni bir layihə və ya sənəd saxlanıldıqda və ya yeni bir istifadəçi üçün məlumat idxal edilərsə), indeks yaratmağı gözləyərək bu ilk böyük əlavə sürətləndirə bilərsiniz. daxil edildikdən sonra.

Digər PRAGMA parametrləri

SQLite fəaliyyətinizi yaxşılaşdırmağa kömək edə biləcək bir sıra PRAGMA parametrləri var.

Ölçü ölçüsü

Yuxarıda qısaca qeyd edildiyi kimi, önbelleğinizi artırmağınız lazım ola bilər. Böyük əməliyyatlar yalnız bütün əməliyyatın ön yaddaşda saxlanıla biləcəyi təqdirdə sürətlənəcəkdir.

Kesh üçün istifadə olunan yaddaş lazım olduqda ayrılır, buna görə onu çox yüksək səviyyəyə qaldırmaq üçün yer yoxdur. Ayrıca dinamik olaraq tənzimləyə bilərsiniz – müəyyən sorğular üçün optimallaşdırmaq üçün artırın və lazım olmasa endirin.

sqlite3_exec (db.), "PRAGMA cache_size = 100000", NULL, NULL, &sErrMsg);

Müvəqqəti masa anbarı

SQLite-ə müvəqqəti cədvəlləri yaddaşda saxlamaq üçün deyə bilərsiniz. Bu, müvəqqəti cədvəllərə, göstəricilərə və görüntülərə etibar edən bir çox oxu əməliyyatlarını sürətləndirəcəkdir.

sqlite3_exec (db.), "PRAGMA temp_store = Yaddaş", NULL, NULL, &sErrMsg);

Android və Pragma Parametrləri

SQL verilənlər bazanıza qarşı xam SQL icra etmək üçün execSQL () metodundan istifadə edə bilərsiniz. PRAGMA parametrlərinin hər hansı birini dəyişdirməyin ən birbaşa yolu budur. Ancaq bəziləri (yuxarıda qeyd olunan jurnal_mode kimi) digər siniflər və ya API-də köməkçilər tərəfindən idarə olunur.

Daha sürətli sorğular – Daha gec filtr edin

Bir çox meyar əsasında bir sorğu edirsinizsə, tez-tez meyarlarınızın necə sifariş verildiyini dəyişdirərək tezləşdirə bilərsiniz. Birinci WHERE bəndində ən az sayda nəticə qaytarılırsa, sonrakı hər birində daha az iş görüləcəkdir.

Çox sayda parametr olan bir sorğuda hansının ən yaxşı orta sürətə sahib olduğunu görmək üçün sifarişin bir neçə fərqli dəyişikliyi ilə sınaq keçirməyə çalışın..

Bəyənmə üçün Case Həssas İndekslər

Mətnin müqayisə edilməsi üçün LIKE bəndi həssasdır. İndekslər cari olaraq həssasdır. İndeksləriniz üçün optimallaşdıran yeganə suallar LIKE sorğularıdırsa, indeks həssaslığını artıraraq yazılara və sorğulara vaxt qənaət edə bilərsiniz..

Adlar üzərində INDEX sLastName yaradın (ƏSAS COLLATE NOCASE);

Mümkünsə, son versiyasından istifadə edin

SQLite-in hər bir əsas versiyasının buraxılışında performans inkişaf etdirmələri mövcuddur. Bəzi buraxılışlar sürəti kəskin artırdı. Buna görə bir neçə yaşında olan (və ya daha pis, hələ v2 istifadə edərək) kiçik bir versiyasını istifadə edirsinizsə, daha sürətli icraya aparan asan yol sadəcə təkmilləşdirilir.

Yeni verilənlər bazası yaratma

Bu, digər RDBMS sistemlərindən gələn insanlar üçün düşüncə baxımından böyük bir dəyişiklikdir.

SQLite tətbiq proqramı formatı kimi istifadə vəziyyətinə baxın. Tətbiqdə ilk dəfə yeni bir layihə (fayl) saxladığınız zaman yeni bir verilənlər bazası nümunəsi lazımdır.

Yeni bir verilənlər bazası yarada və müvafiq cədvəllər və indeksləri əlavə etmək üçün bir sıra SQL bəyanatlarını yerinə yetirə bilərsiniz. Əgər (məsələn) PostgreSQL ilə yayıla bilən bir proqram qurursunuzsa, bunu etmək istəyərsiniz – verilənlər bazasını qurmaq üçün kod yazacaqsınız və quraşdırmada işə salarsınız.

Ancaq daha sürətli bir yol var.

SQLite verilənlər bazası diskret bir fayl olduğundan, verilənlər bazasını klonlaşdırmaq nisbətən mənasızdır – sadəcə bir faylı çoxaldır. Bu o deməkdir ki, ümumiyyətlə yeni bir verilənlər bazası yaratmaq və sonra tələb olunan bütün SQL ifadələrini icra etmək lazım deyildir. Adətən, sadəcə bir nüsxə edə bilərsiniz.

Bunu edərkən Android-də məlumat bazalarını aktiv olaraq idarə etmək üçün SQLite Asset Helper-dən istifadə etmək istəyə bilərsiniz.

Denormalizing düşünün

Nisbi verilənlər bazası sistemləri ilə təcrübəniz varsa, məlumatlarınızı normallaşdırmaq üçün çox qayğı göstərə bilərsiniz. Bundan daha çox şey var, lakin məlumatların normallaşmasının mahiyyəti: həqiqətin tək mənbəyidir.

Normallaşdırılmış bir əlaqəli verilənlər bazasında nə qədər mənasız olursa olsun, hər hansı bir məlumat parçası tam olaraq bir dəfə təmsil olunur. Beləliklə, məsələn, bir kitabı əks etdirən bir yazı müəllifi əks etdirən qeydə istinad edə bilər – ancaq əlbətdə müəllifin adını yazmayacaqdır.

Bu yer qənaət edir və daha zərifdir. Lakin bu, verilənlər bazasından oxumağı daha çox vaxt aparır. Bir müəllif tərəfindən bütün kitabları tapmaq istəyirsinizsə, id almaq üçün müəllif cədvəlini axtarmalısınız, sonra kitab masasını axtarın və qeydləri yığın.

Bütün kitab qeydlərində müəllifin adını çoxaltmaqla bu cür oxumağı sürətləndirə bilərsiniz. Bu performansı yaxşılaşdırır, amma normallaşmağı qurban verir. Bunun mənasızlıqdan başqa iki mümkün mənfi tərəfi var:

  • Tətbiq məntiqi məlumat bütövlüyünün qorunması üçün məsuliyyət daşıyır (yəni doğruluğu və ya dəqiqliyini).
  • Eyni miqdarda məlumat saxlamaq üçün verilənlər bazasının daha böyük olması lazımdır.

SQLite-də denormalizasiya xüsusilə yaxşıdır

Bütün bu narahatlıqlar və ticarət əlaqələri yalnız SQLite ilə deyil, hər hansı bir RDBMS sistemi ilə işləyərkən mövcuddur. Bununla birlikdə, SQLite-də məlumatların denormalizasiyasını daha az problemli və daha faydalı hala gətirən bəzi potensial yumşaldıcı amillər mövcuddur..

  • Tipik olaraq, SQLite tətbiqetməsində verilənlər bazası serverinə ehtiyacı olan çox böyük bir tətbiqdən daha az mürəkkəb bir məlumat modeli (sxem) olacaqdır. Bu, denormalizasiya edilmiş məlumatları dəstəkləmək üçün lazım olan tətbiqetmə mürəkkəbliyini daha az çətinləşdirir.
  • SQLite verilənlər bazası tərəfindən dəstəklənən məlumat dəstləri adətən digər verilənlər bazası sistemlərində saxlanılanlardan daha kiçikdir. Bu, təkrarlanan məlumatlardan ölçülərin artmasının daha az problemli olması deməkdir. Bundan əlavə, əksər SQLite tətbiqlərinin miqyasında (yerli sənəd saxlama) əlavə ölçülərin dəyəri cüzidir.
  • Böyük verilənlər bazası serverlərindən (xüsusən təşkilatlar tərəfindən qorunanlardan) fərqli olaraq, ikinci bir tətbiqinizin tətbiqiniz tərəfindən yaradılan SQLite verilənlər bazası sənədlərinə qoşulmağa çalışması ehtimalı azdır. Buna görə, təsadüfi məlumatların korlanması və problemli komanda dinamikasından qorunmaq lazım deyil.
  • Eynilə, SQLite adətən əlaqədar verilənlər bazası kimi istifadə edildiyi üçün tətbiqetmə ilə verilənlər bazası quruluşu arasında çox vaxt sıx bir əlaqə mövcuddur. Bu o deməkdir ki, tətbiq daxilində məlumat bütövlüyünün işlənməsinin aşağı tərəfləri ümumilikdə verilənlər bazası və tətbiqi fiziki cəhətdən cəlbedicidir, lakin reallıqda çox asılıdır.
  • Nəhayət, digər verilənlər bazası sistemlərində mövcud olan normallaşdırma təmin edən performans gücləndiricilərindən bəziləri – məsələn, materiallaşdırılmış baxışlar – SQLite-də mövcud deyildir.

Bu səbəblərə görə performans üçün ləğv etmə digər əlaqəli verilənlər bazası ilə müqayisədə SQLite ilə daha yaygın bir tətbiqdir.

Xülasə

SQLite performansını optimallaşdırmaq üçün bu göstərişlər yalnız budur – məsləhətlər. Bu əməl etmək üçün dəqiq bir plan deyil və SQLite tətbiqinizi bu siyahıdan hər bir elementi kodunuza əlavə etməklə sürətləndirməyəcəksiniz. Lazımi şəkildə istifadə edilsə kömək edə biləcək fikirlərdir. Buna görə tətbiqinizi düşünün və onlardan hər hansı biri kömək edə biləcəyinə baxın. Və test. Sürətli düzəltmədən əvvəl tətbiqinizi nə yavaşlatdığını öyrənməlisiniz.

Əlavə oxu və mənbələr

Kodlaşdırma və inkişafla əlaqəli daha çox təlimat, dərs vəsaiti və infoqrafiya var:

  • SQL Resources: bütün əlaqəli verilənlər bazası inkişaf etdiriciləri üçün vacib olan ümumi SQL mənbəyimiz.
  • MySQL Giriş və Resurslar: başqa bir populyar verilənlər bazası sistemi.
  • PostgreSQL Giriş və Resurslar: populyar bir verilənlər bazası sistemi, SQLite qismən buna əsaslanır.

Veb Hosting üçün Son Bələdçi

Veb Hosting üçün Ultimate Bələdçimizə baxın. Məlumatlı bir seçim etmək üçün bilmək lazım olan hər şeyi izah edəcəkdir.

Veb Hosting üçün Son Bələdçi
Veb Hosting üçün Son Bələdçi

Jeffrey Wilson Administrator
Sorry! The Author has not filled his profile.
follow me
    Like this post? Please share to your friends:
    Adblock
    detector
    map