ខ្ញុំត្រូវបង្ហាញអ្វីមួយហើយវាមានពេលវេលាណាស់ដើម្បីនិយាយ។ ក្នុងអំឡុងពេលនៃការធ្វើការរបស់ខ្ញុំខ្ញុំខ្ញុំបានគិតថាការសរសេរ SQL ដែលជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើជាប្រសិនបើ។ ខ្ញុំមិនត្រឹមត្រូវទេ។ មិនត្រឹមត្រូវតែទេ។ ការអនុម័តនេះជាការជោគជ័យ។ វាត្រូវបានធ្វើឱ្យខ្ញុំបានសរសេរកូដដែលមើលទៅស្អាតនិងមានប្រសិទ្ធិភាពទេប៉ុន្តែពិតជាការជោគជ័យ។ តើអ្នកអាចជឿថានៅពេលវេលាជាច្រើននៃសំណួរ SQL ដែលត្រូវការដើម្បីធ្វើឱ្យទំព័រតែមួយនៅក្នុងកម្មវិធីរបស់យើង? សៀវភៅសៀវភៅសៀវភៅដែលមានសៀវភៅសៀវភៅសៀវភៅសៀវភៅសៀវភៅសៀវភៅសៀវភៅសៀវភៅសៀវភៅសៀវភៅសៀវភៅ និងចំនួននេះគឺ 47, 47 ការធ្វើដំណើររដូវរដូវរដូវរដូវរដូវរដូវរដូវរដូវរដូវរដូវរដូវរដូវរដូវរដូវរដូវរដូវរដូវរដូវរដូវរដូវរដូវរដូវរដូវរដូវរដូវ។ កូដដែលបានផលិតនេះគឺដោយគ្មានសុវត្ថិភាព។ ប្រភេទសុវត្ថិភាព។ ការធ្វើតេស្តពេញលេញ។ ជាមួយនឹងការបង្វិលដ៏ស្រស់ស្អាត។ និងកូដនេះបានកាត់បន្ថយពេលដំណោះស្រាយរបស់យើង។ ហើយគ្មាននរណាម្នាក់បានចាប់អារម្មណ៍ថាវាដោយសារតែការបាត់បន្ថយនេះបានបាត់បន្ថយការសន្សំពីយើង។ អ្វីមួយដែលអ្នកមិនបានបង្ហាញនៅក្នុងសម្ភារៈទីផ្សាររបស់ ORM គឺថាវាជាការល្អបំផុតក្នុងការចែកចាយអ្វីដែលវាពិតជាធ្វើជាមួយទិន្នន័យ។ សូមអរគុណអំពីអ្វីដែលអ្នកពិតជាមាន ORM អនុញ្ញាតឱ្យអ្នកទទួលបានច្រើន។ ហើយវាជាផ្នែកមួយនៃបញ្ហានេះ។ មួយចំនួននៃបញ្ហានេះគឺជាការល្អណាស់ណាស់ដែលវាអាចជំងឺអ្នកដោយគ្មានអ្នករកឃើញវា។ ORM ផ្តល់នូវការគ្រប់គ្រងប្រព័ន្ធប្រតិបត្តិការ - ការផ្លាស់ប្តូរប្រព័ន្ធប្រតិបត្តិការ, ការផ្លាស់ប្តូរប្រព័ន្ធប្រតិបត្តិការ, និងការផ្លាស់ប្តូរប្រព័ន្ធប្រតិបត្តិការ។ និងផ្នែកនេះគឺល្អឥតខ្ចោះ។ ហើយអ្នកគួរតែបន្តប្រើវា។ លើសពីនេះទៀតវាបានផ្តល់នូវ API ល្អសម្រាប់ប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រព័ន្ធប្រតិបត្តិការប្រ នេះគឺជាផ្នែកសំខាន់នៃ ORM ។ ហើយនេះគឺជាកន្លែងដែលបញ្ហានេះចាប់ផ្តើម។ ការបញ្ហានេះគឺល្អឥតខ្ចោះនៅពេលដែលវាធ្វើការនិងបង្កើតបញ្ហានេះជាបញ្ហានៅពេលដែលវាមិនធ្វើ។ ORM ផ្តល់នូវគំនិតនៃការផ្លាស់ប្តូរទិន្នន័យទិន្នន័យ។ ហើយប្រសិនបើនៅក្នុងពិភពលោកដ៏អស្ចារ្យមួយអ្នកអាចផ្លាស់ប្តូរពី MySQL ទៅ PostgreSQL ដោយគ្មានការផ្លាស់ប្តូរកូដ។ ប៉ុន្តែនៅក្នុងពិភពលោកពិតប្រាកដអ្នកមិនចង់ធ្វើ។ អ្នកជ្រើសទិន្នន័យទិន្នន័យនិងអ្នកបណ្តុះបណ្តាលជាមួយនឹងវា។ និងការបណ្តុះបណ្តាលគំនិតនេះធ្វើឱ្យអ្នកឆ្លើយតបពីលក្ខណៈពិសេសទិន្នន័យទិន្នន័យដែលនឹងធ្វើឱ្យកម្មវិធីរបស់អ្នកឆាប់រហ័ស។ ប្រសិនបើអ្នកជឿទុកចិត្តអ្នកនឹងជឿទុកចិត្តអ្នក។ ប្រសិនបើអ្នកមិនជឿទុកចិត្តអ្នកនឹងជឿទុកចិត្តអ្នកនឹងជឿទុកចិត្តអ្នក។ ប្រសិនបើអ្នកមិនជឿទុកចិត្តអ្នកនឹងជឿទុកចិត្តអ្នកនឹងជឿទុកចិត្តអ្នក។ ប្រសិនបើអ្នកជឿទុកចិត្តអ្នកនឹងជឿទុកចិត្តអ្នកនឹងជឿទុកចិត្តអ្នកនឹងជឿទុកចិត្តអ្នក។ ប្រសិនបើអ្នកមិនជឿទុកចិត្តអ្នកអ្នកនឹងជឿទុកចិត្តអ្នកនឹងជឿទុកចិត្តអ្នក។ N+1 គឺជាប្រសិនបើវាជាប្រសិនបើវាជាប្រសិនបើវាជាប្រសិនបើវាជាប្រសិនបើវាជាប្រសិនបើវាជាប្រសិនបើវាជាប្រសិនបើវាជាប្រសិនបើវាជាប្រសិនបើវាជាប្រសិនបើវាជាប្រសិនបើវាជាប្រសិនបើ ការអភិវឌ្ឍន៍ទាំងអស់ដែលបានធ្វើការជាមួយ ORM បានដឹងអំពីបញ្ហាសម្រាប់បញ្ហាសម្រាប់ N + 1 ។ ការអភិវឌ្ឍន៍ទាំងអស់ដែលបានធ្វើការជាមួយ ORM បានដឹងអំពីបញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់បញ្ហាសម្រាប់ ប៉ុន្តែខ្ញុំគិតថាការផ្លាស់ប្តូរតម្រូវការ N+1 គឺគ្រាន់តែជាផ្នែកមួយដែលអាចមើលឃើញនៅក្នុងភីកែវនៃបញ្ហា ORM - ពួកគេធ្វើឱ្យវាជាការងាយស្រួលណាស់ដើម្បីសរសេរកូដដែលមើលទៅមានប្រសិទ្ធិភាពប៉ុន្តែគឺជាការជោគជ័យនៅក្រោមកញ្ចក់។ មតិ 47 របស់ខ្ញុំមិនគឺជាគំរូ N + 1 ទាំងអស់។ មួយចំនួនគឺជាការស្វែងរកធ្លាក់ចុះ។ នៅក្នុងមួយចំនួនរបស់ពួកគេ, ORM បានទាញយកសកម្មភាពពេញលេញនៅពេលដែលគ្រាន់តែមានតំបន់ពីរដែលត្រូវការ។ មួយចំនួននៃពួកគេគឺជាការស្វែងរក COUNT ដោយស្វ័យប្រវត្តិដែលត្រូវបានផ្ញើដោយសៀវភៅ pagination ។ ហើយអ្វីទាំងអស់នេះមិនមែនជាពិសេសពីការអានកូដកម្មវិធី! អ្នកអាចមើលឃើញវាដោយគ្រាន់តែមើលដំណោះស្រាយការស្វែងរក។ និង SQL ដំបូងផ្តល់ឱ្យអ្នកនូវបទពិសោធផ្សេងទៀត។ អ្នកអាចដឹងថាតើគម្រោងដែលត្រូវបានផ្ញើទៅជាទិន្នន័យបានទេ។ សូមពិនិត្យមើលប្រព័ន្ធ SQL នេះ។ SELECT id, name, email FROM users WHERE account_id = ? AND is_active = 1 ORDER BY created_at DESC LIMIT 20 OFFSET 0; អ្នកដឹងអំពីសំណួរនេះ ហើយអ្នកដឹងអំពីកញ្ចក់ត្រឹមត្រូវដែលត្រូវបានទាញយក។ អ្នកអាចគិតអំពីអេក្រង់ដែលអ្នកត្រូវការសម្រាប់សំណួរនេះ។ ហើយអ្នកអាចប្លុកវាដោយផ្ទាល់ទៅក្នុងកញ្ចក់ទិន្នន័យរបស់អ្នកហើយដំណើរការបញ្ជា EXPLAIN នៅលើវា។ ជាមួយនឹង ORM ទាំងអស់ដែលអ្នកដឹងគឺជាគោលបំណង។ ការអនុវត្តពិតប្រាកដនឹងមានបន្ទាប់ពីពេលដំណើរការ។ និងសំណួរពិតប្រាកដអាចផ្លាស់ប្តូរតាមរយៈពេលដែលគំរូរបស់អ្នកបានផ្លាស់ប្តូរហើយអ្នកមិនអាចគ្រប់គ្រងពួកគេ។ នៅពេលដែល ORMs មិនអាចបន្ទាប់មកអ្នក មានប្រភេទនៃបញ្ហានេះដែល ORM មិនមែនគ្រាន់តែមានរយៈពេលវែង។ វាមិនអាចដោះស្រាយពួកគេ។ និងការកំណត់មិនអាចដោះស្រាយវា។ រូបភាព Window សកម្មភាព Windows - 'RANK()' , 'ROW_NUMBER()' , 'LAG()' , 'LEAD()' , ការដំណើរការសរុប, ការផ្លាស់ប្តូរមធ្យម - គឺជាផ្នែកមួយនៃលក្ខណៈពិសេសដែលមានប្រសិទ្ធិភាពបំផុតនៃ SQL អស្ចារ្យ។ នៅក្នុងសំណួរមួយពួកគេអនុញ្ញាតឱ្យអ្នកធ្វើការដូច្នេះដែលនៅលើកម្រិតកម្មវិធីនឹងមានលក្ខណៈសម្បត្តិដែលមានភាពងាយស្រួលណាស់។ SELECT user_id, amount, order_date, SUM(amount) OVER ( PARTITION BY user_id ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS running_total FROM orders WHERE account_id = ?; វាត្រូវបានបង្កើតឡើងដោយសារតែការបញ្ជាទូទៅនៃការបញ្ជាទូទៅនៃការបញ្ជាទូទៅនៃការបញ្ជាទូទៅនៃការបញ្ជាទូទៅនៃការបញ្ជាទូទៅនៃការបញ្ជាទូទៅនៃការបញ្ជាទូទៅនៃការបញ្ជាទូទៅ។ ប្រសិនបើអ្នកធ្វើការអនុវត្តដូចគ្នានេះនៅលើអ្នកបង្កើតសំណួររបស់ ORM អ្នកនឹងមិនអាចធ្វើដូច្នេះទេ។ មិនដោយមិនកាត់បន្ថយទៅមជ្ឈមណ្ឌល SQL ដំបូងដូចគ្នានេះ។ ដូច្នេះអ្នកអាចធ្វើការគណនីទាំងអស់ទៅក្នុងគណនីទិន្នន័យទិន្នន័យទិន្នន័យទិន្នន័យទិន្នន័យទិន្នន័យទិន្នន័យទិន្នន័យទិន្នន័យទិន្នន័យទិន្នន័យទិន្នន័យទិន្នន័យទិន្នន័យទិន្នន័យទិន្នន័យទិន្នន័យទិន្នន័យទិន្នន័យទិន្នន័យទិន្នន័យទិន្នន័យទិន្នន័យទិន្នន័យ។ ការប្រតិបត្តិការ Bulk សូមអរគុណប្រសិនបើអ្នកត្រូវដោះស្រាយប្រសិនបើអ្នកត្រូវដោះស្រាយប្រសិនបើអ្នកត្រូវដោះស្រាយប្រសិនបើអ្នកត្រូវដោះស្រាយប្រសិនបើអ្នកត្រូវដោះស្រាយប្រសិនបើអ្នកត្រូវដោះស្រាយប្រសិនបើអ្នកត្រូវដោះស្រាយប្រសិនបើអ្នកត្រូវដោះស្រាយប្រសិនបើអ្នកត្រូវដោះស្រាយប្រសិនបើអ្នកត្រូវដោះស្រាយប្រសិនបើអ្នកត្រូវដោះស្រាយប្រសិនបើអ្នកត្រូវដោះស្រាយប្រសិនបើអ្នកត្រូវដោះស្រាយប្រសិនបើអ្នកត្រូវដោះស្រាយប្រសិនបើអ្នកត្រូវដោះស្រាយប្រសិនបើអ្នកត្រូវដោះស្រាយប្រសិនបើអ្នកត្រូវដោះស្រាយប្រសិនបើអ្នក គោលបំណងរបស់ ORM: foreach ($incomingRecords as $data) { $record = $this->repository->findOneBy(['external_id' => $data['id']]); if ($record === null) { $record = new SyncRecord(); $record->setExternalId($data['id']); } $record->setPayload($data['payload']); $record->setSyncedAt(new \DateTimeImmutable()); $this->em->persist($record); } $this->em->flush(); ដើម្បីដំណើរការ 10k ដំណោះស្រាយយើងនឹងត្រូវដំណើរការ 10,000 ការជ្រើសរើសសំណួរនិង 10,000 ការជ្រើសរើសសំណួរឬការបច្ចុប្បន្នភាព។ ហើយវានឹងត្រូវការរយៈពេលជាច្រើនដើម្បីដំណើរការ។ គោលបំណង SQL: INSERT INTO sync_records (external_id, payload, synced_at) VALUES (?, ?, NOW()), (?, ?, NOW()), ... ON DUPLICATE KEY UPDATE payload = VALUES(payload), synced_at = VALUES(synced_at); វាត្រូវបានដំឡើងនៅក្នុងផ្នែកមួយនៃ 500-1,000 ដំណឹង។ ពេលវេលាដំណើរការទាំងអស់: វិនាទី។ 'ON DUPLICATE KEY UPDATE' គឺជាលក្ខណៈពិសេស MySQL ។ វាមិនមានប្រសិទ្ធភាព ORM ។ ការបង្វិលប្រសិនបើមិនអាចបំពាក់នេះទេ។ ការប្រតិបត្តិការ JSON ប្រសិនបើអ្នករក្សាទុក JSON នៅក្នុងទិន្នន័យទិន្នន័យរបស់អ្នកហើយបន្ទាប់ពី MySQL 8 និង PostgreSQL បានធ្វើឱ្យវាជាការងាយស្រួលណាស់។ និងកម្មវិធីជាច្រើនធ្វើដូច្នេះ។ អ្នកនឹងដំណើរការទៅក្នុងកញ្ចប់នៃអ្វីដែល ORM របស់អ្នកអាចបង្ហាញ។ តម្រងតាមផ្លូវ JSON? តម្រងតាមតម្លៃតំបន់ JSON? ការប្រើប្រាស់ 'JSON_TABLE' ដើម្បីផ្លាស់ប្តូរទំហំ JSON ទៅជាបន្ទាត់? នេះគឺជាប្រតិបត្តិការពិតប្រាកដដែលទិន្នន័យគ្រប់គ្រងយ៉ាងល្អ។ វាគឺជាប្រតិបត្តិការដែល ORMs អាចគ្រប់គ្រងយ៉ាងហោចណាស់ជាផ្នែកមួយឬមិនគ្រប់យ៉ាង។ -- Find all products where attributes contain color = 'blue' SELECT * FROM products WHERE JSON_UNQUOTE(JSON_EXTRACT(attributes, '$.color')) = 'blue'; -- This works because we created a functional index: -- CREATE INDEX idx_color ON products((JSON_UNQUOTE(JSON_EXTRACT(attributes, '$.color')))); នៅពេលដែលអ្នកត្រូវការអ្វីមួយដូច្នេះអ្នកកំពុងសរសេរ SQL ដំបូងដូច្នេះ។ ដោយបច្ចេកទេសអ្នកអាចផ្លាស់ប្តូរអាសយដ្ឋាន json ក្នុងអាសយដ្ឋានមួយទៅជាអាសយដ្ឋានបច្ចេកទេសនៅក្នុងវេទិកាប៉ុន្តែវាគឺជាការបង្វិលជាងមុន។ Debugging: ការទូទាត់ការចែកចាយ Here is a scenario you have probably lived through. នេះគឺជាប្រវត្តិសាស្រ្តមួយដែលអ្នកអាចធ្វើបាន។ អ្នកអាចយល់ថានៅក្នុងការបញ្ជាទម្ងន់នៅក្នុងការផលិតនោះទេប៉ុន្តែថានៅក្នុងពេលដែលអតិថិជនអាចបញ្ជាក់ថានៅក្នុងការបញ្ជាទម្ងន់នោះទេប៉ុន្តែថានៅក្នុងពេលដែលអ្នកអាចបញ្ជាក់ថានៅក្នុងការបញ្ជាទម្ងន់នោះទេ។ អ្នកបើកកូដកម្មវិធីដើម្បីស្វែងរកសំណួរ។ វាគឺជាប្រព័ន្ធបណ្តុះបណ្តាលដែលមានវិធីសាស្រ្ត: កម្រិតខ្ពស់ប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលដោយគោលបំណងដោយផ្អែកលើទំហំទម្រង់ទម្រង់កម្រិតខ្ពស់ប្រហែលកម្រិតខ្ពស់ប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែលប្រហែល អ្នកអាចអនុញ្ញាតការកំណត់សៀវភៅសំណួរនិងរក្សាទុក SQL ។ វាមាន 60 ដំណឹង។ វាមានសំណួរបីដែលអ្នកមិនចង់រក្សាទុក។ វាមានសៀវភៅ 'ORDER BY' នៅលើបន្ទះដែលមិនត្រូវបានកំណត់សៀវភៅ។ តើអ្នកត្រូវដឹងពីរបៀបដែល subquery នេះបានមកពីអ្វី។ ការចែកចាយការចែកចាយការចែកចាយការចែកចាយការចែកចាយការចែកចាយការចែកចាយការចែកចាយការចែកចាយការចែកចាយការចែកចាយការចែកចាយការចែកចាយការចែកចាយការចែកចាយការចែកចាយការចែកចាយការចែកចាយការចែកចាយការចែកចាយការចែកចាយការចែកចាយការចែកចាយការចាយការចែកចាយការចាយការចែកចាយការចែកចាយ។ វាគឺជាការបង្អួចនៃភាពងាយស្រួលនៃ ORM ។ នៅពេលដែលអ្វីមួយគត់បានជួសជុល, អ្នកកំពុងធ្វើការបង្អួចពីរដំណាក់កាលនៅតែមួយ: គោលបំណងនៃកម្មវិធីនិងគោលបំណងនៃការបង្កើតសំណួរ។ ជាមួយនឹង SQL ដំបូង, អ្នកគ្រាន់តែបង្អួចមួយ។ // What you see in code review $users = $this->userRepository ->createQueryBuilder('u') ->leftJoin('u.account', 'a') ->andWhere('u.isActive = :active') ->andWhere('a.plan = :plan') ->setParameter('active', true) ->setParameter('plan', $plan) ->getQuery() ->getResult(); // What actually runs. And nobody reads until something breaks SELECT u.id, u.name, u.email, u.created_at, u.updated_at, u.is_active, u.account_id, a.id AS a_id, a.name AS a_name, a.plan AS a_plan, a.is_active AS a_is_active, a.created_at AS a_created_at, a.updated_at AS a_updated_at, a.meta AS a_meta FROM users u LEFT JOIN accounts a ON a.id = u.account_id WHERE u.is_active = 1 AND a.plan = 'enterprise' គោលបំណងនៃការសរសេរសេចក្តីអធិប្បាយនេះគឺជាអ្វីដែលអ្នកបានទូទាត់នៅពេលដែលអ្នកប្រើសម្រាប់ការសរសេរសេចក្តីអធិប្បាយពេញលេញ។ ជាទូទៅអ្នកគ្រាន់តែត្រូវតែបីពីសេចក្តីអធិប្បាយពីរដងនេះ។ ORM បានសរសេរសេចក្តីអធិប្បាយទាំងពីរដងដោយសារតែវាចង់ផ្តល់ឱ្យអ្នកនូវការសរសេរសេចក្តីអធិប្បាយពេញលេញ។ អគារដែលធ្វើការពិតប្រាកដ បន្ទាប់ពី 10 ឆ្នាំនៃការធ្វើឱ្យនិងមើលឃើញអត្ថប្រយោជន៍ទាំងនេះ, នេះគឺជារចនាសម្ព័ន្ធដែលខ្ញុំអនុវត្តទៅនឹងគម្រោងដែលខ្ញុំធ្វើការនៅលើ។ ORM owns: - ការកំណត់គំរូទាំងអស់និងការដំណើរការ ការគ្រប់គ្រងជីវិតសកម្មភាព (Create, Persist, Flush, Remove) - ការស្វែងរកងាយស្រួល: បានស្វែងរកដោយ ID, បានស្វែងរកដោយឯកសារតែមួយ, សៀវភៅប្លាស្ទិចនៃអាជីវកម្ម - ការគ្រប់គ្រងទំនាក់ទំនងក្នុងកំណត់កំណត់កំណត់កំណត់កំណត់តូច Raw SQL owns: - ពិនិត្យឡើងវិញដែលមានគោលបំណងសម្រាប់ប្រព័ន្ធប្រតិបត្តិការ, dashboards, or exports - ប្រព័ន្ធប្រតិបត្តិការទាំងអស់: ការដំឡើង batch, ការដំឡើង batch, upserts - ការបណ្តុះបណ្តុះបណ្តុះបណ្តុះបណ្តុះបណ្តុះបណ្តាល - កម្រងណាមួយដែលប្រើលក្ខណៈពិសេសឯកជនទិន្នន័យ - និងជាទូទៅសួរណាមួយដែលបានបង្ហាញនៅក្នុងសៀវភៅសៀវភៅសៀវភៅឆាប់រហ័ស ក្នុង Symfony, ការអនុវត្តនៃការបាត់បន្ថយនេះគឺស្រស់ស្អាត។ repositories entity បានដំណើរការកម្រិត ORM ។ កម្រិតសំណួរមួយគត់ - ខ្ញុំហៅថា "repositories read" ឬ "repositories query" - នឹងដំណើរការកម្រិត SQL ដោយប្រើ DBAL ដោយផ្ទាល់: // Entity repository - pure ORM, simple operations class UserRepository extends ServiceEntityRepository { public function findActiveById(int $id): ?User { return $this->findOneBy(['id' => $id, 'isActive' => true]); } public function save(User $user): void { $this->getEntityManager()->persist($user); $this->getEntityManager()->flush(); } } // Query repository - raw SQL, complex reads class UserAnalyticsRepository { public function __construct(private readonly Connection $db) {} public function getRetentionBySignupCohort(\DateTimeImmutable $from, \DateTimeImmutable $to): array { $sql = <<<SQL SELECT DATE_FORMAT(u.created_at, '%Y-%m') AS cohort, COUNT(DISTINCT u.id) AS total_users, COUNT(DISTINCT CASE WHEN u.last_active_at >= DATE_SUB(NOW(), INTERVAL 30 DAY) THEN u.id END) AS active_last_30d, ROUND( COUNT(DISTINCT CASE WHEN u.last_active_at >= DATE_SUB(NOW(), INTERVAL 30 DAY) THEN u.id END) / COUNT(DISTINCT u.id) * 100, 1 ) AS retention_pct FROM users u WHERE u.created_at BETWEEN :from AND :to GROUP BY cohort ORDER BY cohort ASC SQL; return $this->db->fetchAllAssociative($sql, [ 'from' => $from->format('Y-m-d'), 'to' => $to->format('Y-m-d'), ]); } } DBAL បានផ្តល់ឱ្យអ្នកនូវអ្វីគ្រប់យ៉ាងដែលអ្នកត្រូវការ - ការបញ្ជាក់ដែលបានរៀបចំការគ្រប់គ្រងការតភ្ជាប់ការគាំទ្រប្រតិបត្តិការ។ អ្នកមិនបាត់បង់សុវត្ថិភាពដើម្បីសរសេរ SQL ។ អ្នកបាត់បង់ hydration សម្ភារៈដែលអ្នកមិនត្រូវការសម្រាប់សំណួរនេះដូច្នេះទេ។ សូមពិនិត្យមើលអ្វីដែលកំណែ SQL ដំបូងផ្តល់ឱ្យអ្នកដែលកំណែ ORM មិនអាចធ្វើបាន: ការបណ្តុះបណ្តាលនេះគឺនៅទីនេះ។ អ្នកអភិវឌ្ឍន៍ណាមួយនៅក្រុមប្រឹក្សាភិបាលអាចអានវាត្រូវបានអានវាត្រូវបានអានវាត្រូវបានអានវាត្រូវបានអានវាត្រូវបានអានវាត្រូវបានអានវាត្រូវបានអានវាត្រូវបានអានវាត្រូវបានអានវាត្រូវបានអានវាត្រូវបានអានវាត្រូវបានអានវា។ សមត្ថភាពដែលមិនមែនជាការជ្រើសរើស មនុស្សមួយគត់គិតថា SQL គឺជាបទពិសោធមួយដែលអ្នកទទួលបានបន្ទាប់មកនៅពេលដែលឧបករណ៍ច្នៃប្រឌិតច្នៃប្រឌិតច្នៃប្រឌិត, ដូចជាការដឹងអំពីរបៀបប្រើម៉ាស៊ីនកែច្នៃប្រឌិតដោយសារតែទូរស័ព្ទរបស់អ្នកបានច្នៃប្រឌិត។ ខ្ញុំនឹងដឹងថាវាជាការឆ្លងកាត់បន្ថយ។ SQL គឺជាភាសាដែលទិន្នន័យទិន្នន័យរបស់អ្នកនិយាយ។ ទិន្នន័យទិន្នន័យនេះធ្វើការច្រើនជាងឧបករណ៍ផ្សេងទៀតណាមួយនៅក្នុងកម្មវិធីបង្វិលភាគច្រើន។ ការយល់ដឹងអំពីអ្វីដែលអ្នកតម្រូវឱ្យវាធ្វើគឺមិនមែនជាបទពិសោធដែលត្រូវការ។ វាគឺជាមូលដ្ឋាន។ អ្នកផ្គត់ផ្គង់ដែលខ្ញុំអរគុណយ៉ាងខ្លាំងជាងមុននៅក្នុងការរចនាសម្ព័ន្ធរបស់ខ្ញុំមានអ្វីដែលពួកគេត្រូវបានរួមគ្នា: ពួកគេមានភាពងាយស្រួលនៅលើគ្រប់កម្រិត។ ពួកគេប្រើ ORM នៅពេលដែលវាមានសមរម្យនិងសរសេរ SQL នៅពេលដែលវាមានសមរម្យ។ ពួកគេមិនគួរឱ្យចាប់អារម្មណ៍ថាការជួបប្រទះសម្រាប់ SQL គឺជាការអនុញ្ញាតនៃការបាត់បង់។ ពួកគេគួរឱ្យចាប់អារម្មណ៍ថាវាជាការប្រើឧបករណ៍ដែលត្រឹមត្រូវ។ ហើយពួកគេដឹងឧបករណ៍ដែលត្រឹមត្រូវដោយសារតែពួកគេដឹងទាំងពីរ។ យើងមិនចង់ដឹងអំពីរបៀបដែលគម្រោង SQL ដែលបានបង្កើត។ យើងចង់ដឹងអំពីរបៀបដែលគម្រោង SQL អាចប្រើសម្រាប់ឧបករណ៍បញ្ជាទិន្នន័យ។ យើងចង់ដឹងអំពីរបៀបដែលគម្រោង SQL អាចប្រើសម្រាប់ឧបករណ៍បញ្ជាទិន្នន័យ។ យើងចង់ដឹងអំពីរបៀបដែលគម្រោង SQL អាចប្រើឧបករណ៍បញ្ជាទិន្នន័យ។