เมื่อใดฉันจึงควรใช้ DBIx :: Class ของ Perl


17

DBIx :: ชั้นเป็นอินเตอร์เฟซ Perl นิยมไปยังฐานข้อมูลใด ๆ ที่คุณสามารถเชื่อมต่อผ่านDBI มีเอกสารที่ดีสำหรับรายละเอียดทางเทคนิค แต่มีข้อมูลเกี่ยวกับการใช้งานที่เหมาะสม (รวมถึงสถานการณ์ที่คุณอาจไม่ต้องการ)

ในหลาย ๆ สถานการณ์ผู้คนจะเข้าถึงมันอย่างถี่ถ้วนเพราะพวกเขาคิดว่าพวกเขาควรใช้มันสำหรับทุกสิ่งที่เกี่ยวข้องกับฐานข้อมูล อย่างไรก็ตามฉันมักจะเห็นว่ามันใช้ผิดวัตถุประสงค์จนถึงจุดที่มันกลายเป็นจุดปวด คำถามของฉันในระหว่างการตรวจสอบโค้ดและสถาปัตยกรรมอยู่เสมอ "อะไรคือประโยชน์ที่ฟูให้คุณ?" บ่อยครั้งที่นักพัฒนาที่ฉันเห็นในสถานการณ์เหล่านี้ไม่สามารถสร้างคำตอบที่สอดคล้องกันได้ แต่บ่อยครั้งที่พวกเขาไม่เข้าใจ SQL อย่างง่าย

ในช่วงสองสามเดือนที่ผ่านมาฉันถามคนอื่นว่า "ทำไมคุณถึงใช้ DBIx :: Class?" และได้รับคำตอบที่ดีเพียงคำเดียวเท่านั้น (และบุคคลนั้นก็สามารถตอบกลับการติดตาม "เมื่อใดที่คุณจะไม่ใช้") Peter Rabbitson ผู้พัฒนานำได้ใกล้กับคำตอบในการสัมภาษณ์ของเขาเกี่ยวกับFLOSS Weeklyแต่มันถูกฝังอยู่เล็กน้อยในระหว่างการสัมภาษณ์

ดังนั้นฉันจะตัดสินใจได้อย่างไรว่าการใช้ DBIx :: Class นั้นเหมาะสมกับโครงการหรือไม่?


3
คุณกำลังเขียนหนังสืออีกเล่มหรือไม่? :)
simbabque

1
จากประสบการณ์ของฉันความเจ็บปวดเกิดขึ้นเมื่อ DBIC ถูกนำมาใช้ในสถานการณ์ที่มันเกินกำลัง และแม้ว่าจะมีประสิทธิภาพมาก แต่ก็มักจะเกินความเป็นจริงเพราะผู้คนใช้คุณลักษณะพื้นฐานเท่านั้น (การสร้างและการรวม SQL) และไม่ต้องการสิ่งอื่นใด นั่นเป็นเหตุผลที่ฉันเขียน DBIx :: Lite ซึ่งมีคุณสมบัติพื้นฐานเหล่านั้นและไม่ต้องการสคีมาใด ๆ
Alessandro

คำตอบ:


24

ก่อนที่ฉันจะตอบคำถามฉันคิดว่าพื้นหลังบางอย่างอยู่ในระเบียบ

แก่นแท้ของปัญหา

หลังจากสัมภาษณ์และจ้างนักพัฒนามาหลายปีฉันได้เรียนรู้สองสิ่ง:

  1. นักพัฒนาส่วนใหญ่มีประสบการณ์น้อยมากในการออกแบบฐานข้อมูล

  2. ฉันสังเกตเห็นความสัมพันธ์ที่หลวมระหว่างผู้ที่ไม่เข้าใจฐานข้อมูลและผู้ที่เกลียดชัง ORM

(หมายเหตุ: และใช่ฉันรู้ว่ามีผู้ที่เข้าใจฐานข้อมูลเป็นอย่างดีที่เกลียด ORMs)

เมื่อคนไม่เข้าใจว่าทำไมคีย์ต่างประเทศที่มีความสำคัญว่าทำไมคุณไม่ฝังชื่อผู้ผลิตในitemตารางหรือทำไมcustomer.address1, customer.address2และcustomer.address3สาขาที่ไม่ได้เป็นความคิดที่ดีเพิ่มออมที่จะทำให้มันง่ายขึ้นสำหรับพวกเขาที่จะข้อบกพร่องฐานข้อมูลการเขียน จะไม่ช่วยอะไรเลย

ด้วยฐานข้อมูลที่ออกแบบมาอย่างถูกต้องและกรณีการใช้ OLTP แทน ORM จึงเป็นทองคำ งานที่หนักหน่วงส่วนใหญ่หายไปและด้วยเครื่องมือเช่นDBIx :: Class :: Schema :: Loaderฉันสามารถเปลี่ยนจาก schema ของฐานข้อมูลที่ดีไปจนถึงการทำงานของรหัส Perl ในเวลาไม่กี่นาที ฉันจะอ้างอิง Pareto Rule และบอกว่า 80% ของปัญหาของฉันได้รับการแก้ไขด้วย 20% ของงาน แต่ในความเป็นจริงฉันพบประโยชน์มากกว่านั้น

การใช้โซลูชันอย่างไม่เหมาะสม

อีกเหตุผลที่บางคนเกลียด ORMs ก็เพราะพวกเขาจะปล่อยให้สิ่งที่เป็นนามธรรมรั่วไหล ลองพิจารณากรณีทั่วไปของเว็บแอป MVC นี่คือสิ่งที่เราเห็นโดยทั่วไป (รหัสหลอก):

GET '/countries/offices/$company' => sub {
    my ( $app, $company_slug ) = @_;
    my $company = $app->model('Company')->find({ slug => $company_slug }) 
      or $app->redirect('/');
    my $countries = $app->model('Countries')->search(
     {
         'company.company_id' => $company->company_id,
     },
     {
         join     => [ offices => 'company' ],
         order_by => 'me.name',
     },
   );
   $app->stash({
     company   => $company,
     countries => $country,
   });
}

ผู้คนเขียนเส้นทางควบคุมเช่นนั้นและตบหลังตัวเองคิดว่ามันดีรหัสที่สะอาด พวกเขาอาจจะตกตะลึงกับ SQL แบบเข้ารหัสในตัวควบคุมของพวกเขา แต่พวกเขาได้ทำมากกว่าการเปิดเผยไวยากรณ์ SQL ที่แตกต่างกันเล็กน้อย รหัส ORM ของพวกเขาจะต้องมีการผลักลงในแบบจำลองและจากนั้นพวกเขาสามารถทำได้:

GET '/countries/offices/$company' => sub {
   my ( $app, $company_slug ) = @_;
   my $result = $app->model('Company')->countries($company_slug)
     or $app->redirect('/');
   $app->stash({ result => $result });
}

คุณรู้ไหมว่าเกิดอะไรขึ้นตอนนี้ คุณได้ห่อหุ้มแบบจำลองของคุณอย่างถูกต้องแล้วคุณไม่ได้รับ ORM และหลังจากนั้นเมื่อคุณพบว่าคุณสามารถดึงข้อมูลนั้นจากแคชแทนที่จะเป็นฐานข้อมูลคุณไม่จำเป็นต้องเปลี่ยนรหัสคอนโทรลเลอร์ของคุณ (และง่ายขึ้น เพื่อเขียนการทดสอบและใช้ตรรกะซ้ำ)

ในความเป็นจริงสิ่งที่เกิดขึ้นคือผู้คนรั่วไหลรหัส ORM ของพวกเขาไปทั่วตัวควบคุม (และมุมมอง) และเมื่อพวกเขาประสบปัญหาเรื่องความสามารถในการปรับขนาดพวกเขาเริ่มโทษ ORM มากกว่าสถาปัตยกรรมของพวกเขา ORM ได้รับการลงโทษที่ไม่ดี (ฉันเห็นสิ่งนี้ซ้ำ ๆ สำหรับลูกค้าหลายราย) แทนที่จะซ่อนสิ่งที่เป็นนามธรรมเพื่อที่ว่าเมื่อคุณได้รับขีด จำกัด ORM อย่างแท้จริงแล้วคุณสามารถเลือกวิธีการแก้ปัญหาที่เหมาะสมสำหรับปัญหาของคุณแทนที่จะปล่อยให้โค้ดเชื่อมโยงกับ ORM ที่คุณผูกติดอยู่อย่างแน่นหนา

การรายงานและข้อ จำกัด อื่น ๆ

เนื่องจาก Rob Kinyon มีความชัดเจนด้านบนการรายงานจึงเป็นจุดอ่อนใน ORM นี่เป็นส่วนย่อยของปัญหาที่ใหญ่กว่าซึ่ง SQL หรือ SQL ที่ซับซ้อนซึ่งบางครั้งอาจมีหลายตารางทำงานได้ไม่ดีกับ ORM ตัวอย่างเช่นบางครั้ง ORM บังคับให้ประเภทการเข้าร่วมที่ฉันไม่ต้องการและฉันไม่สามารถบอกวิธีการแก้ไขได้ หรือบางทีผมอยากจะใช้คำใบ้ดัชนีใน MySQL แต่มันไม่ง่าย หรือบางครั้ง SQL นั้นมีความซับซ้อนมากซึ่งมันจะดีกว่าถ้าจะเขียน SQL แทนที่จะเป็นนามธรรม

นี้เป็นส่วนหนึ่งของเหตุผลที่ผมได้เริ่มต้นเขียนDBIx :: ชั้น :: รายงาน จนถึงตอนนี้มันใช้งานได้ดีและแก้ไขปัญหาส่วนใหญ่ที่ผู้คนมีได้ที่นี่ (ตราบใดที่พวกเขาตกลงกับอินเตอร์เฟซแบบอ่านอย่างเดียว) และในขณะที่ดูเหมือนว่าเป็นไม้ยันรักแร้ แต่ในความเป็นจริงตราบใดที่คุณไม่ได้ทำสิ่งที่เป็นนามธรรม (ดังที่อธิบายไว้ในหัวข้อก่อนหน้า) มันทำให้การทำงานDBIx::Classง่ายขึ้น

ดังนั้นเมื่อใดที่ฉันจะเลือก DBIx :: Class

สำหรับฉันฉันจะเลือกมันเกือบทุกครั้งที่ฉันต้องการอินเทอร์เฟซไปยังฐานข้อมูล ฉันใช้มันมาหลายปีแล้ว อย่างไรก็ตามฉันอาจไม่เลือกใช้สำหรับระบบ OLAP และโปรแกรมเมอร์รุ่นใหม่จะต้องต่อสู้กับมันอย่างแน่นอน นอกจากนี้ฉันมักพบว่าฉันต้องการการเขียนโปรแกรมเมตาและในขณะที่DBIx::Classมีเครื่องมือพวกเขาก็มีเอกสารไม่ดีมาก

กุญแจสำคัญในการใช้DBIx::Classอย่างถูกต้องเหมือนกับ ORM ส่วนใหญ่:

  1. อย่ารั่วสิ่งที่เป็นนามธรรม

  2. เขียนแบบทดสอบที่ถูกสาป

  3. รู้วิธีเลื่อนลงไปที่ SQL ได้ตามต้องการ

  4. เรียนรู้วิธีทำให้ฐานข้อมูลเป็นมาตรฐาน

DBIx::Classเมื่อคุณเรียนรู้แล้วจะช่วยดูแลการยกของหนักของคุณและทำให้การเขียนแอปพลิเคชั่นเป็นไปอย่างรวดเร็ว


1
บางทีคุณสามารถเพิ่มรายการอื่นเมื่อคุณไม่ได้ใช้ :)
brian d foy

1
นี่เป็นสิ่งที่ชัดเจนสำหรับคุณ แต่อาจไม่ชัดเจนสำหรับผู้อ่านหลายคน (ฉันว่าต้องใช้เวลาหลายปี#dbix-classและ#catalyst) - กุญแจสำคัญในการ "อย่ารั่วซึมสิ่งที่เป็นนามธรรม" คือทุกสิ่งที่คุณทำงานด้วยใน DBIC คือ คลาสย่อยของบางสิ่งที่จัดเตรียมลักษณะการทำงานของตัวตัดคุกกี้ คุณควรที่จะเพิ่มวิธีการในคลาสย่อยของคุณและถ้าคุณไม่ได้ทำงาน Q & D เพียงวิธีที่คุณเขียนควรเป็นส่วนหนึ่งของส่วนติดต่อสาธารณะของคุณ
ฮอบส์

@ ฮอบส์: แน่นอนว่าเป็นที่ที่ฉันเห็นผู้คนไปผิดกับสิ่งนี้มากที่สุดและเป็นวิธีที่พวกเขาติดอยู่กับ DBIC เรามักจะสมมติให้ผู้คนรู้ว่าพวกเขากำลังทำอะไรในสิ่งเล็ก ๆ แต่รู้ว่าพวกเขาทำอะไรไม่ได้
brian d foy

9

เมื่อต้องการทราบว่าต้องใช้อะไรเมื่อไหร่สิ่งสำคัญคือต้องเข้าใจว่าจุดประสงค์ของสิ่งนั้นคืออะไร เป้าหมายของผลิตภัณฑ์คืออะไร

DBIx :: Class เป็น ORM - Mapper วัตถุสัมพันธ์ ORM ใช้โครงสร้างข้อมูลฐานข้อมูลเชิงสัมพันธ์ / ชุดสัมพันธ์และแม็พกับแผนผังต้นไม้ การแม็พแบบดั้งเดิมคือหนึ่งวัตถุต่อแถวโดยใช้โครงสร้างของตารางเป็นคำอธิบายคลาส ความสัมพันธ์พาเรนต์ - ลูกในฐานข้อมูลถือว่าเป็นความสัมพันธ์ที่ จำกัด ระหว่างวัตถุ

นั่นคือกระดูกของมัน แต่นั่นไม่ได้ช่วยให้คุณตัดสินใจได้ว่าคุณควรใช้ ORM ORMs นั้นมีประโยชน์เป็นหลักเมื่อสิ่งต่อไปนี้เป็นจริง:

  • คุณใช้ฐานข้อมูลเชิงสัมพันธ์
  • ข้อมูลของคุณส่วนใหญ่ใช้สำหรับ OLTP (การประมวลผลธุรกรรมออนไลน์)
  • คุณไม่ได้เขียนรายงานภายในแอปพลิเคชันของคุณ

จุดแข็งที่ใหญ่ที่สุดที่ ORM สร้างขึ้นคือ SQL ที่ดีเพื่อเดินกราฟต้นไม้ที่วางซ้อนอยู่ด้านบนของโครงสร้างข้อมูลเชิงสัมพันธ์ SQL มักจะมีขนดกและซับซ้อน แต่นั่นคือราคาของการจัดการความไม่ตรงกันของอิมพีแดนซ์

ในขณะที่ ORMs สามารถเขียน SQL การแยกแถวได้ดีมากพวกเขายากจนมากในการเขียนเรียง SQL นี่คือประเภทของ SQL ที่สร้างรายงาน การเรียงลำดับนี้ถูกสร้างขึ้นโดยใช้เครื่องมือต่าง ๆ ไม่ใช่ ORM

มีหลาย ORMs ในภาษาต่าง ๆ หลายแห่งใน Perl ตัวแม็พอื่น ๆ คือ Class :: DBI และ Rose :: DB DBIx :: Class นั้นมักจะถูกพิจารณาว่าดีกว่าตัวอื่น ๆ ในด้านความแข็งแกร่งของชุดผลลัพธ์ นี่เป็นแนวคิดที่การสร้าง SQL จะถูกแยกออกจากการดำเนินการของ SQL


อัปเดต : เพื่อตอบสนองต่อ Ovid, DBIx :: Class (ผ่าน SQL :: Abstract) ให้ความสามารถในการระบุทั้งคอลัมน์ที่จะส่งกลับรวมถึงดัชนีคำแนะนำที่จะใช้

โดยทั่วไปแล้วหากคุณต้องการทำเช่นนี้คุณควรที่จะไม่ใช้ ORM สำหรับการสืบค้นเฉพาะนั้น ข้อควรจำ - วัตถุประสงค์หลักของ ORM คือการจับคู่แถวในตารางกับวัตถุของคลาสที่มีแอตทริบิวต์เป็นคอลัมน์ของตาราง หากคุณเพียงเติมคุณสมบัติบางอย่างแล้วผู้ใช้ที่มีศักยภาพของวัตถุนั้นจะไม่ทราบว่าคุณลักษณะใดที่มีการเติมข้อมูลหรือไม่ สิ่งนี้นำไปสู่การเขียนโปรแกรมการป้องกันที่น่ากลัวและ / หรือความเกลียดชังทั่วไปของ ORM

เกือบตลอดเวลาความปรารถนาที่จะใช้คำแนะนำดัชนีหรือ จำกัด คอลัมน์ที่จะถูกส่งกลับเป็นทั้งการเพิ่มประสิทธิภาพสำหรับความเร็วและ / หรือแบบสอบถามแบบรวม

  • แบบสอบถามแบบรวมเป็นกรณีการใช้ ORM ไม่ได้ถูกออกแบบมาสำหรับ ในขณะที่ DBIx :: Class สามารถสร้างแบบสอบถามแบบรวมคุณไม่ได้สร้างกราฟวัตถุดังนั้นเพียงใช้ DBI โดยตรง
  • การปรับประสิทธิภาพให้เหมาะสมถูกนำมาใช้เนื่องจากข้อมูลที่ถูกสอบถามมีขนาดใหญ่เกินไปสำหรับฐานข้อมูลพื้นฐานไม่ว่าคุณจะเข้าถึงอย่างไร ฐานข้อมูลเชิงสัมพันธ์ส่วนใหญ่เหมาะสำหรับตารางที่มีแถวสูงถึง 1-3 มม. ที่ทำงานจาก SSD ซึ่งข้อมูล + ดัชนีส่วนใหญ่เหมาะสมกับ RAM หากสถานการณ์ของคุณใหญ่กว่านี้ทุกฐานข้อมูลเชิงสัมพันธ์จะมีปัญหา

ใช่ DBA ที่ยอดเยี่ยมสามารถสร้างตารางที่มีฟังก์ชันแถว 100 มม. ใน Oracle หรือ SQL * Server หากคุณกำลังอ่านสิ่งนี้คุณไม่มีพนักงาน DBA ที่ยอดเยี่ยม

ทั้งหมดนี้กล่าวว่า ORM ที่ดีทำมากกว่าสร้างกราฟวัตถุ - มันยังให้คำจำกัดความของฐานข้อมูลของคุณ คุณสามารถใช้สิ่งนี้เพื่อช่วยสร้างคิวรีแบบเฉพาะกิจและใช้มันตามที่คุณต้องการด้วย DBI โดยไม่ต้องสร้างกราฟวัตถุ


ฉันคิดว่าเกือบทุกอย่างที่ฉันเห็นเขียนรายงานซึ่งอาจเป็นสาเหตุที่ผู้คนต้องเลื่อนลงไปที่ข้อความค้นหาด้วยตนเอง (และนั่นคือความเจ็บปวด)
brian d foy

1
ฉันไม่เข้าใจว่าเพราะเหตุใดคุณจึงต้องเลื่อนลงไปที่คำค้นหาด้วยตนเองสำหรับรายงาน ฉันได้สร้างรายงานที่ซับซ้อนโดยใช้ DBIC แน่นอนว่ามันมักจะเกี่ยวข้องกับการสร้างชุดผลลัพธ์ที่กำหนดเองจำนวนมากโดยใช้ 'prefetch' และ 'เข้าร่วม' อย่างหนัก
Dave Cross

Dave: SQL แบบแมนนวลสามารถเขียนได้ง่ายกว่ามากและเพื่อให้แน่ใจว่าคุณดึงเฉพาะเจ็ดฟิลด์ที่คุณต้องการจากสามตารางและแสดงในแถวเดียว นอกจากนี้ยังง่ายต่อการให้คำแนะนำเมื่อเขียน SQL ดิบ
เคอร์ติสโพ

> เพื่อให้แน่ใจว่าคุณดึงเฉพาะเจ็ดฟิลด์ที่คุณต้องการใช่นั่นคือสิ่งที่ "คอลัมน์" attr สำหรับการค้นหา ResultSet ใช้ ข้อโต้แย้งที่ถูกต้องเพียงอย่างเดียวที่ฉันเคยได้ยินหรือเห็นในการทำ SQL แบบดิบคือ: 1. แบบสอบถามย่อยที่ซับซ้อนอย่างมากซึ่งมักเป็นผลงานของตาราง / DB ที่ออกแบบมาไม่ดี 2. การเรียกใช้ DDL หรือการดำเนินการ 'do' อื่น ๆ ไม่ได้สร้างขึ้นมาเพื่อ 3. พยายามแฮ็คข้อมูลคำแนะนำดัชนี อีกครั้งนั่นเป็นจุดอ่อนของ RDBMS แต่บางครั้งก็จำเป็นต้องทำ และเป็นไปได้ที่จะเพิ่มฟังก์ชันประเภทนั้นลงใน DBIC
Brendan Byrd

8

ในฐานะหนึ่งในนักพัฒนาหลักของแพลตฟอร์มอีคอมเมิร์ซ Interchange6 (และคลั่งไคล้สคีมาหลัก) ฉันมีประสบการณ์เชิงลึกกับ DBIC นี่คือบางสิ่งที่ทำให้มันเป็นแพลตฟอร์มที่ยอดเยี่ยม:

  • ตัวสร้างแบบสอบถามช่วยให้คุณสามารถเขียนหนึ่งครั้งสำหรับเอ็นจิ้นฐานข้อมูลจำนวนมาก (และหลายรุ่นในแต่ละรุ่น) ขณะนี้เราสนับสนุน Interchange6 กับ MySQL, PostgreSQL และ SQLite และจะเพิ่มการสนับสนุนสำหรับเอ็นจิ้นเพิ่มเติมเมื่อเราได้รับเวลาและทรัพยากร ขณะนี้มีเพียงสองเส้นทางรหัสในโครงการทั้งหมดที่มีรหัสเพิ่มเติมเพื่อรองรับความแตกต่างระหว่างเครื่องยนต์และนี่คือหมดจดเนื่องจากการขาดฟังก์ชั่นฐานข้อมูลเฉพาะอย่างใดอย่างหนึ่ง (ขาด SQLite ในสถานที่) หรือเนื่องจากความโง่ของ MySQL ที่เปลี่ยน วิธีที่ฟังก์ชัน LEAST จัดการกับ NULL ระหว่างสองเวอร์ชันรอง

  • ข้อความค้นหาที่กำหนดไว้ล่วงหน้าหมายถึงฉันสามารถสร้างวิธีการง่ายๆที่สามารถเรียกใช้ (มีหรือไม่มี args) จากรหัสแอปพลิเคชันดังนั้นฉันจึงเก็บแบบสอบถามของฉันส่วนใหญ่อยู่ในคำจำกัดความของสคีมาแทนการทิ้งรหัสแอปพลิเคชันของฉัน

  • การสร้างแบบสอบถามแบบ Composable ช่วยให้สามารถแยกแบบสอบถามออกเป็นแบบสอบถามที่กำหนดไว้ล่วงหน้าขนาดเล็กที่เข้าใจได้และถูกรวมเข้าด้วยกันเพื่อสร้างแบบสอบถามที่ซับซ้อนซึ่งยากต่อการรักษาระยะยาวใน DBIC (แม้แต่แย่กว่าใน SQL บริสุทธิ์) หากสร้างในขั้นตอนเดียว

  • Schema :: Loader ทำให้เราสามารถใช้ DBIC กับแอปพลิเคชั่นรุ่นเก่าที่ให้เช่าชีวิตแบบใหม่และเส้นทางที่ง่ายกว่าในอนาคต

  • ปลั๊กอิน DBIC, DeploymentHandler & Migration ทั้งหมดเพิ่มอย่างมากในชุดเครื่องมือที่ทำให้ชีวิตของฉันง่ายขึ้น

หนึ่งในความแตกต่างอย่างมากระหว่าง DBIC และแพลตฟอร์มคล้าย ORM / ORM อื่น ๆ ส่วนใหญ่คือแม้ว่ามันจะพยายามแนะนำคุณในการทำสิ่งต่าง ๆ แต่ก็ไม่ได้หยุดที่คุณจะทำสิ่งที่คุณชอบ:

  • คุณสามารถใช้ฟังก์ชั่น SQL และขั้นตอนการจัดเก็บที่ DBIC ไม่ทราบเพียงแค่ใส่ชื่อฟังก์ชั่นเป็นคีย์ในแบบสอบถาม (ยังสามารถนำไปสู่ความสนุกเมื่อคุณลองใช้ LEAST ใน MySQL ^^ แต่นั่นไม่ใช่ความผิดของ DBIC) .

  • ตัวอักษร SQL สามารถใช้เมื่อไม่มี 'วิธี DBIC' ที่จะทำบางสิ่งบางอย่างและผลที่ได้กลับมายังคงถูกห่อหุ้มในคลาสที่ดีกับ accessors

TL; DR ฉันอาจจะไม่สนใจที่จะใช้มันสำหรับแอพพลิเคชั่นที่เรียบง่ายจริง ๆ มีเพียงไม่กี่ตาราง แต่เมื่อฉันต้องการจัดการสิ่งที่ซับซ้อนมากขึ้นโดยเฉพาะอย่างยิ่งที่ความเข้ากันได้ระหว่างเครื่องยนต์และการบำรุงรักษาในระยะยาว โดยทั่วไปเส้นทางที่ฉันต้องการ


7

(ก่อนที่ฉันจะเริ่มฉันควรพูดว่านี่เป็นเพียงการเปรียบเทียบ DBIC, DBI และ DBI-based DBI wrappers ฉันไม่ได้มีประสบการณ์กับ Perl ORM อื่น ๆ และดังนั้นจะไม่แสดงความคิดเห็นกับพวกเขาโดยตรง)

DBIC ทำสิ่งต่างๆได้ดีมาก ฉันไม่ได้เป็นผู้ใช้งานหนัก แต่ฉันรู้ทฤษฎี มันค่อนข้างเป็นงานที่ดีของการสร้าง SQL และโดยเฉพาะอย่างยิ่ง (ตามที่ฉันได้รับการบอกเล่า) การจัดการเข้าร่วมเป็นต้นนอกจากนี้ยังสามารถทำการดึงข้อมูลที่เกี่ยวข้องอื่น ๆ

ข้อได้เปรียบที่สำคัญอย่างที่ฉันเห็นคือความสามารถในการใช้ผลลัพธ์เป็นคลาสโมเดลของคุณโดยตรง สิ่งนี้เรียกว่า "การเพิ่มวิธีตั้งค่าผลลัพธ์" ซึ่งคุณสามารถรับผลลัพธ์และวิธีการโทรในผลลัพธ์เหล่านั้นได้ ตัวอย่างทั่วไปกำลังดึงวัตถุผู้ใช้จาก DBIC แล้วเรียกวิธีการตรวจสอบว่ารหัสผ่านของพวกเขาถูกต้อง

การปรับใช้ schema ที่แน่นอนอาจเป็นเรื่องยาก แต่ก็ยากเสมอ DBIC มีเครื่องมือ (บางตัวในโมดูลภายนอก) ซึ่งทำให้ง่ายขึ้นและอาจจะง่ายกว่าการจัดการ schema ของคุณเอง

ในอีกด้านหนึ่งของเหรียญมีเครื่องมืออื่น ๆ ที่ดึงดูดความรู้สึกอ่อนไหวอื่น ๆ เช่นห่อหุ้ม DBI ที่ปรุงแต่งด้วยโมโจ สิ่งเหล่านี้มีความน่าสนใจที่จะเป็นแบบลีนและยังสามารถใช้งานได้ ส่วนใหญ่มีคิวจาก Mojo :: Pg (ต้นฉบับ) และเพิ่มคุณสมบัติที่มีประโยชน์เช่นการจัดการสคีมาในไฟล์แบนและการรวม pubsub

โมดูลที่ปรุงแต่งรสโมโจเหล่านี้เติบโตขึ้นจากจุดอ่อนอื่น ๆ ของ DBIC ซึ่งก็คือมันยังไม่สามารถทำแบบสอบถามแบบอะซิงโครนัสได้ ผู้เขียนยืนยันกับฉันว่ามันเป็นไปได้ทางเทคนิคบางทีอาจจะเร็วกว่า แต่ก็มีปัญหาในการออกแบบ API ที่เหมาะสม (เป็นที่ยอมรับว่าฉันถูกขอให้ช่วยเหลือด้วยเรื่องนี้และในขณะที่ฉันต้องการฉันก็ไม่รู้จะเคลื่อนเข็มได้อย่างไรในเวลาที่ฉันต้องอุทิศมัน)

TL; DR ใช้ DBIC เว้นแต่ว่าคุณจะรัก SQL หรือคุณต้องการ async ซึ่งในกรณีนี้ให้ตรวจสอบตัวห่อหุ้ม DBI ที่ปรุงแต่งด้วย Mojo


6

ฉันเขียนความคิดของฉันเกี่ยวกับเรื่องนี้ในDBIC กับ DBI เมื่อสามปีที่แล้ว เพื่อสรุปฉันระบุเหตุผลหลักสองประการ:

  1. DBIC หมายความว่าฉันไม่ต้องคิดถึง SQL เล็กน้อยที่จำเป็นสำหรับแอพพลิเคชั่นใด ๆ ที่ฉันเขียน
  2. DBIC ให้ฉันวัตถุกลับมาจากฐานข้อมูลมากกว่าโครงสร้างข้อมูลที่เป็นใบ้ ซึ่งหมายความว่าฉันมีความดีมาตรฐาน OO ทั้งหมดที่จะเล่นกับ โดยเฉพาะฉันพบว่ามีประโยชน์จริง ๆ ที่สามารถเพิ่มวิธีการไปยังวัตถุ DBIC ของฉัน

สำหรับรูปแบบการต่อต้านสิ่งเดียวที่ฉันคิดได้ก็คือประสิทธิภาพ หากคุณต้องการบีบทุกรอบนาฬิกาออกจาก CPU ของคุณบางที DBIC ไม่ใช่เครื่องมือที่เหมาะสมสำหรับงาน แต่สำหรับแอพพลิเคชั่นที่เขียนกรณีเหล่านี้หายากขึ้นเรื่อย ๆ ฉันจำไม่ได้ว่าครั้งล่าสุดที่ฉันเขียนแอปพลิเคชันใหม่ที่พูดคุยกับฐานข้อมูลและไม่ได้ใช้ DBIC แน่นอนมันช่วยถ้าคุณรู้เพียงเล็กน้อยเกี่ยวกับการปรับแต่งแบบสอบถามที่ DBIC สร้าง


2
อืมฉันไม่สามารถแก้ไขความผิดพลาดได้เพราะฉันเปลี่ยนตัวอักษรไม่มากพอ ("righ ttool") ง่อยอยากรู้อยากเห็น แต่นี่เป็นคำตอบที่ไขปริศนาฉัน ฉันคิดว่าในโพสต์ PerlHacks ของคุณคุณพูดถึงสิ่งหนึ่งที่ Rob ชี้ให้เห็น แต่ไม่ต้องคำนึงถึงเรื่องอื่น ในหลายกรณีฉันพบผู้คนกำลังย้อนกลับไปใช้ SQL แบบแมนนวล
brian d foy

1

วิธีที่ฉันทำให้ขนาด:

  1. สร้างคลาสหนึ่งที่มีตัวสร้างซ็อกเก็ต DBI และวิธีทดสอบ

  2. สืบทอดคลาสนั้นลงในคลาสเคียวรี SQL ของคุณ (หนึ่งคลาสต่อตาราง sql) และทดสอบซ็อกเก็ต ณ เวลาตัวสร้าง

  3. ใช้ตัวแปรที่กำหนดขอบเขตคลาสเพื่อเก็บชื่อตารางและชื่อคอลัมน์ดัชนีหลักของคุณ

  4. เขียนชื่อตาราง interpolating SQL และคอลัมน์ดัชนีหลักทั้งหมดของคุณจากตัวแปรเหล่านั้นแทนที่จะกำหนดไว้ใน SQL แบบสแตติก

  5. ใช้มาโครตัวแก้ไขเพื่อให้คุณสร้างคู่เมธอด DBI พื้นฐาน (เตรียมและดำเนินการ) ในขณะที่พิมพ์คำสั่ง sql เท่านั้น

หากคุณสามารถทำได้คุณสามารถเขียนโค้ด API แบบสะอาดด้านบนของ DBI ตลอดทั้งวันได้อย่างง่ายดาย

สิ่งที่คุณจะพบคือข้อความค้นหาจำนวนมากของคุณจะถูกเคลื่อนย้ายข้ามหลายตาราง ณ จุดนี้คุณสามารถตัดและวางลงในคลาส EXPORTER แล้วโรยกลับไปตามที่ต้องการ นี่คือจุดที่การแก้ไขขอบเขตของชื่อตารางและชื่อคอลัมน์ดัชนีหลักเข้าสู่การเล่น

ฉันใช้วิธีนี้เพื่อปรับวิธีการ DBI หลายร้อยวิธีด้วยประสิทธิภาพที่ค่อนข้างดี ฉันไม่ต้องการลองและบำรุงรักษาโค้ด DBI ด้วยวิธีอื่น

เมื่อใดที่จะใช้ DBI: เสมอ

ฉันไม่คิดว่านั่นเป็นคำถามจริงของคุณ คำถามจริงของคุณคือ: "มันดูเหมือน PITA ขนาดใหญ่โปรดบอกฉันว่าฉันไม่ต้องทำอย่างนั้นเหรอ?"

คุณทำไม่ได้ จัดวางอย่างถูกต้องและส่วน DBI ได้รับการซ้ำซ้อนมากพอที่จะทำให้เป็นอัตโนมัติ


โอกาสใดก็ตามที่คุณมีโปรเจ็กต์โอเพนซอร์ซที่คุณสามารถแบ่งปันหรืออาจจะเป็นเพียงแก่นสารของ github พร้อมตัวอย่างของแต่ละคลาส ฉันคิดว่าความคิดที่คุณพูดนั้นน่าสนใจและอาจเป็นไปได้สำหรับโครงการของคนจำนวนมาก แต่มันจะง่ายขึ้นนิดหน่อยที่จะไปกับตัวอย่าง
msouth

0

ฉันไม่ใช่ผู้เชี่ยวชาญ Perl แต่ฉันใช้มันเยอะ มีหลายสิ่งที่ฉันไม่รู้จักหรือรู้วิธีที่จะทำได้ดีกว่า; บางสิ่งที่ฉันเพิ่งยังไม่สามารถเข้าใจได้แม้จะมีเอกสารประกอบ

ฉันมักจะเริ่มต้นด้วย DBI เพราะฉันคิดว่า "โอ้นี่เป็นโครงการง่าย ๆ ฉันไม่ต้องการ bloat ของ ORM และฉันไม่ต้องการรบกวนการตั้งค่าและโมดูล Schema" แต่เร็วมาก - เกือบทุกครั้ง - ฉันเริ่มสาปแช่งตัวเองอย่างรวดเร็วเพื่อการตัดสินใจนั้น เมื่อฉันต้องการเริ่มการสร้างสรรค์ในคิวรี SQL ของฉัน (เคียวรีแบบไดนามิกไม่ใช่แค่การเปรียบเทียบตัวยึด) ฉันพยายามรักษาสติด้วย DBI SQL :: บทคัดย่อช่วยได้มากและโดยทั่วไปก็น่าจะเพียงพอสำหรับฉัน แต่การต่อสู้ทางจิตต่อไปของฉันคือการรักษา SQL จำนวนมากไว้ในรหัส มันทำให้เสียสมาธิมากสำหรับฉันที่จะมีบรรทัดและบรรทัดของ SQL ฝังตัวอยู่ใน heredocs ที่น่าเกลียด บางทีฉันต้องใช้ IDE ที่มีคุณภาพ

ในที่สุดเวลามากกว่าฉันติดกับ DBI ตรง แต่ฉันหวังว่าจะมีวิธีที่ดีกว่า DBIx :: Class มีลักษณะที่ประณีตจริงๆและฉันเคยใช้มาสองสามครั้ง แต่มันดูเหมือนเกินความจริงสำหรับทุกคนยกเว้นโครงการที่ใหญ่ที่สุด ฉันไม่แน่ใจด้วยซ้ำว่าฉันยุ่งยากในการจัดการมากขึ้น: DBI ด้วยกระจัดกระจาย SQL หรือ DBIC ด้วยโมดูล Schema กระจัดกระจาย

(โอ้สิ่งที่ จำกัด และทริกเกอร์เป็นประโยชน์อย่างมากสำหรับฉันสำหรับ DBIC)


4
คำตอบนี้ไม่ได้มาถึงจุดดีมาก - แน่นอนคุณมีปัญหาเมื่อคุณใช้ DBIx แต่ทำไมคุณมีปัญหาเหล่านั้น DBI ไม่ยืดหยุ่นรวมกับฐานข้อมูลแน่นเกินไปไม่สามารถปรับขนาดได้หรืออะไร
Jay Elston
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.