কেন একটি ডাটাবেসের জন্য সম্পর্কিত মডেল পদার্থ?


61

আমি এমন একটি প্রকল্পের দিকে যাচ্ছি যেখানে আমাকে আমার বসের সাথে একটি ডাটাবেস প্রয়োগ করতে হবে; কাজের পরিবেশ গভীরভাবে ব্যক্তিগত তাই আমরা খুব ছোট একটি সূচনা।

তিনি আমাকে আগে কোম্পানির একটি ডাটাবেস দিয়েছিলেন এবং এটি আরডিবিএমএসের জন্য স্কুলে আমাকে যা শিখানো হয়েছিল (এবং তার সম্পর্কে পড়ুন) পুরোপুরি এটির বিরুদ্ধে গিয়েছিল। উদাহরণস্বরূপ, এখানে পুরো ডাটাবেস রয়েছে যা একটি সারণী (প্রতি স্বাধীন ডাটাবেস) নিয়ে গঠিত। এই টেবিলগুলির মধ্যে একটি হ'ল 20+ কলাম দীর্ঘ এবং প্রসঙ্গে, এখানে একটি টেবিলের কিছু কলামের নাম দেওয়া হয়েছে :

lngStoreID | vrStoreName | lngCompanyID | vrCompanyName | lngProductID | vrProductName

মূল কথাটি হ'ল যেখানে তাঁর পৃথক সারণী থাকা উচিত যা সত্তা ডেটা (নাম, আকার, খরিদ তারিখ ইত্যাদি) ধারণ করে সে সমস্ত ডাটাবেসটিতে একটি বড় টেবিলের মধ্যে রেখে দেয়।

আমি এই নকশাটি উন্নত করতে চাই, তবে কেন আমি সঠিকভাবে নরমালাইজড এবং বিভাগযুক্ত ডেটা মডেলটি এই পণ্যটির উন্নতি করতে পারে তা নিশ্চিত not যদিও আমি কলেজ থেকে ডেটাবেস ডিজাইনের সাথে পরিচিত এবং এটি কীভাবে করব তা আমি বুঝতে পেরেছি, কেন এটি আসলে ডাটাবেসের উন্নতি করে তা আমি নিশ্চিত নই ।

কেন একটি ভাল সম্পর্কযুক্ত স্কিমা একটি ডাটাবেস উন্নত করে?


33
একটি শব্দ: সাধারণীকরণ।
রবার্ট হার্ভে

9
ভোটার বন্ধ করুন - নিজেকে ন্যায়সঙ্গত করুন! :-)
রবি ডি

6
নতুন কর্মীদের পক্ষে কারণগুলির কারণগুলি না বুঝে প্রতিষ্ঠিত পদ্ধতিগুলির সমালোচনা করা সাধারণ, এমনকি যদি কারণগুলি প্রযুক্তিগতভাবে সঠিক না হয়। প্রথমে আপনার বস কেন সেভাবে এটি তৈরি করেছিলেন তা সন্ধান করুন। সে / সে খুব ভাল করেই জানে যে এটি একটি ভাল নকশা নয়, তবে এটি আরও ভাল করার জন্য জ্ঞান (বা সম্ভবত বেশি সময়) নেই। আপনার প্রস্তাবিত যে কোনও পরিবর্তন সম্ভবত আপনি যদি বর্তমান নকশার কারণগুলি শ্রদ্ধার সাথে স্বীকার করেন তবে সম্ভবত আরও ইতিবাচকভাবে গ্রহণ করা হবে।
পেড্রো

5
He [the boss] had given me one of his databases before and it completely went against what I was taught (and read about) in school for RDBMS<- বাস্তব বিশ্বের আপনাকে স্বাগতম!
মাওজ

5
আমি আমার প্রিয় সম্পর্কের ডাটাবেসের উক্তিটির কথা মনে করিয়ে দিচ্ছি: "যতক্ষণ না এটি ব্যথা হয় ততক্ষণ স্বাভাবিক করুন, এটি কাজ করে তাত্পর্যপূর্ণ করুন"
জ্যাক

উত্তর:


70

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

আর একটি হ'ল স্টোরেজ আকারের যুক্তি। প্রচুর রিন্ডন্ডেন্সিসহ একটি অস্বীকৃত টেবিলের জন্য আরও বেশি স্টোরেজ প্রয়োজন storage এটি পারফরম্যান্স দিকটিতেও খেলবে: আপনার যত বেশি ডেটা থাকবে আপনার প্রশ্নগুলি ধীরে ধীরে হবে।

একটি যুক্তিও রয়েছে যা বোঝা কিছুটা শক্ত, তবে বাস্তবে এটি আরও গুরুত্বপূর্ণ কারণ আপনি এটিতে আরও হার্ডওয়ার ছুঁড়ে দিয়ে সমাধান করতে পারবেন না। এটি ডেটা ধারাবাহিকতার সমস্যা। একটি সঠিকভাবে সাধারণীকৃত ডাটাবেস নিজেই যত্ন নেবে যে নির্দিষ্ট আইডি সহ একটি পণ্যের সর্বদা একই নাম থাকে। তবে একটি অস্বীকৃত ডাটাবেসে এই জাতীয় অসঙ্গতিগুলি সম্ভব, সুতরাং অসঙ্গতিগুলি এড়ানো যখন বিশেষ যত্ন নেওয়া দরকার, যা সঠিক হওয়ার জন্য প্রোগ্রামিংয়ের সময় লাগবে এবং তবুও ত্রুটিগুলি সৃষ্টি করবে যা গ্রাহক সন্তুষ্টিতে আপনাকে ব্যয় করবে।


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


11
আমি নিশ্চিত নই যে কেন ধারাবাহিকতার যুক্তিটি "বোঝা শক্ত।" এটি আমার কাছে অনেক সহজ বলে মনে হচ্ছে: যদি কোনও মান পরিবর্তন হয় তবে অবশ্যই সেই মানটির সমস্ত অনুলিপি আপডেট করতে হবে। একক অনুলিপি আপডেট করা একই ডেটার শত শত বা কয়েক হাজার অনুলিপি আপডেট করার চেয়ে কম ত্রুটিযুক্ত প্রবণ। এটি ডেটার মধ্যকার সম্পর্কের ক্ষেত্রেও সমানভাবে প্রযোজ্য । (আমার যদি সম্পর্কের দুটি উপায় সঞ্চিত থাকে তবে আমাকে সম্পর্কের দুটি অনুলিপি আপডেট করতে হবে)) অস্বীকৃত ডিবিতে এটি একটি অত্যন্ত সাধারণ সমস্যা; এটা খুব (একটি ব্যতিক্রম দর্শন প্রকার ব্যবহার রূপায়িত হয়) বাস্তবে এই দুর্নীতির প্রতিরোধ কঠিন।
jpmc26

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

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

24

আমি আমার বসের সাথে একটি ডাটাবেস বাস্তবায়ন করব ...

ডেডিকেটেড ডেটাবেস ম্যানেজমেন্ট সফটওয়্যার ব্যবহার করা যথেষ্ট সহজ হতে পারে (দুঃখিত; প্রতিরোধ করতে পারেনি)।

lngStoreID | vrStoreName | lngCompanyID | vrCompanyName | lngProductID | vrProductName

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

তবে ...

এই ডেটা ব্যবহার করে অ্যাপ্লিকেশন / ক্যোয়ারীগুলি কি খারাপ / ধীরে ধীরে সাড়া দেয়? যদি তা না হয় তবে সমাধানের জন্য আসল সমস্যা নেই। অবশ্যই, এটি দেখতে দেখতে কুৎসিত মনে হয়, তবে এটি যদি কাজ করে তবে আপনি এটির প্রস্তাব দেওয়ার জন্য কোনও "পয়েন্ট" পাবেন না "আরও ভাল" হতে পারে।

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

এটি ভাল "দর্শন .." দিয়ে ডেটা তার "একক টেবিল দেখুন" পুনরায় তৈরি করা পুরোপুরি সম্ভব।


11
একক টেবিলের ওয়েল্টান্সচাউংয়ের প্রতিরোধ প্রায়ই আসে যারা এসকিউএল-এর সাথে অনভিজ্ঞ যারা যোগ দেয় না বুঝতে পারে না - বিশেষত হারিয়ে যাওয়া ডেটার সাথে সম্পর্কিত অর্থাৎ বাইরের সাথে যোগ দেয় with
রবি ডি

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

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

1
@ জাচ: সম্মত, সেজন্যই বিক্রয় লগ সম্ভাব্যত এটির জন্য একটি গ্রহণযোগ্য কেস। মনে করুন আপনি যে প্রতিটি বিক্রয় বিক্রয়টির সময় নামকরণ করেছিলেন, তার সাথে "দোকানের বর্তমান নাম" নয় , তার সাথে যুক্ত হতে চান , তারপরে "স্বাভাবিককরণ" করার চেষ্টা করার ফলে এটি কিছুটা জটিলতার পরিচয় দেয় (কারণ টেবিল রেকর্ডিং স্টোরের নাম স্টোরিডের জন্য কেবল একটি মূল্য নয়, সময়ের সাথে একটি সিরিজ হওয়া দরকার
স্টিভ জেসপ

সম্ভবত থাম্বের নিয়মটি হ'ল যদি প্রস্তাবিত স্বাভাবিককরণের দ্বারা প্রবর্তিত একমাত্র জটিলতাটি হ'ল যে কয়েকটি ক্যোয়ারিতে তাদের যে সমস্ত কলামগুলি প্রতিবেদন করতে হবে তা চয়ন করতে এখন তাদের সাথে যোগ দেওয়া দরকার, তবে আপনার সেই পরিবর্তনটি করতে হাঁটাচলা করা উচিত নয়: - )
স্টিভ জেসোপ

14

কেন একটি ভাল সম্পর্কযুক্ত স্কিমা একটি ডাটাবেস উন্নত করে?

উত্তরটি হ'ল: এটি সর্বদা একটি ডেটাবেস উন্নত করে না । আপনার সচেতন হওয়া উচিত যে আপনাকে সম্ভবত যা শেখানো হয়েছিল তাকে তৃতীয় নরমাল ফর্ম বলা হয় ।

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

3NF বিধি ডেটাবেসের মধ্যে "উন্নতি" করে এমন ডেটার মধ্যে সম্পর্ক স্থাপন করে:

  1. আপনার সিস্টেমে অবৈধ ডেটা প্রবেশ করতে বাধা দিন (যদি কোনও সম্পর্ক 1-থেকে -1 হয় তবে এটির উপরে লিখিত কোড থাকা সত্ত্বেও এটি একটি ত্রুটি জোর করে)। যদি আপনার ডেটাবেস ডাটাবেসে সামঞ্জস্যপূর্ণ থাকে তবে এটি আপনার ডাটাবেসের বাইরে অসঙ্গতি হওয়ার সম্ভাবনা কম।

  2. এটি কোডকে বৈধতা দেওয়ার একটি উপায় সরবরাহ করে (উদাহরণস্বরূপ বহু-এক-এক সম্পর্ক কোনও অবজেক্টের বৈশিষ্ট্য / আচরণগুলি সীমাবদ্ধ করার লক্ষণ। ডাটাবেস ব্যবহার করার জন্য কোড লেখার সময়, প্রোগ্রামাররা কখনও কখনও তাদের কোডটি কীভাবে কাজ করা উচিত তার একটি সূচক হিসাবে ডেটা স্ট্রাকচারটি লক্ষ্য করেন। অথবা ডাটাবেস যদি তাদের কোডের সাথে মেলে না তবে তারা দরকারী প্রতিক্রিয়া সরবরাহ করতে পারে। (এটি দুর্ভাগ্যক্রমে শুভাকাঙ্ক্ষী চিন্তাভাবনার মতো))

  3. এমন কোনও নিয়ম সরবরাহ করুন যা ডেটাবেস তৈরি করার সময় ভুলগুলি হ্রাস করতে আপনাকে সহায়তা করতে পারে, যাতে আপনি এটি নির্বিচারে প্রয়োজনের উপর ভিত্তি করে তৈরি করছেন না যা কোনও ডাটাবেসের জীবনের সময় যে কোনও সময় আসতে পারে। পরিবর্তে, আপনি নির্দিষ্ট লক্ষ্য অর্জনের জন্য তথ্যটি পদ্ধতিগতভাবে মূল্যায়ন করছেন।

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

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

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

শুভকামনা!


4
উল্লেখ না করে তবে আমি মনে করি প্রোগ্রামারদের কাছে একটি গুরুত্বপূর্ণ বিষয় হ'ল একটি "জিনিস" সম্পাদনা করার জন্য সেই একক জিনিসটি সন্ধান এবং প্রতিস্থাপনের জন্য পুরো ডাটাবেস লুপ না করে কেবল একটি একক সারির সম্পাদনা প্রয়োজন requires
slebetman

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

@ jpmc26: ডাটাবেসটি লুপ করে আমি বোঝাচ্ছি যে সমস্ত প্রভাবিত সারিগুলি আপডেট করার জন্য একটি কোয়েরি তৈরি করা। কখনও কখনও একটি একক যথেষ্ট suff তবে আমি অপরিষ্কার কাঠামো দেখেছি যেগুলি পরিবর্তিত হওয়া উচিত না এমন সারিগুলিকে প্রভাবিত না করেই সমস্ত আক্রান্ত সারিগুলি একই টেবিলে সাবলেট করতে হবে। এমনকী আমি এমন কাঠামো দেখেছি যেখানে একটি একক ক্যোয়ারী কাজটি করতে পারে না (সত্তার পরিবর্তনের প্রয়োজনে সত্তা সারি অনুসারে বিভিন্ন কলামে বাস করে)
slebetman

এই প্রশ্নের অনেক দুর্দান্ত উত্তর, এবং এটি ব্যতিক্রম ছিল না।
মাইক চেম্বারলাইন

11

একাধিক কারণে কেন একটি বড় "গড টেবিল" ব্যবহার করা খারাপ। আমি চেষ্টা করব এবং একটি উদাহরণস্বরূপ তৈরি একটি উদাহরণ ডেটাবেস দিয়ে সমস্যাগুলি বর্ণনা করব। ধরে নেওয়া যাক আপনি ক্রীড়া ইভেন্টগুলি মডেল করার চেষ্টা করছেন। আমরা বলব যে আপনি মডেল গেমস এবং দলগুলি সেই গেমগুলিতে খেলতে চান। একাধিক টেবিল সহ একটি নকশা এটি দেখতে দেখতে (এটি উদ্দেশ্যটির পক্ষে খুব সরলতর তাই আরও সাধারণীকরণ প্রয়োগ করা যেতে পারে এমন জায়গায় আটকাবেন না):

Teams
Id | Name | HomeCity

Games
Id | StartsAt | HomeTeamId | AwayTeamId | Location

এবং একটি একক টেবিল ডাটাবেস এর মত দেখতে হবে

TeamsAndGames
Id | TeamName | TeamHomeCity | GameStartsAt | GameHomeTeamId | GameAwayTeamId | Location

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

দ্বিতীয়ত, ডেটা ধারাবাহিকতা। দুটি পৃথক টেবিল ব্যবহার করার ক্ষেত্রে, আমি কোন দল খেলায় খেলছে তা নির্ধারণ করতে আমি টেবিল থেকে Gamesটেবিলের কাছে বিদেশী কী ব্যবহার Teamsকরতে পারি। এবং ধরে নিলাম যে আমি HomeTeamIdএবং AwayTeamIdকলামগুলি বাতিল নয়, ডাটাবেসটি নিশ্চিত করবে যে আমি যে খেলাগুলি রেখেছি সেগুলিতে 2 টি দল রয়েছে এবং সেই দলগুলি আমার ডেটাবেজে উপস্থিত রয়েছে। তবে একক টেবিলের দৃশ্যের কী হবে? ঠিক আছে, যেহেতু এই টেবিলটিতে একাধিক সত্ত্বা রয়েছে, সেই কলামগুলি অবিচ্ছিন্ন হওয়া উচিত (আপনি এগুলিকে আবশ্যক নয় এবং সেখানে আবর্জনার ডেটা সরিয়ে ফেলতে পারেন, তবে এটি কেবল একটি ভয়ঙ্কর ধারণা)। যদি এই কলামগুলি অবিস্মরণযোগ্য হয় তবে ডাটাবেসটি আর গ্যারান্টি দিতে পারে না আপনি যখন কোনও গেম সন্নিবেশ করান যে এটিতে দুটি দল রয়েছে।

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

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

(এটি আরও খারাপ হয়ে যায় যদি আপনার নকশাটি এমন এক যেখানে আপনি বিদেশী কীগুলি ব্যবহার না করে সারিগুলির মধ্যে সমস্ত প্রাসঙ্গিক ডেটা অনুলিপি করেন। যেকোন বানান / অন্যান্য ডেটা অসঙ্গতিগুলি সমাধান করা কঠিন। "জন" যদি "জন" এর ভুল বানান হয় তবে আপনি কীভাবে বলতে পারবেন? "বা যদি এটি উদ্দেশ্যমূলক ছিল (কারণ তারা দুটি পৃথক ব্যক্তি)?)

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

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

শেষ অবধি, এমন কিছু বিকাশ করুন যা বজায় রাখা সহজ হবে। এটি "কাজ করে" এর অর্থ এটি ঠিক আছে। গড টেবিলগুলি বজায় রাখার চেষ্টা করা (godশ্বরের ক্লাসগুলির মতো) একটি দুঃস্বপ্ন। আপনি পরে ব্যথার জন্য নিজেকে প্রস্তুত করছেন।


1
"টিমস: আইডি | নাম | হোমসিটি"। কেবল নিশ্চিত হয়ে নিন যে আপনার ডেটা স্কিমা আপনার অ্যাপ্লিকেশনটিকে ভুলভাবে দাবি করে না যে সুপার বোল XXXIV এলএ র‌্যামসের দ্বারা জিতেছে। যদিও বর্তমানে এলএ র‌্যামস নামে পরিচিত দলটি জিতেছে সমস্ত চ্যাম্পিয়নশিপগুলির জন্য একটি কোয়েরিতে এসবি এক্সএক্সএক্সএক্সআইএল-তে উপস্থিত হওয়া উচিত । আরও ভাল এবং আরও খারাপ "গড টেবিল" রয়েছে এবং আপনি অবশ্যই একটি খারাপ উপস্থাপনা করেছেন। আরও ভাল একটি হ'ল "গেম আইডি | হোম টিমের নাম | হোম টিম সিটি | দূরের দলের নাম | টিম সিটি | গেম শুরু হয় ইত্যাদি ..." " যা "নিউ অরলিন্স সান্টস @ শিকাগো বিয়ার্স 1 পি ইস্টার্ন" এর মতো মডেল তথ্যের প্রথম প্রচেষ্টা হিসাবে আসে।
স্টিভ জেসোপ

6

দিনের উদ্ধৃতি: " তত্ত্ব এবং অনুশীলন একই হওয়া উচিত ... তত্ত্বের মধ্যে "

অস্বীকৃত টেবিল

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

  • এটি সম্পর্কের অপ্রয়োজনীয় কপিগুলি রাখে (যেমন IngCompanyIDএবং vrCompanyName)। মাস্টার ডেটা আপডেট করার জন্য সাধারণ স্কিমার চেয়ে অনেক বেশি লাইন আপডেট করা দরকার update
  • এটি সবকিছু মিশ্রিত করে। আপনি ডাটাবেস পর্যায়ে একটি সহজ অ্যাক্সেস নিয়ন্ত্রণ নিশ্চিত করতে পারবেন না, উদাহরণস্বরূপ যে ব্যবহারকারী এটিকে কেবল কোম্পানির তথ্য এবং ব্যবহারকারী বি কেবলমাত্র পণ্য তথ্য আপডেট করতে পারে তা নিশ্চিত করে।
  • আপনি ডাটাবেস পর্যায়ে ধারাবাহিকতা সংক্রান্ত নিয়মগুলি নিশ্চিত করতে পারবেন না (যেমন কোনও কোম্পানির আইডির জন্য কেবলমাত্র একটি কোম্পানির নাম রয়েছে তা প্রয়োগের জন্য প্রাথমিক কী)।
  • আপনি কোনও ডিবি অপ্টিমাইজারের কাছ থেকে সম্পূর্ণরূপে উপকৃত হবেন না যিনি একটি জটিল প্রশ্নের জন্য অনুকূল অ্যাক্সেস কৌশলগুলি সনাক্ত করতে পারেন, সাধারণ আকারের টেবিলগুলির আকার এবং বেশ কয়েকটি সূচকের পরিসংখ্যানের সুবিধা গ্রহণ করে। এটি দ্রুত যোগদান এড়ানোর সীমিত সুবিধাটি অফসেট করে।

সাধারণ টেবিল

উপরের অসুবিধাগুলি হ'ল সাধারণীকরণের স্কিমার সুবিধাগুলি। অবশ্যই, প্রশ্নগুলি লেখার ক্ষেত্রে আরও জটিল হতে পারে।

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


5

আমি মনে করি আপনার প্রশ্নের কমপক্ষে দুটি অংশ রয়েছে:

১. কেন বিভিন্ন ধরণের সত্তা একই টেবিলে সংরক্ষণ করা উচিত নয়?

এখানে সর্বাধিক গুরুত্বপূর্ণ উত্তরগুলি হল কোড পাঠযোগ্যতা এবং গতি। এ এর SELECT name FROM companies WHERE id = ?চেয়ে অনেক বেশি বেশি পঠনযোগ্য SELECT companyName FROM masterTable WHERE companyId = ?এবং আপনি অজ্ঞাতসারে বাজে বাজে জিজ্ঞাসা করার সম্ভাবনা কম (উদাহরণস্বরূপ SELECT companyName FROM masterTable WHERE employeeId = ?যখন সংস্থাগুলি এবং কর্মচারীরা বিভিন্ন টেবিলে সঞ্চয় করা থাকে তখন সম্ভব হবে না)। গতি হিসাবে, একটি ডাটাবেস টেবিল থেকে ডেটা হয় পুরো টেবিলটি ধারাবাহিকভাবে পড়ার মাধ্যমে, বা একটি সূচী থেকে পড়ে ret টেবিল / সূচীতে কম ডেটা থাকলে উভয়ই দ্রুত হয় এবং যদি তথ্যটি বিভিন্ন টেবিলগুলিতে সঞ্চিত থাকে (এবং আপনার কেবলমাত্র সারণী / সূচকগুলির একটি পড়তে হবে)।

২. কেন একক প্রকারের সত্তাকে বিভিন্ন সারণীতে সংরক্ষিত উপ-সত্তায় বিভক্ত করা উচিত?

এখানে, কারণটি হ'ল ডেটাতে অসঙ্গতি রোধ করা। একক সারণী পদ্ধতির সাথে, একটি অর্ডার ম্যানেজমেন্ট সিস্টেমের জন্য আপনি গ্রাহকের নাম, গ্রাহকের ঠিকানা এবং পণ্যটির আইডি সংরক্ষণ করতে পারেন গ্রাহক একটি একক সত্তা হিসাবে অর্ডার করেছিলেন। যদি কোনও গ্রাহক একাধিক পণ্য অর্ডার করে থাকেন তবে আপনার ডাটাবেসে আপনার গ্রাহকের নাম এবং ঠিকানার একাধিক উদাহরণ থাকতে হবে। সর্বোত্তম ক্ষেত্রে, আপনি কেবল আপনার ডাটাবেসে সদৃশ ডেটা পেয়েছেন যা এটি কিছুটা কমিয়ে দিতে পারে। তবে আরও খারাপ বিষয় হ'ল ডেটা প্রবেশের সময় কেউ (বা কোনও কোড) ভুল করেছে যাতে কোনও সংস্থাগুলি আপনার ডাটাবেসে বিভিন্ন ঠিকানা দিয়ে শেষ করে। এটি একা যথেষ্ট খারাপ। তবে আপনি যদি কোনও কোম্পানির নামের উপর ভিত্তি করে ঠিকানা জিজ্ঞাসা করে থাকেন (উদাঃ)SELECT companyAddress FROM orders WHERE companyName = ? LIMIT 1) আপনি যথেচ্ছভাবে দুটি ঠিকানার মধ্যে একটি ফেরত পেতে চাইবেন এবং বুঝতে পারবেন না যে এখানে কোনও অসঙ্গতি রয়েছে। কিন্তু প্রতিবার আপনি যখন ক্যোয়ারীটি চালাবেন আপনি আসলে ডিবিএমএস দ্বারা আপনার ক্যোয়ারীটি কীভাবে অভ্যন্তরীণভাবে সমাধান করা হয়েছে তার উপর নির্ভর করে একটি আলাদা ঠিকানা পেতে পারেন। এটি সম্ভবত আপনার অ্যাপ্লিকেশনটি অন্য কোথাও ভঙ্গ করবে এবং সেই ভাঙ্গার মূল কারণটি খুঁজে পাওয়া খুব কঠিন।

মাল্টি-টেবিল পদ্ধতির সাহায্যে আপনি বুঝতে পারবেন যে সংস্থার নাম থেকে কোম্পানির ঠিকানায় কার্যকরী নির্ভরতা রয়েছে (যদি কোনও সংস্থার কেবল একটি ঠিকানা থাকতে পারে), আপনি একটি টেবিলের মধ্যে (CompanyName, CompanyAdress) টিপল সংরক্ষণ করবেন (উদাঃ company), এবং (productId, CompanyName) অন্য একটি সারণীতে টিপল (উদাঃ order)। টেবিলে একটি UNIQUEপ্রতিবন্ধকতা companyতখন কার্যকর করতে পারে যে প্রতিটি সংস্থার কেবল আপনার ডাটাবেসে একটি ঠিকানা থাকে যাতে সংস্থার ঠিকানাগুলির জন্য কোনও অসঙ্গতি দেখা দিতে পারে না।

দ্রষ্টব্য: বাস্তবে, কার্য সম্পাদনের কারণে আপনি সম্ভবত প্রতিটি কোম্পানির জন্য একটি অনন্য সংস্থা তৈরি করতে চান এবং সরাসরি CompanyName সরাসরি ব্যবহার না করে বিদেশী কী হিসাবে ব্যবহার করবেন। তবে সাধারণ পন্থা একই থাকে।


3

টিএল; ডিআর - তারা স্কুলে পড়ার সময় কীভাবে শেখানো হয়েছিল তার উপর ভিত্তি করে তারা ডেটাবেস ডিজাইন করছে ।

আমি এই প্রশ্নটি 10 ​​বছর আগে লিখতে পারতাম। আমার পূর্বসূরীরা কেন তাদের ডাটাবেসগুলি ডিজাইন করেছিল তা বুঝতে আমার কিছুটা সময় লেগেছে। আপনি কারও সাথে কাজ করছেন যে হয়:

  1. এক্সেলকে ডেটাবেস বা হিসাবে ব্যবহার করে তাদের বেশিরভাগ ডাটাবেস ডিজাইনের দক্ষতা অর্জন করেছেন
  2. তারা স্কুল ছাড়ার সময় থেকেই সেরা অনুশীলনগুলি ব্যবহার করছে।

আপনার টেবিলে আসলে আইডি নম্বর রয়েছে বলে আমি এটি # 1 সন্দেহ করি না, তাই আমি # 2 ধরে নেব।

আমি স্কুল ছাড়ার পরে, আমি এমন একটি দোকানে কাজ করছিলাম যেটিতে একটি এএস / 400 ব্যবহার করা হত (ওরফে আইবিএম আমি)। তারা যেভাবে তাদের ডাটাবেসগুলি ডিজাইন করেছিল তাতে আমি কিছু অদ্ভুত জিনিস পেয়েছি এবং কীভাবে আমাকে কীভাবে ডেটাবেসগুলি ডিজাইন করতে শেখানো হয়েছিল তা অনুসরণ করার জন্য আমরা পরিবর্তনগুলি করা শুরু করেছিলাম। (আমি তখন বোবা ছিলাম)

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

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


আমি যে সমস্যার মুখোমুখি হয়েছিল তার কয়েকটি উদাহরণ যা সম্পর্কিত মডেলটির সাথে খাপ খায় না:

  • তারিখগুলি জুলিয়ান দিনের সংখ্যা হিসাবে সংরক্ষণ করা হয়েছিল যার আসল তারিখ পাওয়ার জন্য একটি তারিখের টেবিলে যোগদানের প্রয়োজন।
  • একই ধরণের অনুক্রমিক কলামগুলির সাথে ডেনরমালাইজড টেবিলগুলি (যেমন code1,code2, ..., code20)
  • NxM দৈর্ঘ্যের CHAR কলামগুলি দৈর্ঘ্যের M এর স্ট্রিংগুলির একটি অ্যারে উপস্থাপন করে

এই ডিজাইনের সিদ্ধান্তগুলির জন্য আমাকে যে কারণগুলি দেওয়া হয়েছিল সেগুলি সমস্ত ডাটাবেস যখন ডিজাইন করা হয়েছিল তখন সিস্টেমের সীমাবদ্ধতার উপর নির্ভর করে।

তারিখ - আমাকে জানানো হয়েছিল যে সমস্ত তথ্য সহ প্রতিটি সম্ভাব্য তারিখের একটি টেবিল তৈরি করার চেয়ে তারিখের কার্যকারিতা (যা মাস বা দিন বা সপ্তাহের দিন) ব্যবহারের ক্ষেত্রে প্রসেসিং সময় বেশি লেগেছিল।

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

NxM দৈর্ঘ্য CHAR কলাম - ফাইল রিড অপারেশন হ্রাস করার জন্য একটি কলামে কনফিগারেশন মানগুলি সরানো সহজ ছিল।

সি প্রোগ্রামিংয়ের পরিবেশের প্রতিফলন ঘটানোর জন্য সি এর সমমানের একটি দুর্বল ধারণা example

#define COURSE_LENGTH 4
#define NUM_COURSES 4
#define PERIOD_LENGTH 2

struct mytable {
    int id;
    char periodNames[NUM_COURSES * PERIOD_LENGTH];  // NxM CHAR Column
    char course1[COURSE_LENGTH];
    char course2[COURSE_LENGTH];
    char course3[COURSE_LENGTH];
    char course4[COURSE_LENGTH];
};

...

// Example row
struct mytable row = {.id= 1, .periodNames="HRP1P2P8", .course1="MATH", .course2="ENGL", .course3 = "SCI ", .course4 = "READ"};

char *courses; // Pointer used to access the sequential columns
courses = (char *)&row.course1;


for(int i = 0; i < NUM_COURSES; i++) {

    printf("%d: %.*s -> %.*s\n",i+1, PERIOD_LENGTH, &row.periodNames[PERIOD_LENGTH * i], COURSE_LENGTH,&courses[COURSE_LENGTH*i]);
}

আউটপুট

1: এইচআর -> ম্যাথ
2: পি 1 -> ENGL
3: পি 2 -> এসসিআই
4: পি 8 -> পড়ুন

আমাকে যা বলা হয়েছিল সে অনুসারে এর কিছুটিকে সেই সময়ের সেরা অনুশীলন হিসাবে বিবেচনা করা হত।

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