คุณจะไม่เขียนแอปพลิเคชันที่มีฟังก์ชันยาว 200 บรรทัด คุณจะแยกย่อยฟังก์ชันยาวเหล่านั้นออกเป็นฟังก์ชันย่อย ๆ โดยแต่ละฟังก์ชันมีความรับผิดชอบที่กำหนดไว้อย่างชัดเจนเพียงอย่างเดียว
ทำไมต้องเขียน SQL ของคุณแบบนั้น?
ย่อยสลายคำค้นหาของคุณเช่นเดียวกับที่คุณย่อยสลายฟังก์ชันของคุณ สิ่งนี้ทำให้สั้นลงง่ายขึ้นเข้าใจง่ายขึ้นทดสอบง่ายขึ้นง่ายต่อการ refactor และช่วยให้คุณสามารถเพิ่ม "shims" ระหว่างพวกมันและ "wrapper" รอบ ๆ พวกมันได้เช่นเดียวกับที่คุณทำในโค้ดขั้นตอน
คุณจะทำอย่างไร? การทำให้สิ่งสำคัญแต่ละอย่างที่แบบสอบถามทำในมุมมอง จากนั้นคุณจะเขียนข้อความค้นหาที่ซับซ้อนมากขึ้นจากมุมมองที่ง่ายกว่านี้เช่นเดียวกับที่คุณเขียนฟังก์ชันที่ซับซ้อนขึ้นจากฟังก์ชันดั้งเดิมมากขึ้น
และสิ่งที่ยอดเยี่ยมคือสำหรับการจัดองค์ประกอบภาพส่วนใหญ่คุณจะได้รับประสิทธิภาพที่เท่ากันทุกประการจาก RDBMS ของคุณ (สำหรับบางคนคุณจะไม่ทำอะไรการเพิ่มประสิทธิภาพก่อนวัยอันควรเป็นรากเหง้าของความชั่วร้ายทั้งหมดตั้งรหัสให้ถูกต้องก่อนจากนั้นจึงเพิ่มประสิทธิภาพหากคุณต้องการ)
นี่คือตัวอย่างของการใช้หลายมุมมองเพื่อแยกการสืบค้นที่ซับซ้อน
ในตัวอย่างเนื่องจากแต่ละมุมมองเพิ่มการเปลี่ยนแปลงเพียงรายการเดียวแต่ละมุมมองสามารถทดสอบได้อย่างอิสระเพื่อค้นหาข้อผิดพลาดและการทดสอบก็ง่าย
นี่คือตารางฐานในตัวอย่าง:
create table month_value(
eid int not null, month int, year int, value int );
ตารางนี้มีข้อบกพร่องเนื่องจากใช้สองคอลัมน์เดือนและปีเพื่อแสดงข้อมูลหนึ่งรายการซึ่งเป็นเดือนที่แน่นอน นี่คือข้อกำหนดของเราสำหรับคอลัมน์จากการคำนวณใหม่:
เราจะทำเช่นนั้นเป็นการแปลงเชิงเส้นเพื่อให้มันเรียงลำดับเช่นเดียวกับ (ปีเดือน) และสำหรับทูเปิล (ปีเดือน) ใด ๆ จะมีค่าเดียวและค่าทั้งหมดต่อเนื่องกัน:
create view cm_absolute_month as
select *, year * 12 + month as absolute_month from month_value;
ตอนนี้สิ่งที่เราต้องทดสอบนั้นมีอยู่ในสเป็คของเรากล่าวคือสำหรับทูเพิลใด ๆ (ปีเดือน) มีหนึ่งและเพียงหนึ่ง (เดือนสัมบูรณ์) และ (absolute_month) ที่ต่อเนื่องกัน มาเขียนแบบทดสอบกัน
การทดสอบของเราจะเป็นselect
แบบสอบถามSQL โดยมีโครงสร้างดังต่อไปนี้: ชื่อการทดสอบและคำสั่งกรณีที่รวมเข้าด้วยกัน ชื่อการทดสอบเป็นเพียงสตริงที่กำหนดเอง คำสั่งกรณีที่เป็นเพียงงบการทดสอบcase when
then 'passed' else 'failed' end
คำสั่งทดสอบจะเป็นเพียง SQL เลือก (เคียวรีย่อย) ที่ต้องเป็นจริงเพื่อให้การทดสอบผ่าน
นี่เป็นการทดสอบครั้งแรกของเรา:
--a select statement that catenates the test name and the case statement
select concat(
-- the test name
'For every (year, month) there is one and only one (absolute_month): ',
-- the case statement
case when
-- one or more subqueries
-- in this case, an expected value and an actual value
-- that must be equal for the test to pass
( select count(distinct year, month) from month_value)
--expected value,
= ( select count(distinct absolute_month) from cm_absolute_month)
-- actual value
-- the then and else branches of the case statement
then 'passed' else 'failed' end
-- close the concat function and terminate the query
);
-- test result.
การเรียกใช้แบบสอบถามนั้นก่อให้เกิดผลลัพธ์นี้: For every (year, month) there is one and only one (absolute_month): passed
ตราบใดที่มีข้อมูลการทดสอบเพียงพอใน month_value การทดสอบนี้ก็ใช้ได้
เราสามารถเพิ่มการทดสอบสำหรับข้อมูลการทดสอบที่เพียงพอได้เช่นกัน:
select concat( 'Sufficient and sufficiently varied month_value test data: ',
case when
( select count(distinct year, month) from month_value) > 10
and ( select count(distinct year) from month_value) > 3
and ... more tests
then 'passed' else 'failed' end );
ตอนนี้เรามาทดสอบต่อเนื่องกัน:
select concat( '(absolute_month)s are consecutive: ',
case when ( select count(*) from cm_absolute_month a join cm_absolute_month b
on ( (a.month + 1 = b.month and a.year = b.year)
or (a.month = 12 and b.month = 1 and a.year + 1 = b.year) )
where a.absolute_month + 1 <> b.absolute_month ) = 0
then 'passed' else 'failed' end );
ตอนนี้เรามาทำการทดสอบของเราซึ่งเป็นเพียงแบบสอบถามลงในไฟล์และเรียกใช้สคริปต์นั้นกับฐานข้อมูล อันที่จริงถ้าเราเก็บนิยามมุมมองของเราไว้ในสคริปต์ (หรือสคริปต์ฉันขอแนะนำให้เรียกใช้หนึ่งไฟล์ต่อมุมมองที่เกี่ยวข้อง) เพื่อรันกับฐานข้อมูลเราสามารถเพิ่มการทดสอบของเราสำหรับแต่ละมุมมองลงในสคริปต์เดียวกันเพื่อให้การกระทำของ (re -) การสร้างมุมมองของเรายังเรียกใช้การทดสอบของมุมมอง ด้วยวิธีนี้เราทั้งคู่จะได้รับการทดสอบการถดถอยเมื่อเราสร้างมุมมองใหม่และเมื่อการสร้างมุมมองทำงานเทียบกับการผลิตมุมมองจะถูกทดสอบในการผลิตด้วย