ایپدا  مقالات آموزشی مقالات SQLSERVER جاي دیتا درون جداول ديتابيس است، نه درون کدی که می نویسیم

جاي دیتا درون جداول ديتابيس است، نه درون کدی که می نویسیم

  • در اين نوشته مي خواهم روی این نکته تاکید و توصيه کنم که: حداکثر سعی خود را بکنید تا تمام داده هایی را که به دیتابیس مربوط می شود درون جدول ها ذخیره کنید.
    می دانم که می گویید اینکه خیلی واضح است! اما اگر متوجه شويد که چه مقدار از دیتای اپلیکیشن تان در عوض آنکه درون جدول های دیتابیس شما _جایی که به آن تعلق دارند_ باشند درون کد قرار گرفته اند، حتما تعجب خواهید کرد!

    مثال شماره 1
    شرکتی 3 شیفت در روز تعریف می کند: شیفت 1 از 12:00 صبح–8 صبح، شیفت 2 از 8 صبح-4 عصر، شیفت 3 از 4 عصر-12 صبح. بنابراین اگر بخواهید یک متغیر از نوع DateTime را محاسبه کنید تا ببینید در کدام شیفت قرار گرفته می نویسید:

    SELECT ..., CASE 
                WHEN Hour(SomeDate) <  8 THEN 1
                WHEN Hour(SomeDate) < 16 THEN 2
                ELSE 3
           END as ShiftNo
    FROM ...
    

    فوق العاده است، فقط الان دیتا را درون کد ذخیره کرده اید – نه درون یک جدول! بیایید با ساختن جدولی با نام "Shifts" دیتا را جایی ذخیره کنیم که به آنجا تعلق دارد:

    Shifts


    ShiftNo (PK) StartHour

    EndHour

    Description

    1 0 7 Morning
    2 8 15 Day
    3 16 23 Night

    و حالا به سادگي مي نويسيد:


     SELECT ...., Shift.ShiftNo, Shift.Description
    FROM ...
    INNER JOIN Shift
      ON Hour(SomeDate) BETWEEN Shift.StartHour and Shift.EndHour
    

    به این ترتیب می توانید توضیحات، مدیران شیفت ها، تنظیم محاسبات و هر چیز دیگری که به یک شیفت مربوط می شود را هم به جدول اضافه کنید. علاوه بر این می توانید از این جدول Shift برای تهیه گزارش استفاده کنید و حالا دیگر اگر بخواهید تعداد شیفت ها را به 4 عدد تغییر دهید، باید دیتا را تغییر دهید و هیچ لازم نیست کد را دست کاری کنید. حتی از این هم بهتر اینکه می توانید یک فلگ "WeekEnd" (پايان هفته) یا ستون "WeekDay" (روز هفته) به جدول شیفت اضافه کنید تا امکان تعریف شیفت های مختلفی را برای روزهای مختلف هفته فراهم کنید؛ ستون های بیشتری برای موارد ديگر اضافه كنيد. حتي با اضافه كردن ستونهاي StartDate/EndDate به كليد اوليه اين جدول، مي توان تغييرات را از نظر تاريخي ارائه و بصورت مشخص مستند كرد.


    (نكته: طبعا" اين يك مثال بسيار ساده است، گو اينكه شيفت ها معمولا تا پاسي بعد از نيمه شب ادامه دارند (!)، اما در اينجا براي آنكه مفهوم اصلي را درك كنيد از آن استفاده كردم.)

    مثال شماره 2

    شركتي پاداش ها را بر اساس نوع كارمند پرداخت مي كند: مديران 10% حقوق ساليانه، كارمندان عادي 7% و سرپرست ها 5%. بنابراين براي محاسبه پاداش، خيلي ساده مي نويسيد:
    SELECT ..., Salary * CASE EmpType WHEN 'Manager' THEN .10 
                                      WHEN 'Regular' THEN .07 
                                      WHEN 'Admin' THEN .05 
                                      ELSE 0 
                         END as Bonus
    FROM ...

    ضمنا" در گزارش پرسنل هميشه مي خواهيد اول از همه مديران را فهرست كنيد، بعد كارمندان عادي و پس از آن سرپرست ها را؛ نمي توانيد آنها را برحسب حروف الفبا مرتب كنيد، بنابراين مي نويسيد:
    SELECT ...
    FROM ...
    ORDER BY CASE EmpType WHEN 'Manager' THEN 1 
                          WHEN 'Regular' THEN 2 
                          WHEN 'Admin' THEN 3
                          ELSE 4
             END ASC
    


    خيلي خوب كار مي ده! اما شما يك جدول با عنوان EmployeeType (نوع كارمندان) داريد، درسته؟ اگر نداريد الان وقتش است كه ايجادش كنيد. حتي اگر چنين جدولي هم داشتيد، به خاطر داشته باشيد كه داده ها را در جدول قرار بدهيد، نه كد:

    EmpType (PK)

    BonusPct

    Sort

    'Manager'

    .10

    1

    'Regular'

    .07

    2

    'Admin'

    .05

    3


    حالا يك join ساده به اين جدول آنچه كه نياز داريد را به شما تحويل مي دهد. ديگر در SELECT ي كه مي نويسيد نه به CASE هاي بيشتري احتياج است و نه به كدهاي دشوار-دشوار! به علاوه الان تغيير درصدها يا ايجاد انواع جديد كارمندان با ويرايش محتواي جداول ميسر است و به هيچ وجه نيازي به اصلاح كد نيست. خيلي ساده و روشن است، نه؟ البته هميشه هم نه!

    مثال شماره 3

    در يك شركت محصولات خاصي نبايد در گزارش هاي ساليانه نمايان شوند، زيرا داخلي هستند، تمام شده اند يا براي اهداف آزمايشي استفاده شدند. در گزارشها براي مقادير مشخصي استثناء قائل مي شويم و اين كار را به سادگي تمام انجام مي دهيم، مگر نه؟
    SELECT ..
    FROM ...
    WHERE ProductTypeID Not IN (24,203,1,293)
    

    خيلي ساده است و خوب هم جواب مي ده! اما فكر مي كنم بدانيد كه چه مي شود – چرا اين داده ها را در كد ذخيره كنيم وقتي بايستي در جدولي كه براي نوع محصول داريم نگهداري شوند؟ يك ستون ناقابل يا چند شاخص ديگر به جدول اضافه كنيد تا در بخش ديتا اين اقلام را مشخص كنند تا بتوانيد اين مقادير را از كدتان برداريد. حتي اگر نمي توانيد جدول ProductTypes (انواع محصولات) را ويرايش كنيد، با ساختن يك جدول جديد قادر خواهيد بود اين كار را انجام دهيد:

    ProductTypeID (PK, FK)

    Notes

    24

    'Testing'

    203

    'Converted to product type #12'

    1

    'Internal'

    293

    ‘Testing’


    به كمك چنين جدولي، با يك LEFT OUTER JOIN به اين جدول مي توانيد بفهميد چه زماني بايد براي يك مورد خاص استثناء قائل شد:
    SELECT ...
    FROM ...
    LEFT OUTER JOIN ProductTypeExclusions PEX 
      ON ...
    WHERE PEX.ProductTypeID is NULL 
    

    حالا در بخش ديتايمان درباره اينكه چه نوع محصولاتي بايد مستثني شوند (و چرا) مستندسازي داريم و به آساني مي توانيم بدون كامپايل دوباره كد، تغييرات انجام دهيم و حتي با استفاده از اين جدول گزارش بنويسيم. مي توانيم به اين جدول دامنه تاريخ يا فاكتورهاي ديگري اضافه كنيم كه مشخص كنند ProductTypes (انواع محصولات) خاصي چه موقع در گزارشهايمان ظاهر شوند و يا حذف گردند.
    به عنوان يك اثر جانبي خوب ديگر، عبارت SELECT به روشني به ما مي گويد كه چرا داريم اقلام خاصي را از گزارش مستثني مي كنيم و ديگر لازم نيست ندانيم ليست بزرگي از ID ها چه معني دارند!

    مثال شماره 4

    و سرانجام اينكه با دقت بيشتري جداول "look-up" را مطالعه كنيد. ما همه از آنها استفاده مي كنيم – اين جدولها روش فوق العاده اي براي ايجاد فهرستي از مقادير معتبر براي ستون هاي خاص هستند؛ و اغلب بيش از اين كاري انجام نمي دهند:

    StatusCode (PK)

    Description

    A

    Approved

    P

    Preliminary

    R

    Rejected

    D

    Deleted

    H

    Archived


    اگر جدولي مانند جدول بالا در سيستم تان داريد دستتان را بالا ببريد! اما واقعا" اين جدول به خودي خود چه چيزي به ما مي گويد؟ معني واقعي 'Rejected' چيست؟ براي فهميدن اين مطلب معمولا" بايد به اپليكيشن يا كد T-SQL ي كه نوشتيم نگاه بيندازيم. در آنجا كدهايي مانند اينها نوشتيم:
    ... WHERE StatusCode IN ('A','H') ... هر چه كه معتبر باشد را بر مي گرداند
    ... IF StatusCode NOT IN ('P','R','A') THEN ... مواردي كه نمي توان ويرايش كرد
    ... WHERE StatusCode IN ('P','R') ... تمامي اشيائي را كه مي توان بازنگري كرد نشان مي دهد
    ... IF StatusCode IN ('P','R') THEN ... اجازه حذف آنرا مي دهد
    و الي آخر... (توجه داشته باشيد كه اوضاع از اين هم بدتر مي شود وقتي از شناسه ها (ID) به عنوان PK اين جدول جستجو استفاده مي كنيم، اما شرح اين موضوع خود يك مقاله را در بر مي گيرد!) اين نيز يك مثال بسيار ساده است و ممكن است مفهوم قسمتي از اين كدها را متوجه نشويد، اما منظور اصلي را در مي يابيد.
    اما ما درحقيقت اينجا چه مي كنيم؟ مقصود اين جدول Status چيست؟ آيا از آن به حد وافر بهره مي گيريم؟ آيا واقعا بايد ديتا(مقادير كد وضعيت) را با درون كدمان بگنجانيم؟ اگر بخواهيم وضعيت جديد اضافه كنيم چه اتفاقي مي افتد؟ بار ديگر جواب واضح است: سعي كنيد داده ها را تا حد امكان در جدول ها ذخيره كنيد و آنرا از كد بيرون بكشيد. ممكن است اين مثال در نگاه اول به آساني قابل درك نباشد، اما با دقت آنرا ملاحظه كنيد:

    StatusCode (PK)

    Description

    IsValid

    IsEditable

    IsReviewable

    IsDeletable

    A

    Approved

    1

    1

    0

    0

    P

    Preliminary

    0

    1

    1

    1

    R

    Rejected

    0

    1

    1

    1

    D

    Deleted

    0

    0

    0

    0

    H

    Archived

    1

    0

    0

    0


    به ناگهان جدول StatusCodes (كد وضعيت ها) تعاريف بسيار روشني از اينكه معني حقيقي اين كدها چيست (خودش خود را به خوبي مستند مي كند!) و نحوه استفاده اپليكيشن و گزارشها از آنها را در خود دارد. اگر به ازاي هر يك از اعمال اصلي مختلفي كه برنامه مي تواند انجام دهد ستوني در اين جدول در نظر بگيريم، تقريبا هرگز لازم نخواهد شد هيچ ديتايي زا به كدمان اضافه كنيم، اما در عوض داده ها در جدول ها زندگي مي كنند! حالا با يك JOIN ساده به جدول Status مي توانيم بنويسيم:
    ...
    WHERE IsValid =1 ...
    IF isEditable = 0 THEN ...
    ... WHERE isReviewable = 1 ...
    IF isDeleteable = 1 THEN ...
    

    و غيره. اكنون مي توانيم كدهاي وضعيت را تغيير بدهيم، كدهاي جديد ايجاد كنيم و آنها را مجددا دسته بندي كنيم – همه اين كارها را در بخش ديتا انجام مي دهيم.

    نتيجه گيري

    تا آنجا كه به نظر مي رسد تمامي موارد بالا يك سري مطالب بديهي و روشنتر از روزند! با اين حال براي همه ما گاهي پيش مي آيد بيش از مقداري كه بايد در كدمان ديتا وارد مي كنيم، بعضي اوقات چون اين كار سريعتر است و معطلي كمتري دارد و برخي اوقات هم چون نمي توانيم نموداري را كه طراحي كرده ايم تغيير بدهيم، اما بيشتر اوقات به اين علت است كه از پيش براي پياده سازي، آن مقدار كه بايد برنامه ريزي نكرده ايم.
    اميدوارم اين نوشته توانسته باشد ايده هايي درباره راههايي كه مي توان به وسيله آن ديتا را بيشتر در جايي كه بايد – درون جدول ها -- قرار داد ارائه كند. به اين ترتيب كد مختصرتر و قابل فهم تري خواهيد داشت و خواهيد ديد كه ناخودآگاه داده هايتان در واقع سيستم شما را به خوبي مستندسازي مي كنند و اين امكان را فراهم مي كنند كه هنگام انجام اصلاحات گسترده، تغييرات تنها در جدول ها اعمال شوند.



    نوشته شده توسط محسن کاویانی
    در تاریخ 1394/01/29
    ضمیمه ها :
    آیا برایتان مفید بود ؟     







    دریافت مقاله
  • لطفا برای ارسال نظر خود به سیستم ورود کنید.
  • نظرات کاربران
    7نظر برای این مقاله تاکنون ثبت شده است.



    توسط محسن کاویانی

        ارسال شده در 1394/12/11


    تست
    <br/>&lt;br/&gt;اینتر
    <br/>&lt;br/&gt;سیستماتیک
    خیلی اینتر کار رو بد خراب میکنه

    پاسخ              
    توسط محسن کاویانی

        ارسال شده در 1394/12/12


    این نظر بنده است

          
    توسط محسن کاویانی

        ارسال شده در 1394/12/11


    نظر دوم
    سر دوم نظر دوم

    پاسخ              
    توسط محسن کاویانی

        ارسال شده در 1394/12/11


    پاسخ در پاسخ نظر نوم

          
    توسط محسن کاویانی

        ارسال شده در 1394/12/11


    پاسخ در پاسخ نظر نوم

          
    توسط محسن کاویانی

        ارسال شده در 1394/12/11


    نظر سوم

    پاسخ              
    توسط محسن کاویانی

        ارسال شده در 1394/12/12


    sda

          

درباره IPDA

شرکت ایده پردازان دنیای داده که با نام تجاری ایپدا فعالیت می کند، شرکتی است نوپا اما با کوله باری از تجربیات و ایده های نوین اعضایی که هر کدام سابقه ی طولانی و موفق در زمینه ی فعالیت خود دارند


اطلاعات بیشتر