ডাটাবেস প্রশ্নগুলি পৃষ্ঠা থেকে নিজেই বিমূর্ত হওয়া উচিত?


10

পিএইচপি-তে পৃষ্ঠা জেনারেশন লেখার সময়, আমি প্রায়শই নিজেকে ডাটাবেস কোয়েরিগুলিতে লিখিত ফাইলগুলির সেট লিখতে দেখি। উদাহরণস্বরূপ, কোনও পৃষ্ঠায় প্রদর্শন করার জন্য আমার কাছে ডাটাবেস থেকে সরাসরি কোনও পোস্ট সম্পর্কে কিছু তথ্য আনার জন্য একটি প্রশ্ন থাকতে পারে:

$statement = $db->prepare('SELECT * FROM posts WHERE id=:id');
$statement->bindValue(':id', $id, PDO::PARAM_INT);
$statement->execute();
$post = $statement->fetch(PDO::FETCH_ASSOC);
$content = $post['content']
// do something with the content

এই দ্রুত, এক-বন্ধ জিজ্ঞাস্যগুলি সাধারণত ছোট হয় তবে আমি মাঝে মাঝে ডাটাবেস ইন্টারঅ্যাকশন কোডের বড় অংশগুলি দিয়ে শেষ করি যা দেখতে বেশ অগোছালো দেখা শুরু করে।

কিছু ক্ষেত্রে, আমি আমার পোস্ট সম্পর্কিত ডিবি কোয়েরিগুলি পরিচালনা করার জন্য ফাংশনগুলির একটি সাধারণ গ্রন্থাগার তৈরি করে এই কোডটির ব্লকটি একটি সহজ করে সংক্ষিপ্ত করে এই সমস্যার সমাধান করেছি:

$content = post_get_content($id);

এবং এটি দুর্দান্ত। বা কমপক্ষে এটি অন্য কিছু করার দরকার না হওয়া পর্যন্ত। একটি তালিকায় প্রদর্শিত হতে পারে আমার সবচেয়ে সাম্প্রতিক পাঁচটি পোস্ট পেতে হবে। ঠিক আছে, আমি সবসময় অন্য ফাংশন যুক্ত করতে পারতাম:

$recent_posts = post_get_recent(5);
foreach ($recent_posts as $post) { ... }

তবে এটি একটি SELECT *ক্যোয়ারী ব্যবহার করে শেষ হয় , যার সাধারণত আমার সাধারণত প্রয়োজন হয় না তবে প্রায়শই যুক্তিযুক্ত বিমূর্ত করার পক্ষে খুব জটিল হয়। আমি শেষ পর্যন্ত প্রতিটি একক ব্যবহারের ক্ষেত্রে ডাটাবেস ইন্টারঅ্যাকশন ফাংশনগুলির একটি বিশাল গ্রন্থাগার, বা প্রতিটি পৃষ্ঠার কোডের অভ্যন্তরে নোংরা কোয়েরিগুলির একটি সিরিজ দিয়ে শেষ করি। এমনকি একবার আমি এই লাইব্রেরিগুলি তৈরি করে নেওয়ার পরে, আমি নিজেকে একটি ছোটখাটো যোগদান করতে হবে যা আমি আগে ব্যবহার করি নি এবং হঠাৎ কাজটি করার জন্য আমাকে আরও একটি উচ্চ-বিশেষায়িত ফাংশন লিখতে হবে।

অবশ্যই, আমি নির্দিষ্ট ইন্টারঅ্যাকশনগুলির জন্য সাধারণ ব্যবহারের ক্ষেত্রে এবং প্রশ্নের জন্য ফাংশনগুলি ব্যবহার করতে পারি, তবে কাঁচা প্রশ্নগুলি লিখতে শুরু করার সাথে সাথে আমি সমস্ত কিছুর জন্য সরাসরি অ্যাক্সেসে ফিরে যেতে শুরু করি। তা হয়, না হয় আমি অলস হয়ে যাব এবং পিএইচপি লুপগুলিতে এমন কাজ শুরু করব যা সত্যিই মাইএসকিউএল কোয়েরিতে সরাসরি করা উচিত।

আমি ইন্টারনেট অ্যাপ্লিকেশন লেখার সাথে আরও অভিজ্ঞদের জিজ্ঞাসা করতে চাই: কোডের অতিরিক্ত লাইন এবং বিমূর্ততাগুলি প্রবর্তন করতে পারে এমন সম্ভাব্য অদক্ষতার মূল্য রক্ষণাবেক্ষণতা কি? অথবা সহজেই সরাসরি জিজ্ঞাসার স্ট্রিংগুলি ডাটাবেস ইন্টারঅ্যাকশন পরিচালনা করার জন্য একটি গ্রহণযোগ্য পদ্ধতি ব্যবহার করছেন?


সম্ভবত আপনি "মোড়ানো" অগোছালো selectগুলি সংরক্ষণের জন্য ব্যবহার করতে পারেন - আপনার কেবলমাত্র প্রয়োজনীয় প্যারামিটারগুলির সাথে এই জাতীয় পদ্ধতিগুলি কল করতে হবে
102

উত্তর:


7

আপনার যখন খুব বেশি বিশেষায়িত ক্যোয়ারী ফাংশন থাকে আপনি তাদেরকে কমপোজেবল বিটে বিভক্ত করার চেষ্টা করতে পারেন। এই ক্ষেত্রে

$posts = posts()->joinWithComments()->orderBy("post.post_date")->first(5);

বিমূর্ত স্তরগুলির একটি শ্রেণিবিন্যাসও রয়েছে যা আপনি মনে রাখতে দরকারী বলে মনে করতে পারেন। তোমার আছে

  1. mysql API
  2. আপনার মাইএসকিএল ফাংশন, যেমন নির্বাচন করুন ("পোস্টগুলি থেকে foo = বার" নির্বাচন করুন "); বা সম্ভবত আরও কমপোজযোগ্যselect("posts")->where("foo = bar")->first(5)
  3. উদাহরণস্বরূপ, আপনার অ্যাপ্লিকেশন ডোমেনের সাথে সুনির্দিষ্ট ফাংশন posts()->joinWithComments()
  4. কোনও নির্দিষ্ট পৃষ্ঠায় নির্দিষ্ট ফাংশন যেমন commentsToBeReviewed($currentUser)

বিমূর্ততার এই আদেশটিকে সম্মান করতে রক্ষণাবেক্ষণের স্বাচ্ছন্দ্যের ক্ষেত্রে এটি প্রচুর অর্থ প্রদান করে। পৃষ্ঠাগুলি স্ক্রিপ্টগুলিতে মাত্র 4 স্তরের ফাংশন ব্যবহার করা উচিত, স্তর 4 ফাংশন 3 স্তরের ফাংশনগুলির ক্ষেত্রে লেখা উচিত so এটি সত্য যে সামনের দিকে সামান্য বেশি সময় নেয় তবে এটি আপনার রক্ষণাবেক্ষণ ব্যয়কে সময়ের সাথে অবিচ্ছিন্ন রাখতে সহায়তা করবে ("ওহ আমার গোশ তারা অন্য পরিবর্তন চায় !!!" এর বিপরীতে)


2
+1 এই বাক্য গঠনটি আপনার নিজের ORM তৈরি করে। আপনি যদি ডাটাবেস অ্যাক্সেসের জিনিসগুলি জটিল হয়ে ওঠার বিষয়ে সত্যিই চিন্তিত হন এবং বিশদটি নিয়ে কিছুটা সময় ব্যয় করতে চান না তবে আমি একটি পরিপক্ক ওয়েব ফ্রেমওয়ার্ক (উদাহরণস্বরূপ কোডআইগনিটার ) ব্যবহার করার পরামর্শ দিচ্ছি যা ইতিমধ্যে এই জিনিসটি খুঁজে পেয়েছে । বা কমপক্ষে এটি ব্যবহার করার চেষ্টা করুন এটি আপনাকে কী ধরণের সিনট্যাকটিক চিনি দেয় তা এক্সপিমেটোও যা দেখিয়েছে তার অনুরূপ।
হার্টলে ব্রোডি

5

উদ্বেগ পৃথকীকরণ সম্পর্কে পড়ার জন্য একটি নীতি, এটি উইকিপিডিয়া নিবন্ধ দেখুন।

http://en.wikipedia.org/wiki/Separation_of_concerns

সম্পর্কে পড়ার মতো আরও একটি মূলনীতি হল কাপলিং:

http://en.wikedia.org/wiki/Coupling_( কম্পিউটার_সায়েন্স )

আপনার দুটি স্বতন্ত্র উদ্বেগ রয়েছে, একটি হ'ল ডাটাবেস থেকে ডেটা মার্শালিং এবং দ্বিতীয়টি হ'ল ডেটা উপস্থাপন। সত্যিই সাধারণ অ্যাপ্লিকেশনগুলিতে আপনার চিন্তার খুব কমই রয়েছে, আপনি আপনার রেন্ডারিং স্তরটির সাথে আপনার ডাটাবেস অ্যাক্সেস এবং পরিচালনা স্তরটিকে শক্তভাবে সংযুক্ত করেছেন তবে ছোট অ্যাপ্লিকেশনগুলির জন্য এটি কোনও বড় বিষয় নয়। সমস্যাটি হ'ল ওয়েব অ্যাপ্লিকেশনগুলির বিকাশ ঘটে এবং আপনি যদি কোনও ওয়েব অ্যাপকে কোনও উপায়ে অর্থাত্ পারফরম্যান্স বা কার্যকারিতা বাড়াতে চান তবে আপনি কিছু সমস্যার মধ্যে চলে যান।

বলুন যে আপনি ব্যবহারকারীর দ্বারা উত্পাদিত মন্তব্যের একটি ওয়েব পৃষ্ঠা তৈরি করছেন। সেই সাথে মোটা কেশিক বস আসেন এবং আপনাকে নেটিভ অ্যাপ্লিকেশনগুলি যেমন আইফোন / অ্যান্ড্রয়েড ইত্যাদির সমর্থন শুরু করতে বলেন আমাদের কিছু জেএসওএন আউটপুট প্রয়োজন, আপনাকে এখন রেন্ডারিং কোডটি বের করতে হবে যা এইচটিএমএল তৈরি করছে। আপনি যখন এটি সম্পন্ন করেছেন এখন আপনি দুটি রেন্ডারিং ইঞ্জিন সহ একটি ডেটা অ্যাক্সেস লাইব্রেরি পেয়েছেন এবং সবকিছু ঠিকঠাক হয়ে গেলে, আপনি কার্যকরীভাবে মাপলেন। আপনি এমনকি রেন্ডারিং থেকে ব্যবসায়ের লজিককে পৃথক করে রাখতে সক্ষম হয়েছেন।

পাশাপাশি বস আসবেন এবং আপনাকে বলবেন যে তাঁর একটি গ্রাহক আছেন যারা তাদের ওয়েবসাইটে পোস্টগুলি প্রদর্শন করতে চান, তাদের এক্সএমএল প্রয়োজন এবং তাদের প্রতি দ্বিতীয় শিখরের পারফরম্যান্সে প্রায় 5000 অনুরোধের প্রয়োজন হয়। এখন আপনাকে এক্সএমএল / জেএসএন / এইচটিএমএল তৈরি করতে হবে। আপনি আপনার রেন্ডারিং আবার আলাদা করতে পারেন আগের মত। তবে আপনার প্রয়োজন অনুযায়ী পারফরম্যান্সটি পাওয়ার জন্য এখন আপনাকে 100 টি সার্ভার যুক্ত করতে হবে। এখন আপনার ডাটাবেসটি 100 সার্ভার থেকে সম্ভবত সার্ভারে কয়েক ডজন সংযোগের মাধ্যমে হিট হচ্ছে, যার প্রতিটি প্রত্যক্ষভাবে সরাসরি বিভিন্ন প্রয়োজনীয়তা এবং বিভিন্ন প্রশ্নের সাথে তিনটি পৃথক অ্যাপ্লিকেশনকে উন্মুক্ত করা হয়েছে। প্রতিটি ফ্রন্টএন্ড মেশিনে ডাটাবেস অ্যাক্সেস থাকা একটি সুরক্ষা ঝুঁকি এবং ক্রমবর্ধমান is এক কিন্তু আমি সেখানে যাব না। এখন আপনাকে পারফরম্যান্সের জন্য স্কেল করতে হবে, প্রতিটি অ্যাপ্লিকেশনটির বিভিন্ন ক্যাশে প্রয়োজনীয়তা রয়েছে যেমন বিভিন্ন উদ্বেগ। আপনি এটি দৃ tight়ভাবে সংযুক্ত স্তর হিসাবে আপনার ডাটাবেস অ্যাক্সেস / ব্যবসায়িক যুক্তি / রেন্ডারিং স্তরটিতে এটি চেষ্টা করে পরিচালনা করতে পারেন। প্রতিটি স্তরের উদ্বেগগুলি এখন একে অপরের পথে আসতে শুরু করেছে অর্থাৎ ডাটাবেস থেকে ডেটা ক্যাশে করার প্রয়োজনীয়তা রেন্ডারিং লেয়ারের তুলনায় খুব আলাদা হতে পারে, আপনার ব্যবসায়ের স্তরটিতে যে যুক্তি রয়েছে তাতে রক্তক্ষরণ হওয়ার সম্ভাবনা রয়েছে এসকিউএল অর্থাত্ পিছন দিকে সরে যাওয়া বা এটি রেন্ডারিং লেয়ারের দিকে এগিয়ে যেতে পারে, এটিই একটি বৃহত্তম সমস্যা যা আমি দেখেছি এক স্তরে সমস্ত কিছু থাকা, এটি আপনার প্রয়োগের মধ্যে শক্তিশালী কংক্রিট likeালার মতো এবং কোনও ভাল উপায়ে নয়।

এই ধরণের সমস্যার কাছে যাওয়ার জন্য স্ট্যান্ডার্ড উপায় রয়েছে যেমন ওয়েব পরিষেবাদির এইচটিটিপি ক্যাচিং (স্কুইড / ইয়টস ইত্যাদি)। ওয়েব পরিষেবাগুলিতে অ্যাপ্লিকেশন স্তরের ক্যাচিং মেমক্যাচ / রেডিসের মতো কিছু দিয়ে থাকে। আপনি আপনার ডাটাবেস যেমন একাধিক পঠিত হোস্ট এবং একটি মাস্টার, বা হোস্ট জুড়ে শারডযুক্ত ডেটা স্কেল শুরু করার সাথে সাথে সমস্যার সমাধান করতে পারবেন। আপনি চাইছেন না যে আপনার 100 টি হোস্ট আপনার ডাটাবেসে বিভিন্ন সংযোগ পরিচালনা করছে যা লেখার জন্য বা পড়ার অনুরোধের ভিত্তিতে বা একটি ধারালো ডাটাবেসে কোনও ব্যবহারকারী যদি "ইউজার" হ্যাশগুলিকে সমস্ত লেখার অনুরোধের জন্য "[টেবিল / ডাটাবেস] ফু" দিয়ে থাকে তার উপর ভিত্তি করে আলাদা হয়।

উদ্বেগের বিচ্ছেদ আপনার বন্ধু, এটি কখন এবং কোথায় করবেন তা বেছে নেওয়া একটি স্থাপত্যিক সিদ্ধান্ত এবং কিছুটা শিল্প। খুব আলাদা প্রয়োজনীয়তার জন্য বিকশিত হবে এমন কোনও কিছুর সংমিশ্রণ সংযোজন এড়িয়ে চলুন। জিনিস আলাদা রাখার জন্য আরও অনেকগুলি কারণ রয়েছে এটি পরীক্ষা-নিরীক্ষা, পরিবর্তন মোতায়েন, সুরক্ষা, পুনরায় ব্যবহার, নমনীয়তা ইত্যাদি সহজ করে


আমি বুঝতে পেরেছি আপনি কোথা থেকে এসেছেন, এবং আপনি যা বলেছেন তার সাথে আমি একমত নই, তবে এটি এখনই একটি ছোট উদ্বেগ। প্রশ্নে প্রকল্পটি একটি ব্যক্তিগত, এবং আমার বর্তমান মডেলটির সাথে আমার বেশিরভাগ সমস্যাটি শক্তিশালী সংযোজন এড়াতে আমার প্রোগ্রামারের প্রবৃত্তি থেকে আসছে, তবে আমি জটিল সার্ভার-সাইড বিকাশের সত্যিই একজন নবাগত, তাই এর শেষটা কিছুটা এগিয়ে গেল আমার মাথার উপর. তবুও, আমার কাছে যা ভাল বলে মনে হচ্ছে তার জন্য +1, যদিও আমি এই প্রকল্পের জন্য এটি পুরোপুরি অনুসরণ না করি।
অ্যালেক্সিস কিং

আপনি যা করছেন তা যদি ছোট থেকে যায় তবে আমি এটিকে যথাসম্ভব সহজ রাখি। এখানে অনুসরণ করার জন্য একটি ভাল নীতি হ'ল YAGNI
হ্যারি

1

আমি ধরে নিয়েছি যে আপনি যখন "পৃষ্ঠাটি নিজেই" বলবেন তখন আপনার অর্থ পিএইচপি উত্স ফাইল যা গতিশীলভাবে এইচটিএমএল উত্পন্ন করে।

ডাটাবেসগুলি জিজ্ঞাসা করবেন না এবং একই উত্স ফাইলে এইচটিএমএল তৈরি করুন।

উত্স ফাইল যেখানে আপনি ডাটাবেসটি জিজ্ঞাসা করেছেন এটি কোনও "পৃষ্ঠা" নয়, যদিও এটি একটি পিএইচপি উত্স ফাইল।

পিএইচপি উত্স ফাইলে যেখানে আপনি গতিশীলভাবে এইচটিএমএল তৈরি করেন আপনি কেবলমাত্র সেই ফাংশনগুলিতে কল করেন যেখানে পিএইচপি উত্স ফাইলে সংজ্ঞায়িত হয় যেখানে ডাটাবেস অ্যাক্সেস করা হয়।


0

আমি বেশিরভাগ মাঝারি স্কেল প্রকল্পের জন্য যে ধরণটি ব্যবহার করি তা হ'ল:

  • সমস্ত এসকিউএল কোয়েরিগুলি একটি পৃথক স্থানে সার্ভার-সাইড কোড থেকে আলাদা করা হয়।

    সি # এর সাথে কাজ করা, এর অর্থ আংশিক ক্লাস ব্যবহার করা, অর্থাত্ কোয়েরিগুলিকে একটি পৃথক ফাইলে রাখা, এই প্রশ্নগুলি একক শ্রেণীর অ্যাক্সেসযোগ্য হবে (নীচের কোডটি দেখুন)।

  • এই এসকিউএল কোয়েরিগুলি ধ্রুবক । এটি গুরুত্বপূর্ণ, যেহেতু এটি ফ্লাইতে এসকিউএল কোয়েরিগুলি তৈরির প্রলোভন প্রতিরোধ করে (এভাবে এসকিউএল ইঞ্জেকশনের ঝুঁকি বাড়ায় এবং একই সাথে পরে প্রশ্নগুলি পর্যালোচনা করা আরও কঠিন করে তোলে)।

সি # তে বর্তমান পদ্ধতি

উদাহরণ:

// Demo.cs
public partial class Demo : DataRepository
{
    public IEnumerable<Stuff> LoadStuff(int categoryId)
    {
        return this
            .Query(Queries.LoadStuff)
            .With(new { CategoryId = categoryId })
            .ReadRows<Stuff>();
    }

    // Other methods go here.
}

public partial class Demo
{
    private static class Queries
    {
        public const string LoadStuff = @"
select top 100 [StuffId], [SomeText]
    from [Schema].[Table]
    where [CategoryId] = @CategoryId
    order by [CreationUtcTime]";

        // Other queries go here.
    }
}

এই পদ্ধতির প্রশ্নের আলাদা আলাদা ফাইলে থাকার সুবিধা রয়েছে। এটি ডিবিএকে বিকাশকারীদের দ্বারা সম্পাদিত সমঝোতার সাথে দ্বন্দ্ব না করেই অনুসন্ধানগুলি পর্যালোচনা ও সংশোধন / অনুকূলিত করতে এবং পরিবর্তিত ফাইলটিকে উত্স নিয়ন্ত্রণে প্রতিশ্রুতিবদ্ধ করার অনুমতি দেয়।

সম্পর্কিত বেনিফিটটি হ'ল উত্স নিয়ন্ত্রণটি ডিবিএর অ্যাক্সেসকে কেবলমাত্র সেই ফাইলগুলিতে সন্ধান করতে পারে যা কোয়েরিগুলিকে সীমাবদ্ধ করতে পারে এবং বাকী কোডটিতে অ্যাক্সেস অস্বীকার করে।

পিএইচপি করা কি সম্ভব?

পিএইচপি-তে আংশিক শ্রেণী এবং অভ্যন্তরীণ উভয় শ্রেণির অভাব রয়েছে, সুতরাং যেমন পিএইচপি তে এটি প্রয়োগ করা যায় না।

DemoQueriesধ্রুবকগুলি সমন্বিত একটি পৃথক স্ট্যাটিক ক্লাস ( ) সহ আপনি একটি পৃথক ফাইল তৈরি করতে পারেন , প্রদত্ত শ্রেণিটি যে কোনও জায়গা থেকে অ্যাক্সেসযোগ্য হবে given তদুপরি, বিশ্বব্যাপী সুযোগকে দূষিত করা এড়ানোর জন্য, আপনি সমস্ত ক্যোয়ারী ক্লাস একটি নিবেদিত নেমস্পেসে রাখতে পারেন। এটি বরং ভার্বোজের বাক্য গঠন তৈরি করবে, তবে আমি সন্দেহ করি যে আপনি ভার্বোসটি এড়াতে পারবেন:

namespace Data {
    public class Demo inherit DataRepository {
        public function LoadStuff($categoryId) {
            $query = \Queries\Demo::$LoadStuff;
            // Do the stuff with the query.
        }

        // Other methods go here.
    }
}

namespace Queries {
    public static class Demo {
        public const $LoadStuff = '...';

        // Other queries go here.
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.