مهدی
4 سال پیش توسط مهدی مطرح شد
3 پاسخ

مشکل در MYSQL

سلام
من دیتابیسی برای ذخیره بازدیدهای وبسایتم طراحی کرده ام اما یک مشکل دارد که به شرح زیر است:

ساختار دیتابیس

| id | last_visit          | date       | count |
|----|---------------------|------------|-------|
| 1  | 2020-09-21 15:47:30 | 1399-06-30 | 10    |

فیلد date در جدول به از جنس DATE تعریف شده است. مشکلی که در این جدول وجود دارید این است که mysql ماه و تعداد روز را چک می کند و در مثال فوق mysql فرض می کند که ماه ششم میلادی از سال 1399 انتخاب شده و چون ماه ششم 30 روز است من نمی توانم در جدول عدد 31-06-1399 را ثبت کنم.
علت اینکه با چنین ساختاری اطلاعات را ذخیره می کنم به شرح زیر است:

public function month(){
        $verta = New Verta();
        $currentMonth = $verta->month;
        $currentYear = $verta->year;
        $data = Visits::whereYear('date', $currentYear)->whereMonth('date', $currentMonth)->orderBy('date', 'asc')->get();

        $items = [];

        foreach($data as $datum){
            $day = explode('-', $datum['date']);
            $day = (int)$day[2];
            $items[$day] = $datum['count'];
        }
        return response()->json($items);
    }

در خط چهارم این متد همانطور که مشخص است من فیلد date را مورد بررسی قرار داده و اطلاعات ماه جاری در سال جاری را بدست می آورم. یعنی اطلاعات ماه شهریور سال 99
طبیعتا تغییر این ساختار بسیار مشکل است و حجم زیادی از محاسبات را بهم میریزد، در این صورت باید چه کنم؟ راه حلی برای رفع ارور mysql دارید؟


ثبت پرسش جدید
مهدی
تخصص : برنامه نویس و طراح وب
@mrmmg 4 سال پیش مطرح شد
1

خب خب خب! بالاخره مشکل حل شد
راه حل این مشکل:

  1. ذخیره تاریخ به صورت میلادی در فیلد date جدول
  2. استفاده ترکیبی از پکیج های ورتا و کربن و اصلاح کد

نمونه کد اصلاح شده تابع مذکور در سوال را در زیر ببینید:

public function month(){
        $verta = New Verta();
        $carbon = New Carbon();

        $startMonth = Carbon::instance($verta->startMonth()->datetime())->format('Y-m-d');
        $endMonth = Carbon::instance($verta->endMonth()->datetime())->format('Y-m-d');
        $currentYear = $carbon->year;

        $data = Visits::whereYear('date', $currentYear)->whereBetween('date', [$startMonth, $endMonth])->orderBy('date', 'asc')->get();

        $items = [];

        foreach($data as $datum){
            $day = explode('-', $datum['date']);
            $jalali = $verta->createDate($day[0], $day[1], $day[2]);
            $jalali = explode('-', $jalali);
            $day = (int)$jalali[2];
            $items[$day] = $datum['count'];
        }
        return response()->json($items);
    }

البته این راه حل رو هوز هم موقتی تلقی میکنم و به دنبال اصلاح بیشتر و بهتر کد خودم هستم، اگر راهکاری دارید خوشحال میشم از طریق کامنت ها به اطلاعم برسونید.


saman
@saman1111 4 سال پیش مطرح شد
1

سلام
شما باید به صورت میلادی تاریخ رو ذخیره کنید و فقط برای استفاده اون رو به شمسی تبدیل کنید.
هیچموقع تاریخ شمسی در دیتابیس ذخیره نکنید


مهدی
تخصص : برنامه نویس و طراح وب
@mrmmg 4 سال پیش مطرح شد
0

@saman1111 به این دلیل اومدم به صورت شمسی هم ذخیره کردم چونکه نیازمند این بودم که با استفاده از پکیج تاریخ شمسی Verta رو بدست میارم و بر اساس همین تاریخ نمودار بازدید رسم میکنم. یعنی راهی برای بدست اوردن بازه تاریخ شمسی از روی تاریخ میلادی پیدا نکردم. مثلا چطوری بیام و تشخیص بدم که 1 تا 31 شهریور معادل 22 آگوست تا 21 سپتامبر هست؟
نمودار بازدید ماهانه

همانطور که در تصویر بالا مشخصه در محور X عدد 1 تا 31 در نظر گرفته میشه و بازدید اون روز در محور Y نمایش داده میشه. با این فرضیات چطوری باید این مساله را حل کرد؟


مهدی
تخصص : برنامه نویس و طراح وب
@mrmmg 4 سال پیش مطرح شد
1

خب خب خب! بالاخره مشکل حل شد
راه حل این مشکل:

  1. ذخیره تاریخ به صورت میلادی در فیلد date جدول
  2. استفاده ترکیبی از پکیج های ورتا و کربن و اصلاح کد

نمونه کد اصلاح شده تابع مذکور در سوال را در زیر ببینید:

public function month(){
        $verta = New Verta();
        $carbon = New Carbon();

        $startMonth = Carbon::instance($verta->startMonth()->datetime())->format('Y-m-d');
        $endMonth = Carbon::instance($verta->endMonth()->datetime())->format('Y-m-d');
        $currentYear = $carbon->year;

        $data = Visits::whereYear('date', $currentYear)->whereBetween('date', [$startMonth, $endMonth])->orderBy('date', 'asc')->get();

        $items = [];

        foreach($data as $datum){
            $day = explode('-', $datum['date']);
            $jalali = $verta->createDate($day[0], $day[1], $day[2]);
            $jalali = explode('-', $jalali);
            $day = (int)$jalali[2];
            $items[$day] = $datum['count'];
        }
        return response()->json($items);
    }

البته این راه حل رو هوز هم موقتی تلقی میکنم و به دنبال اصلاح بیشتر و بهتر کد خودم هستم، اگر راهکاری دارید خوشحال میشم از طریق کامنت ها به اطلاعم برسونید.


برای ارسال پاسخ لازم است وارد شده یا ثبت‌نام کنید

ورود یا ثبت‌نام