تعيين البيانات من قاعدة بيانات علائقية

في بعض الأحيان تنشأ المواقف عندما لا يتناسب حل مشكلة استرداد البيانات من قاعدة بيانات علائقية مع إمكانات ORM المستخدمة في المشروع ، على سبيل المثال ، إما بسبب السرعة غير الكافية لـ ORM نفسه ، أو ليس استعلامات SQL المثالية تمامًا الناتجة عن ذلك. في هذه الحالة ، عليك عادةً كتابة الاستعلامات يدويًا.

المشكلة هي أن البيانات من قاعدة البيانات (بما في ذلك استجابة لطلب JOIN) يتم إرجاعها على هيئة صفيف ثنائي الأبعاد "مسطح" لا يعكس هيكل "الشجرة" المعقد لبيانات التطبيق. من غير الملائم للغاية العمل مع مثل هذا المصفوفة بشكل أكبر ، لذلك ، يلزم حل عالمي أكثر أو أقل لإحضار هذا المصفوفة إلى شكل أكثر ملاءمة وفقًا للنمط المحدد.

تم العثور على الحل ، مريح وسريع بما فيه الكفاية.

مدى السرعة


لتقييم سرعة المكتبة ، قمت بتجميع منصة اختبار صغيرة يتم فيها مقارنة سرعة مكتبتي مع سرعة Eloquent. للقياسات ، تم استخدام حزمة phpbench.

من أجل نشر حامل في المنزل:

git clone https://github.com/hrustbb2/env-arrayproc-bench.git
cd env-arrayproc-bench
./env

هنا استخدمت الأداة الموضحة في مقالتي السابقة .

ثم في القائمة ، نختار: 1 تطوير ، ثم: 1 بناء ، ثم 2 نشر وأعلى ؛
ثم شغّل الاختبارات 5. شغّل الاختبارات

هناك 3000 كتاب في قاعدة البيانات. النتائج كما يلي:

+-----------------+-----+------+------+-------------+--------------+
| subject         | set | revs | iter | mem_peak    | time_rev     |
+-----------------+-----+------+------+-------------+--------------+
| benchEloquent   | 0   | 1    | 0    | 76,442,912b | 12,781.612ms |
| benchEloquentId | 0   | 10   | 0    | 5,123,224b  | 16.432ms     |
| benchProc       | 0   | 1    | 0    | 36,364,176b | 1,053.937ms  |
| benchProcId     | 0   | 10   | 0    | 4,462,696b  | 7.684ms      |
+-----------------+-----+------+------+-------------+--------------+

benchEloquent - تسحب جميع الكتب مع المؤلفين باستخدام
Eloquent benchEloquentId - تسحب كتابًا معينًا مع المؤلفين باستخدام

Eloquent (10 مرات) benchProc - تسحب جميع الكتب مع المؤلفين باستخدام مكتبة
benchProcId - تسحب كتابًا معينًا مع المؤلفين باستخدام المكتبة (10)

للتفعيل الاختبارات ليست ممثلة بما فيه الكفاية ، ولكن الفرق ملحوظ ، سواء في وقت التشغيل أو في استهلاك الذاكرة.

كيف تعمل


تثبيت:

composer require hrustbb2/arrayproc:v1.0.0

علاوة على ذلك ، على سبيل المثال (بسيط للغاية) ، تخيل أن لدينا قاعدة بيانات من الكتب والمؤلفين بالهيكل التالي.

صورة

المهمة هي سحب كل الكتب مع مؤلفيها.

سيبدو الطلب على النحو التالي:

SELECT
    books.id,
    books.name,
    authors.id,
    authors.name
FROM
    books
LEFT JOIN relations ON relations.books_id = books.id
LEFT JOIN authors ON authors.id = relations.authors_id

واستجابة لذلك ، نحصل على مثل هذه المجموعة من البيانات.

معرف الكتاباسم الكتابالمؤلفاسم المؤلف
1كتاب 12المؤلف 2
1كتاب 14المؤلف 4
1كتاب 16المؤلف 6
2الكتاب 22المؤلف 2
2الكتاب 23المؤلف 3
2الكتاب 26المؤلف 6
2الكتاب 27المؤلف 7


الصفيف ثنائي الأبعاد ، بعض الحقول مكررة ، للراحة تحتاج إلى تحويله
[
	1 => [
		'id' => 1,
		'name' => 'book1',
		'authors' => [
			2 => [
				'id' => 2,
				'name' => 'author2'
			],
			4 => [
				'id' => 4,
				'name' => 'author4'
			],
			6 => [
				'id' => 6,
				'name' => 'author6'
			],
		]
	],
	2 => [
		'id' => 2,
		'name' => 'book2',
		'authors' => [
			2 => [
				'id' => 2,
				'name' => 'author2'
			],
			3 => [
				'id' => 3,
				'name' => 'author3'
			],
			6 => [
				'id' => 6,
				'name' => 'author6'
			],
			7 => [
				'id' => 7,
				'name' => 'author7'
			],
		]
	],
]


للقيام بذلك ، قم بتعديل طلبنا قليلاً:


SELECT
    books.id AS book_id,
    books.name AS book_name,
    authors.id AS author_id,
    authors.name AS author_name
FROM
    books
LEFT JOIN relations ON relations.books_id = books.id
LEFT JOIN authors ON authors.id = relations.authors_id

نقوم هنا بتعيين الأسماء المستعارة في قسم SELECT: للحقول التي تحتوي على بيانات حول الكتب ، والأسماء المستعارة بالبادئة "book_" ، والحقول التي تحتوي على معلومات حول المؤلفين بالبادئة "المؤلف".

بعد ذلك ، نقوم بتحويل استجابة قاعدة البيانات

use hrustbb2\arrayproc\ArrayProcessor;

$arrayProcessor = new ArrayProcessor();
$config = [
	'prefix' => 'book_',
	'authors' => [
		'prefix' => 'author_',
	]
]
$booksData = $arrayProcessor->process($conf, $rows)->resultArray();

حيث:

$ rows هو استجابة قاعدة البيانات في شكل مصفوفة من الكائنات / stdClass ()
$ config هو مصفوفة ترابطية تعكس بنية بيانات المصفوفة الناتجة

ونتيجة لذلك ، في $ booksData لدينا مصفوفة تشبه الشجرة لها البنية الموضحة في $ config ، مليئة بالبيانات المقابلة.

شيء من هذا القبيل.

All Articles