ก่อนที่ฉันจะตอบคำถามฉันคิดว่าพื้นหลังบางอย่างอยู่ในระเบียบ
แก่นแท้ของปัญหา
หลังจากสัมภาษณ์และจ้างนักพัฒนามาหลายปีฉันได้เรียนรู้สองสิ่ง:
นักพัฒนาส่วนใหญ่มีประสบการณ์น้อยมากในการออกแบบฐานข้อมูล
ฉันสังเกตเห็นความสัมพันธ์ที่หลวมระหว่างผู้ที่ไม่เข้าใจฐานข้อมูลและผู้ที่เกลียดชัง 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 ส่วนใหญ่:
อย่ารั่วสิ่งที่เป็นนามธรรม
เขียนแบบทดสอบที่ถูกสาป
รู้วิธีเลื่อนลงไปที่ SQL ได้ตามต้องการ
เรียนรู้วิธีทำให้ฐานข้อมูลเป็นมาตรฐาน
DBIx::Class
เมื่อคุณเรียนรู้แล้วจะช่วยดูแลการยกของหนักของคุณและทำให้การเขียนแอปพลิเคชั่นเป็นไปอย่างรวดเร็ว