PDA

View Full Version : حرفه ای: بحث درباره دیتابیس و فایل



i love you php
شنبه 10 بهمن 1394, 20:58 عصر
با سلام؛
دوستان ؛ سوالی منو خیلی درگیر کرده ...
چگونه کلاسی بنویسم که قدرت یک دیتابیس معمولی را حداقل داشته باشد .
من چندین بار روی آن کار کردم اما سرعت بسیار بد ؛ 20000 تا که فایل محتوا داشتم 15 ثانیه برای بروز کردن آدرس دیتابیس وقت میگرفت :) .
مشکلات من ، تنها سرعت نبود ؛ جستجو , حذف و... بخشی از مشکلات بود ...

کلاسهایی که نوشته بودم به این شکل عمل میکرد .
فایل را به صورت json در مسیر db/Ym/Ymdhis.db ذخیره میکرد .
سپس آدرس هر فایل در داخل فایل آدرس ذخیره میشد :

db/data-address.db

و به شکل :

13941012092420
13941012092443
13941012092508
.
.
ذخیره ، و هر گاه می خواستم فایلها را نمایش دهم "آخرین پست ها" ؛ count میگرفتم و مثلا از آخر به اول بسته به تنظیم متد کلاسم 10 تا 10 تا نمایش میدادم ، مثلا :)

حالا حساب کنید برای آرشیو شمسی و میلادی من باید db/Ym چجوری ثبت میکردم . که البته یجوری حلش میکردم ...

اما پیچیدگی زیادی در میامد .

حال می دانم می فرمایید که وقتی دیتابیس های قدرتمند و آماده هست چرا با فایل :) منم میگم وقتی ربات آماده برای فروش هست چرا ساخت ربتهای تکراری مثلا مسیر یاب :)

--------------------------------

حال می خواهم در رابطه با دیتابیس و نحوه ی کارکرد آن به زبان ساده و اجرایی نه تئوری با هم تبادل نظر کنیم و ایده بدیم که اگر شما پایگاه داده می ساختید ، آن هم تنها با php چجوری کلاس می نوشتید .

i love you php
یک شنبه 11 بهمن 1394, 13:59 عصر
دوستان ؛ امروز آمدم به تقلید از mysql کلاسم را بهتر نوشتم .
حداقل کل اطلاعات روی یک فایل می باشد .
تمام اطلاعات به صورت json ذخیره و درون یک فایل قرار داده می شود
و در زمان فراخوانی میگیم id = name ( شماره کاربری فلان و نام فلان هر چه ذخیره شده (نام طرف) را بر میگرداند .)

منتها محدودیت بالایی دارد .

مثلا اگر حجم کل اطلاعات در مجموع ؛مثلا 20 فیلد 1 کیلوبایت باشد و 1000 رکورد : برای سلکت کردن پنج فیلد از یک شناسه آی دی > 0.0.8 ثانیه زمان می برد .
همین را اگر روی 30 کیلوبایت بزنم 500 مگ باید محدودیت استفاده از رم را کم کنم و حدودا 3.3 ثانیه حدودا زمان می برد .

حال برای کم حجم کردن اطلاعات و سرعت و کم کردن میزان استفاده از رم باید چه کنم.

البته برای ذخیره :

json_encode($data,JSON_UNESCAPED_UNICODE)
قرار دادم تا حجم فایل نصف گردد :)

چطور در mysql حجم های هر جدول ؛ 1 گیگ به 1 گیگ تقسیم بندی می شوند و حدود یک میلیون رکورد را حدودا در 2 ثانیه انتخاب میکنند .
ولی من با روی 28 مگ گیر کردم ....



خواهشاً من را یاری بفرمایید .

i love you php
یک شنبه 11 بهمن 1394, 14:46 عصر
این کلاس را بعد از ظهر نوشتم

<?php

class dbfile{

public $address;
//------------------------------
function __construct(){
header('content-type: application/json; charset=utf-8');
}
//------------------------------
public function ifnotfile($file)
{
$file=explode('/',$file);
$a='';
$count=count($file);
if(strstr(end($file),'.')){$count--;$u=1;}else{$u=0;};
for($i=0;$i<$count;$i++){
$a.=$file[$i].'/';
if(!is_dir($a)){mkdir($a);}
if(!is_file($a.'index.php')){file_put_contents($a. 'index.php','');}
}
if($u==1){if(!is_file($a.$file[$count])){file_put_contents($a.$file[$count],'');}}
return $file;
}
//------------------------------
public function insert_update($id,$content)
{
@$data = json_decode(file_get_contents($this->address), true);
$data[$id] = $content;
file_put_contents($this->address,json_encode($data,JSON_UNESCAPED_UNICODE)) ;
}
//------------------------------
public function select($id,$table)
{
$obj = json_decode(file_get_contents($this->address));
if(isset($obj->{$id}->{$table})){ return $obj->{$id}->{$table};};
}
//------------------------------
public function delete($id)
{
$data = json_decode(file_get_contents($this->address), true);
unset($data[$id]);
file_put_contents($this->address,json_encode($data));
}
//------------------------------
public function select_all()
{
$data = json_decode(file_get_contents($this->address),TRUE);
$count= count($data);
$content=array_keys($data);
for($i=0;$i<$count;$i++){
$content[$i];
}
return $content;
}
//------------------------------
public function count()
{
$data = json_decode(file_get_contents($this->address),TRUE);
return count($data);
}



}

$dbf=new dbfile;
$dbf->address='db.txt';

/*
$content = array(
'name' => 'رضا',
'family' => 'karimi',
'age' => '28',
'date' => '20160131142713'
);
$dbf->insert_update(3,$content);
*/
//echo $dbf->select('3','name');
//$dbf->delete('2');
//print_r($dbf->select_all());
//echo $dbf->count();
?>

مهرداد سیف زاده
یک شنبه 11 بهمن 1394, 18:21 عصر
دوست عزیز این که قوه طراحی دوباره چرخ شما گل کرده، شکی بر آن نیست
یعنی به نظر شما تیم توسعه mysql( که الان اوراکل هست) و تیم توسعه دهنده mariadb ( که همون پدید آورنده mysql هستن) به این فکر نیفتادن؟
روشهای فایلی خیلی خیلی پیچیده هست. اون ها با زبان c دارن مستقیما روی فایل میخونن و مینویسن، اونم نه به روش شما که هم ram زیادی میگیره و هم io رو درگیره میکنه، بلکه بیت به بیت و بر حسب نیاز
این که در ۱ گیگ فایل چطور داده رو پیدا میکنه و شما روی ۲۸ مگ گیر کردید برمیگرده به روشهای فایلی. در دیتابیس‌ها با بزرگ شدن فایل index گذاری میشه و هر داده‌ای در جای خودش مشخص هست. با یک select فورا به index میره و داده رو برمیداره. ولی شما داری فایل رو کامل باز میکنی(که میشه مصرف بیهوده ram) بعدش حجم فایلی که توی memory ذخیره میشه و خونده میشه.
در کل چیزهای بهتری هست، یا همون مسیریاب. ولی دیگه چرخ دیتابیس خیلی وقته راه افتاده، جای طراحی دوبارش خنده داره.

plague
یک شنبه 11 بهمن 1394, 18:59 عصر
چیزی که شما دارید راجبش حرف میزنید و دنبالش میری دیتبایس های nosql هستن پس به جای دیتبایس های رابطه ای مثل mysql بهتره راجب اونها تحقیق کنید

مشخصا دیتابیس های سند محور document based که اکثرا از همین json استفاده میکنن که معروف ترینشون mongodb هستش
من انقد علمش رو ندارم که بخام براتون بیشتر بازش کنم ولی اینجوری که من متوجه شدم اکثر این دیتبایس ها با مشکلی که شما دارید روبرو هستن مثلا برای سلکت کردن یا آپدیت کردن مجبورید حجم زیادی دیتا رو جابجا کنن که باید تحقیق کنید ببینید چجوری بر این مشکلات غلبه میکنن چون با وجود این موارد معروف هستن که سرعت بالایی دارن و میتونن حجم زیادی از دیتبایس رو پردازش کنن

i love you php
دوشنبه 12 بهمن 1394, 08:28 صبح
ممنون از همراهی شما دوستان

i love you php
سه شنبه 13 بهمن 1394, 15:03 عصر
در نهایت تواستم به اندازه ای بهینه کنم که 10 رکورد از 500,000 رکورد را کمتر از 0.5 ثانیه به انتخاب صفحه، نمایش دهد . البته برای نوشتن حدودا 3 ثانیه . که برای بهینه کردن آن هم راه حل است .
و برای چنین حجمی از اطلاعات ؛ هنگام خواندم 128 مگ تنها حافظه رم مصرف می نمایید . که البته کسی برای چنین رکوردی از دیتابیس فایلی با قابلیت های محدود استفاده نخواهد کرد .

اما واقعا بهینه و سریع شد .


اشتباهات :
1. برای انتخاب هر رکورد نباید به تعداد فیلدها، ما تابع انتخابی که نوشتیم فراخوانی کنیم ، در عوض تمام فیلد ها را به شکل آرایه قرار دهیم و به انتخاب اجرا کنیم . مانند اشتباه کد بالا :


echo $dbf->select('3','name');


رعایت این نکته به تعداد فراخوانی به شکل فوق ، X برابر سرعت را کاهش می دهد . مثلا اگر برای خواندن، 0.5 ثانیه زمان ببرد ؛ 10 فیلد معادل بر 5 ثانیه ، خواهد بود ، اما به روش آرایه همان 0.5 ثانیه برای ما زمان خواهد برد :)
البته تجربه نبود ؛ یک اشتباه از سر بی توجهی بود . وگرنه مشخصه که یک فایل را ده بار باز کنیم با باز کردن یکباره از زمین تا آسمان فرق دارد .

2. برای حذف کردن نیازی نیست اطلاعات را هم در فایل اطلاعات و هم در آدرس فایل اطلاعات حذف کرد . کافیست تنها آدرس اطلاعات حذف گردد . البته اگر سیستم جستجو در این پایگاه داده قرار بگیرد ، همه چیز نمایش پیدا میکند ، و هنوز مشکل جستجو حل نگردید .

3. داده ها باید پارت بندی گردند . از 50 رکورد یک فایل مثلا : v1.txt v2.txt v3.txt و ... .

و ...

هفته دیگر انشالله ، نسخه ی بتا از کلاس خود را در github قرار خواهم داد .


با تشکر