সংক্ষিপ্ত উত্তর
তৃতীয় বিকল্প: Query all identifiers for all permissions (5), then query the Form model using the identifiers in an IN() statement
$teamMorphType = Relation::getMorphedModel('team');
$groupMorphType = Relation::getMorphedModel('group');
$formMorphType = Relation::getMorphedModel('form');
$permissible = [
$teamMorphType => [$user->team_id],
$groupMorphType => [],
$formMorphType => [],
];
foreach ($user->permissible as $permissible) {
switch ($permissible->permissible_type) {
case $teamMorphType:
case $groupMorphType:
case $formMorphType:
$permissible[$permissible->permissible_type][] = $permissible->permissible_id;
break;
}
}
$forms = Form::query()
->where('user_id', '=', $user->id)
->orWhereIn('id', $permissible[$fromMorphType])
->orWhereIn('team_id', $permissible[$teamMorphType])
->orWhereIn('group_id', $permissible[$groupMorphType])
->get();
দীর্ঘ উত্তর
একদিকে, (কোড) আপনি কোডগুলিতে যা করতে পারেন তার সবকিছুই ক্যোয়ারিতে না করাই ভাল পারফরম্যান্স-ভিত্তিক।
অন্যদিকে, প্রয়োজনের তুলনায় ডাটাবেস থেকে আরও বেশি ডেটা প্রাপ্ত করা ইতিমধ্যে অনেক বেশি ডেটা (র্যামের ব্যবহার এবং এই জাতীয়)।
আমার দৃষ্টিকোণ থেকে, আপনার মধ্যে কিছু দরকার এবং কেবলমাত্র আপনি জানবেন যে সংখ্যাটির উপর নির্ভর করে ভারসাম্যটি কোথায় থাকবে।
আমি বেশ কয়েকটি ক্যোয়ারী চালানোর পরামর্শ দেব, আপনি প্রস্তাবিত শেষ বিকল্প ( Query all identifiers for all permissions (5), then query the Form model using the identifiers in an IN() statement
):
- সমস্ত অনুমতিগুলির জন্য সমস্ত সনাক্তকারীকে জিজ্ঞাসা করুন (5 টি কোয়েরি)
- সমস্ত ফর্মের ফলাফলগুলিকে স্মৃতিতে মার্জ করুন এবং অনন্য মান পাবেন
array_unique($ids)
- আইএন () বিবৃতিতে শনাক্তকারীদের ব্যবহার করে ফর্ম মডেলটি অনুসন্ধান করুন।
আপনি প্রস্তাবিত তিনটি বিকল্প চেষ্টা করতে পারেন এবং একাধিকবার ক্যোরি চালানোর জন্য কোনও সরঞ্জাম ব্যবহার করে পারফরম্যান্স পর্যবেক্ষণ করতে পারেন তবে আমি 99% নিশ্চিত যে শেষটি আপনাকে সেরা পারফরম্যান্স দেবে।
আপনি কোন ডাটাবেসটি ব্যবহার করছেন তার উপর নির্ভর করে এটিও অনেক পরিবর্তন করতে পারে তবে উদাহরণস্বরূপ যদি আমরা মাইএসকিউএল সম্পর্কে কথা বলি; খুব বড় ক্যোয়ারিতে আরও বেশি ডাটাবেস সংস্থান ব্যবহার করা হবে, যা কেবলমাত্র সহজ অনুসন্ধানগুলির চেয়ে বেশি সময় ব্যয় করবে না, তবে লেখাগুলি থেকে টেবিলটি লক করে দেবে এবং এটি ডেডলক ত্রুটি তৈরি করতে পারে (যদি আপনি কোন গোলাম সার্ভার ব্যবহার না করেন)।
অন্যদিকে, ফর্ম আইডির সংখ্যা যদি খুব বড় হয় তবে আপনার অনেকগুলি স্থানধারীর জন্য ত্রুটি থাকতে পারে, সুতরাং আপনি 500 টি আইডির গ্রুপগুলিতে প্রশ্নগুলি কাটাতে চাইতে পারেন, এটি সীমা হিসাবে অনেকটা নির্ভর করে আকারে, বাইন্ডিংয়ের সংখ্যায় নয়), এবং ফলাফলগুলিকে মেমরিতে মিশ্রিত করে। এমনকি যদি আপনি একটি ডাটাবেস ত্রুটি না পান তবে আপনি পারফরম্যান্সেও একটি বড় পার্থক্য দেখতে পাবেন (আমি এখনও মাইএসকিউএল সম্পর্কে কথা বলছি)।
বাস্তবায়ন
আমি ধরে নেব যে এটি ডাটাবেস স্কিম:
users
- id
- team_id
forms
- id
- user_id
- team_id
- group_id
permissible
- user_id
- permissible_id
- permissible_type
সুতরাং জায়েজযোগ্য এটি ইতিমধ্যে একটি কনফিগার করা পলিমারফিক সম্পর্ক ।
সুতরাং, সম্পর্কগুলি হবে:
- নিজস্ব ফর্ম:
users.id <-> form.user_id
- দলটির ফর্মের মালিকানা:
users.team_id <-> form.team_id
- একটি ফর্মের মালিক এমন একটি গোষ্ঠীর অনুমতি রয়েছে:
permissible.user_id <-> users.id && permissible.permissible_type = 'App\Team'
- একটি ফর্মের মালিকানাধীন একটি দলে অনুমতি রয়েছে:
permissible.user_id <-> users.id && permissible.permissible_type = 'App\Group'
- একটি ফর্ম অনুমোদিত:
permissible.user_id <-> users.id && permissible.permissible_type = 'App\From'
সরলকরণ সংস্করণ:
$teamMorphType = Relation::getMorphedModel('team');
$groupMorphType = Relation::getMorphedModel('group');
$formMorphType = Relation::getMorphedModel('form');
$permissible = [
$teamMorphType => [$user->team_id],
$groupMorphType => [],
$formMorphType => [],
];
foreach ($user->permissible as $permissible) {
switch ($permissible->permissible_type) {
case $teamMorphType:
case $groupMorphType:
case $formMorphType:
$permissible[$permissible->permissible_type][] = $permissible->permissible_id;
break;
}
}
$forms = Form::query()
->where('user_id', '=', $user->id)
->orWhereIn('id', $permissible[$fromMorphType])
->orWhereIn('team_id', $permissible[$teamMorphType])
->orWhereIn('group_id', $permissible[$groupMorphType])
->get();
বিস্তারিত সংস্করণ:
// Owns Form
// users.id <-> forms.user_id
$userId = $user->id;
// Team owns Form
// users.team_id <-> forms.team_id
// Initialise the array with a first value.
// The permissions polymorphic relationship will have other teams ids to look at
$teamIds = [$user->team_id];
// Groups owns Form was not mention, so I assume there is not such a relation in user.
// Just initialise the array without a first value.
$groupIds = [];
// Also initialise forms for permissions:
$formIds = [];
// Has permissions to a group that owns a Form
// permissible.user_id <-> users.id && permissible.permissible_type = 'App\Team'
$teamMorphType = Relation::getMorphedModel('team');
// Has permissions to a team that owns a Form
// permissible.user_id <-> users.id && permissible.permissible_type = 'App\Group'
$groupMorphType = Relation::getMorphedModel('group');
// Has permission to a Form
// permissible.user_id <-> users.id && permissible.permissible_type = 'App\Form'
$formMorphType = Relation::getMorphedModel('form');
// Get permissions
$permissibles = $user->permissible()->whereIn(
'permissible_type',
[$teamMorphType, $groupMorphType, $formMorphType]
)->get();
// If you don't have more permissible types other than those, then you can just:
// $permissibles = $user->permissible;
// Group the ids per type
foreach ($permissibles as $permissible) {
switch ($permissible->permissible_type) {
case $teamMorphType:
$teamIds[] = $permissible->permissible_id;
break;
case $groupMorphType:
$groupIds[] = $permissible->permissible_id;
break;
case $formMorphType:
$formIds[] = $permissible->permissible_id;
break;
}
}
// In case the user and the team ids are repeated:
$teamIds = array_values(array_unique($teamIds));
// We assume that the rest of the values will not be repeated.
$forms = Form::query()
->where('user_id', '=', $userId)
->orWhereIn('id', $formIds)
->orWhereIn('team_id', $teamIds)
->orWhereIn('group_id', $groupIds)
->get();
সংস্থানসমূহ ব্যবহৃত:
ডাটাবেস কর্মক্ষমতা:
- ডাটাবেসের প্রশ্ন (ব্যবহারকারী বাদে): 2 ; একটি অনুমোদিত হতে এবং অন্য একটি ফর্ম পেতে।
- যোগ দেয় না !!
- সর্বনিম্ন ওআরএস সম্ভব ()
user_id = ? OR id IN (?..) OR team_id IN (?...) OR group_id IN (?...)
।
পিএইচপি, স্মৃতিতে, কর্মক্ষমতা:
- foreach ভিতরে একটি স্যুইচ সঙ্গে জায়েজ লুপিং ।
array_values(array_unique())
আইডি পুনরাবৃত্তি এড়ানোর জন্য।
- মেমরি, আইডি 3 অ্যারে (
$teamIds
, $groupIds
, $formIds
)
- স্মৃতিতে, প্রাসঙ্গিক অনুমতিগুলি সুস্পষ্ট সংগ্রহ (এটি যদি প্রয়োজন হয় তবে অনুকূলিত করা যেতে পারে)।
সুবিধা - অসুবিধা
পেশাদাররা:
- সময় : একক ক্যোয়ারির বারের যোগফল এবং ওআর-এর সাথে একটি বড় ক্যোয়ারির সময়ের চেয়ে কম হয়।
- ডিবি রিসোর্সস: মাইএসকিউএল রিসোর্সগুলি যোগ বা বিবৃতি সহ একটি কোয়েরি দ্বারা ব্যবহৃত হয়, এটির পৃথক ক্যোয়ারীর যোগফলের চেয়ে বড়।
- টাকা : পিএইচপি সংস্থানগুলির চেয়ে বেশি ব্যয়বহুল, খুব কম ডাটাবেস সংস্থান (প্রসেসর, র্যাম, ডিস্ক রিড ইত্যাদি)।
- লক্স : আপনি যদি কেবল পঠনযোগ্য স্লেভ সার্ভারকে জিজ্ঞাসা করছেন না, আপনার প্রশ্নগুলি কম সারিগুলি পড়ার লকগুলিকে তৈরি করবে (পঠিত লকটি মাইএসকিউএলে ভাগ করা আছে, সুতরাং এটি অন্য পড়াটি লক করবে না, তবে এটি কোনও লিখনকে ব্লক করবে)।
- স্কেলেবল : এই পদ্ধতির সাহায্যে ক্যোয়ারিকে খণ্ডিত করার মতো আরও পারফরম্যান্স অনুকূলকরণ করতে পারবেন ations
কনস:
- কোড সংস্থানসমূহ : ডাটাবেসের পরিবর্তে কোডে গণনা করা কোডের উদাহরণে স্পষ্টতই বেশি সংস্থান গ্রহণ করবে তবে বিশেষত র্যামের মধ্যে মাঝারি তথ্য সংরক্ষণ করবে। আমাদের ক্ষেত্রে এটি কেবল আইডির একটি অ্যারে হবে, যা সত্যিই কোনও সমস্যা হওয়া উচিত নয়।
- রক্ষণাবেক্ষণ : আপনি যদি লারাভেলের সম্পত্তি এবং পদ্ধতিগুলি ব্যবহার করেন এবং আপনি ডাটাবেসে কোনও পরিবর্তন করেন তবে আপনি আরও স্পষ্ট প্রশ্ন এবং প্রক্রিয়াজাতকরণের চেয়ে কোডে আপডেট করা সহজ হবে।
- Overkilling? : কিছু ক্ষেত্রে, যদি ডেটাটি এত বড় না হয় তবে পারফরম্যান্সের অনুকূলকরণের জন্য অতিরিক্ত খরচ করা যেতে পারে।
কর্মক্ষমতা পরিমাপ কিভাবে
পারফরম্যান্সটি কীভাবে পরিমাপ করবেন সে সম্পর্কে কিছু সূত্র?
- স্লো ক্যোয়ারী লগগুলি
- বিশ্লেষণ সারণী
- টেবিল স্থিতির মতো দেখান
- ব্যাখ্যা ; এক্সটেন্ডেড এক্সপ্লেইন আউটপুট ফর্ম্যাট ; ব্যাখ্যার ব্যবহার ; আউটপুট ব্যাখ্যা
- সতর্কতাগুলি দেখান
কিছু আকর্ষণীয় প্রোফাইলিংয়ের সরঞ্জাম: