เหตุใดจึงไม่นำมาตรฐาน SQL ANSI-92 มาใช้มากกว่า ANSI-89


107

ในทุก บริษัท ที่ฉันเคยทำงานฉันพบว่าผู้คนยังคงเขียนคำค้นหา SQL ในมาตรฐาน ANSI-89:

select a.id, b.id, b.address_1
from person a, address b
where a.id = b.id

มากกว่ามาตรฐาน ANSI-92:

select a.id, b.id, b.address_1
from person a
inner join address b
on a.id = b.id

สำหรับแบบสอบถามที่ง่ายมากเช่นนี้ความสามารถในการอ่านไม่แตกต่างกันมากนัก แต่สำหรับการสืบค้นขนาดใหญ่ฉันพบว่าการมีเกณฑ์การเข้าร่วมของฉันถูกจัดกลุ่มโดยแสดงรายการในตารางทำให้ง่ายขึ้นมากที่จะดูว่าฉันอาจมีปัญหาในการเข้าร่วมและ ขอฉันเก็บการกรองทั้งหมดไว้ใน WHERE clause ไม่ต้องพูดถึงว่าฉันรู้สึกว่าการรวมภายนอกนั้นใช้งานง่ายกว่าไวยากรณ์ (+) ใน Oracle

ขณะที่ฉันพยายามเผยแพร่ ANSI-92 ให้กับผู้คนมีประโยชน์ด้านประสิทธิภาพที่เป็นรูปธรรมในการใช้ ANSI-92 ผ่าน ANSI-89 หรือไม่? ฉันจะลองด้วยตัวเอง แต่การตั้งค่า Oracle ที่เรามีที่นี่ไม่อนุญาตให้เราใช้ EXPLAIN PLAN - ไม่ต้องการให้คนอื่นพยายามเพิ่มประสิทธิภาพโค้ดของพวกเขาใช่ไหม


7
ข้อได้เปรียบหลักอย่างหนึ่งของสัญกรณ์การรวม SQL-92 คือมีวิธีการเขียน LEFT OUTER JOIN และตัวแปรที่เป็นมาตรฐานและมีเหตุผล DBMS แต่ละตัวมีไวยากรณ์ที่แตกต่างกัน (โดยปกติจะไม่ดีจริงๆแล้วฉันคิดว่าโดยไม่มีข้อยกเว้นว่าสัญกรณ์นั้นไม่ดี) และมักจะมีความหมายที่แตกต่างกันเล็กน้อย SQL-92 ได้รับการแก้ไขและสัญกรณ์ใหม่นั้นคุ้มค่าที่จะใช้ในพื้นที่เหล่านั้นเพียงอย่างเดียว ฉันคิดว่ามันชัดเจนกว่าอยู่ดีเมื่อคุณชินแล้ว ใช้เวลาทำความคุ้นเคยเล็กน้อย แต่ก็ไม่ยากและเมื่อกลับใจใหม่แล้วจะไม่มีการย้อนกลับ
Jonathan Leffler

ความหมาย, ชีแมนติก, แอนตี้ - ชีแมนติก!
แซม

ฉันไปงานปาร์ตี้ที่นี่ช้าไปหน่อย แต่ดูเหมือนจะไม่มีใครชี้ให้เห็นว่า Oracle แนะนำให้คุณใช้ไวยากรณ์ FROM clause OUTER JOIN แทนที่จะเป็นตัวดำเนินการเข้าร่วม Oracle
bornfromanegg

ฉันได้เพิ่มคำตอบใหม่ที่ทันสมัยและตรงไปตรงมามากขึ้นโดยมีความชัดเจนเหนือความเข้าใจผิดอื่น ๆ ในคำตอบที่นี่stackoverflow.com/a/47720615/124486
Evan Carroll

คำตอบ:


77

ตาม "การปรับแต่งประสิทธิภาพ SQL" โดย Peter Gulutzan และ Trudy Pelzer จากแบรนด์ RDBMS หกหรือแปดแบรนด์ที่พวกเขาทดสอบไม่มีความแตกต่างในการเพิ่มประสิทธิภาพหรือประสิทธิภาพของ SQL-89 กับการรวมสไตล์ SQL-92 เราสามารถสันนิษฐานได้ว่าเอ็นจิน RDBMS ส่วนใหญ่แปลงไวยากรณ์เป็นการแสดงภายในก่อนที่จะปรับให้เหมาะสมหรือดำเนินการสืบค้นดังนั้นไวยากรณ์ที่มนุษย์อ่านได้จึงไม่มีความแตกต่าง

ฉันพยายามที่จะเผยแพร่ไวยากรณ์ SQL-92 ด้วย สิบหกปีหลังจากได้รับการอนุมัติก็ถึงเวลาที่ผู้คนเริ่มใช้มัน! และตอนนี้ฐานข้อมูล SQL ทุกยี่ห้อรองรับดังนั้นจึงไม่มีเหตุผลที่จะใช้(+)ไวยากรณ์ Oracle ที่ไม่เป็นมาตรฐานหรือไวยากรณ์*=ของ Microsoft / Sybase ต่อไป

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

ฉันค่อยๆเห็นผู้คนใช้ไวยากรณ์ SQL-92 บ่อยกว่าที่ฉันเคยเป็น ฉันตอบคำถาม SQL ออนไลน์มาตั้งแต่ปี 1994


6
ฉันเห็นด้วยอย่างยิ่ง ฉันทำงานร่วมกับผู้เขียนโค้ด SQL จำนวนมากที่เรียนรู้ SQL เมื่อ 15 ปีที่แล้วหรือมากกว่านั้น (เหมือนที่ฉันทำด้วยตัวเอง) และไม่รู้เรื่องนวัตกรรมใด ๆ เลยตั้งแต่เริ่มต้น พวกเขายังขาดความสนใจในการค้นหา
Tony Andrews

8
เห็นด้วย แต่เพิ่มเติมว่ามีสถานการณ์จำลองที่มีการจัดทำเอกสารไว้อย่างดีซึ่งไวยากรณ์การเข้าร่วม ANSI-89 แบบเก่าให้ผลลัพธ์ที่ไม่ถูกต้อง ... การเข้าร่วมภายนอกโดยเฉพาะเมื่อมีเพรดิเคตการกรองตามเงื่อนไขในคอลัมน์ที่ไม่เกี่ยวข้องกับการเข้าร่วมจากด้าน "ด้านนอก" ของการรวม
Charles Bretana

1
ฉันไม่รู้เฉพาะภายในของ MS SQL แต่นั่นเป็นหลักฐานที่ดีว่าไวยากรณ์ของ SQL-92 นั้นคุ้มค่า ใช้ได้ผลสำหรับฉัน!
Bill Karwin

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

2
นอกจากนี้หลักฐาน "เกร็ดเล็กเกร็ดน้อย" ก็ไม่ใช่ตัวชี้วัดทางวิทยาศาสตร์อยู่ดี มักจะถูกนำมาด้วยเกลือเม็ดเสมอ
Bill Karwin

16

มาตรฐาน ANSI092 มีไวยากรณ์ที่น่ากลัวบางอย่าง Natural Joinsเป็นอีกหนึ่งข้อและข้อใช้อีกข้อหนึ่ง IMHO การเพิ่มคอลัมน์ลงในตารางไม่ควรทำลายโค้ด แต่ NATURAL JOIN จะแตกในลักษณะที่ร้ายแรงที่สุด วิธีที่ "ดีที่สุด" ในการทำลายคือข้อผิดพลาดในการคอมไพล์ ตัวอย่างเช่นถ้าคุณเลือก * ที่ไหนสักแห่งการเพิ่มคอลัมน์อาจทำได้ไม่สามารถรวบรวม วิธีที่ดีที่สุดต่อไปในการล้มเหลวคือข้อผิดพลาดขณะทำงาน แย่กว่านั้นเพราะผู้ใช้ของคุณอาจเห็น แต่ก็ยังเตือนคุณได้ดีว่าคุณทำบางอย่างพัง หากคุณใช้ ANSI92 และเขียนคิวรีด้วยการรวม NATURAL จะไม่แตกในเวลาคอมไพล์และจะไม่หยุดทำงานเมื่อรันไทม์คิวรีจะเริ่มให้ผลลัพธ์ที่ไม่ถูกต้อง โรคจิตประเภทนี้ร้ายกาจ รายงานผิดพลาดการเปิดเผยข้อมูลทางการเงินอาจไม่ถูกต้อง

สำหรับผู้ที่ไม่คุ้นเคยกับ NATURAL Joins พวกเขารวมสองตารางกับทุกชื่อคอลัมน์ที่มีอยู่ในทั้งสองตาราง ซึ่งเจ๋งมากเมื่อคุณมีคีย์ 4 คอลัมน์และคุณเบื่อที่จะพิมพ์ ปัญหาเกิดขึ้นเมื่อ Table1 มีคอลัมน์ที่มีอยู่แล้วชื่อ DESCRIPTION และคุณเพิ่มคอลัมน์ใหม่ใน Table2 ชื่อโอ้ฉันไม่รู้บางสิ่งที่ไม่มีอันตรายเช่น mmm DESCRIPTION และตอนนี้คุณกำลังเข้าร่วมสองตารางบน VARCHAR2 (1,000) ฟิลด์ที่เป็นรูปแบบอิสระ

ประโยค USING อาจนำไปสู่ความคลุมเครือทั้งหมดนอกเหนือจากปัญหาที่อธิบายไว้ข้างต้น ในโพสต์อื่น ๆ มีคนแสดง ANSI-92 SQL นี้และขอความช่วยเหลือในการอ่าน

SELECT c.* 
FROM companies AS c 
JOIN users AS u USING(companyid) 
JOIN jobs AS j USING(userid) 
JOIN useraccounts AS us USING(userid) 
WHERE j.jobid = 123

นี่เป็นความคลุมเครืออย่างสมบูรณ์ ฉันใส่คอลัมน์ UserID ทั้งใน บริษัท และตารางผู้ใช้และไม่มีข้อร้องเรียนใด ๆ จะเกิดอะไรขึ้นถ้าคอลัมน์ UserID ใน บริษัท ต่างๆเป็น ID ของบุคคลสุดท้ายที่แก้ไขแถวนั้น

ฉันจริงจังใครช่วยอธิบายได้ไหมว่าทำไมความคลุมเครือถึงจำเป็น? เหตุใดจึงสร้างตรงตามมาตรฐาน

ฉันคิดว่า Bill ถูกต้องที่มีฐานนักพัฒนาจำนวนมากที่คัดลอก / วางผ่านการเข้ารหัส ในความเป็นจริงฉันยอมรับได้ว่าฉันเป็นคนประเภทหนึ่งเมื่อพูดถึง ANSI-92 ทุกตัวอย่างที่ฉันเคยเห็นแสดงให้เห็นการรวมหลายรายการที่ซ้อนกันอยู่ในวงเล็บ ความซื่อสัตย์ที่ทำให้การเลือกตารางใน sql ทำได้ยากที่สุด แต่จากนั้นนักพัฒนา SQL92 ได้อธิบายว่าจะบังคับให้มีคำสั่งเข้าร่วม พระเยซู ... ผู้คัดลอกทั้งหมดที่ฉันเคยเห็นตอนนี้บังคับให้เข้าร่วมคำสั่ง - งานที่ 95% ของเวลาที่เหลือดีกว่าสำหรับเครื่องมือเพิ่มประสิทธิภาพโดยเฉพาะสำเนา / paster

โตมาลักษณ์เข้าใจถูกเมื่อเขาพูดว่า

ผู้คนไม่ได้เปลี่ยนไปใช้ไวยากรณ์ใหม่เพียงเพราะมันอยู่ที่นั่น

มันต้องให้บางอย่างกับฉันและฉันไม่เห็นกลับหัว และหากมีการกลับหัวเชิงลบจะเป็นอัลบาทรอสที่มีขนาดใหญ่เกินกว่าจะละเลยได้


3
ฉันมักจะใช้เปิดเพราะมีความคลุมเครือน้อยกว่าการใช้หรือเข้าร่วมโดยธรรมชาติ สำหรับวงเล็บผู้ที่เรียนรู้ "SQL" บน Microsoft Access จะใช้สิ่งนั้นเป็น Access คร่ำครวญหากคุณละเว้น (เครื่องหมายคำพูดรอบ SQL ควรเป็นคำพูดแบบนิ้ว)
Powerlord

1
ไอใช้ประโยคคืออะไร? ;-) ฉันมาจากเศษส่วนของเซิร์ฟเวอร์ SQL ดังนั้นนี่จึงไม่ได้อยู่ในเรดาร์ของฉัน ดังที่ R.Bemrose กล่าวว่ามีคำสั่ง ON ซึ่งทำงานได้ดีไม่ทิ้งฉันไว้กับการเข้าร่วมฉันไม่สามารถแสดงออกทางวากยสัมพันธ์ได้ ไม่จำเป็นต้องปรับการออกแบบ DB ของฉันเพื่อสืบค้นไวยากรณ์เพื่อบันทึกการพิมพ์บางอย่าง
Tomalak

3
หากคุณไม่ทราบข้อมูลของคุณดีพอที่จะใช้ NATURAL JOIN หรือ USING ตามความเหมาะสมคุณอาจไม่ควรเขียน SQL ให้ -1 สำหรับความไม่รู้
Rob

4
IMHO การรวมแบบธรรมชาติตกอยู่ในกระเป๋าใบเดียวกับSELECT *(จากนั้นการค้นหาว่าลูกค้าอาศัยคำสั่งภาคสนาม) - รู้สึกเลอะเทอะเล็กน้อย
พื้นฐาน

2
ปัญหาที่คุณอธิบายด้วยการรวมแบบธรรมชาติเป็นปัญหากับการออกแบบฐานข้อมูลของคุณไม่ใช่ปัญหาเดียวกับมาตรฐาน คุณควรตระหนักถึงข้อมูลของคุณและกำหนดมาตรฐานสำหรับชื่อคอลัมน์
Travis

14

เหตุผลบางประการในใจ:

  • คนทำจนเป็นนิสัย
  • คนขี้เกียจและชอบการรวม "แบบเก่า" เพราะพวกเขามีส่วนร่วมในการพิมพ์น้อยลง
  • ผู้เริ่มต้นมักมีปัญหาในการตัดหัวของพวกเขาเกี่ยวกับไวยากรณ์การเข้าร่วม SQL-92
  • ผู้คนไม่ได้เปลี่ยนไปใช้ไวยากรณ์ใหม่เพียงเพราะมันอยู่ที่นั่น
  • ผู้คนไม่ทราบถึงประโยชน์ของไวยากรณ์ใหม่ (ถ้าคุณต้องการเรียกมันว่า) โดยหลักแล้วมันช่วยให้คุณสามารถกรองตารางก่อนที่คุณจะทำการรวมภายนอกและไม่ใช่หลังจากนั้นเมื่อสิ่งที่คุณมีคือ WHERE clause

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


3
สำหรับหลาย ๆ คนการดู SQL นั้นทำให้พวกเขาเจ็บปวด การเปลี่ยนรหัสการทำงานใด ๆ มีความเสี่ยงในการทำให้เกิดข้อบกพร่องโดยเฉพาะอย่างยิ่งเมื่อผู้เข้ารหัสหลบเลี่ยงสายตาของเขา :-)
Bill Karwin

หืม ... ถึงฉันจะดูการแสดงออกปกติที่ซับซ้อนก็ไม่เจ็บเลย SQL ไม่สามารถทำร้ายฉันได้ ;-)
Tomalak

"มือใหม่มักมีปัญหา ... " นั่นคือจุดขาย

2
ด้วยเหตุผลบางอย่างฉันไม่แน่ใจว่านั่นเป็นความคิดเห็น "โปร" หรือ "ตรงกันข้าม" ... บางทีเครื่องตรวจจับประชดของฉันอาจเสีย
Tomalak

10

เพื่อตอบสนองต่อ NATURAL JOIN และ USING โพสต์ด้านบน

ทำไมคุณถึงเห็นความจำเป็นในการใช้สิ่งเหล่านี้ - ไม่มีใน ANSI-89 และถูกเพิ่มเข้ามาสำหรับ ANSI-92 เป็นสิ่งที่ฉันเห็นเป็นทางลัดเท่านั้น

ฉันจะไม่ทิ้งการเข้าร่วมกับโอกาสและจะระบุตาราง / นามแฝงและรหัสเสมอ

สำหรับฉันวิธีเดียวที่จะไปคือ ANSI-92 เป็นคำที่ละเอียดกว่าและผู้ติดตาม ANSI-89 ไม่ชอบไวยากรณ์ แต่จะแยกการเข้าร่วมของคุณออกจากตัวกรองของคุณอย่างเรียบร้อย


ฉันไม่เห็น NATURAL JOIN เป็นทางลัด แต่เป็น Segway ในการเขียนโปรแกรม Object Oriented DB ภายใน Relational DB
Armand

5

ก่อนอื่นให้ฉันบอกว่าใน SQL Server ไวยากรณ์การรวมภายนอก (* =) ไม่ได้ให้ผลลัพธ์ที่ถูกต้องตลอดเวลา มีหลายครั้งที่ตีความว่าเป็นการรวมแบบไขว้ไม่ใช่การรวมภายนอก มีเหตุผลที่ดีที่จะหยุดใช้ และไวยากรณ์การรวมภายนอกนั้นเป็นคุณลักษณะที่เลิกใช้แล้วและจะไม่อยู่ใน SQL Server เวอร์ชันถัดไปหลังจาก SQL Server 2008 คุณจะยังคงสามารถทำการรวมภายในได้ แต่ทำไมทุกคนถึงต้องการบนโลกนี้? ไม่มีความชัดเจนและดูแลรักษายากกว่ามาก คุณไม่สามารถรู้ได้อย่างง่ายดายว่าอะไรเป็นส่วนหนึ่งของการเข้าร่วมและอะไรเป็นเพียงส่วนคำสั่งที่แท้จริง

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

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


1
ดีใจที่ได้เจอ. ยินดีที่ได้เป็นคนแรกของคุณ

4

ฉันได้รับการสอน ANSI-89 ในโรงเรียนและทำงานในอุตสาหกรรมเพียงไม่กี่ปี จากนั้นฉันก็ออกจากโลกที่สวยงามของ DBMS เป็นเวลา 8 ปี แต่แล้วฉันก็กลับมาและสิ่งใหม่นี้กำลังสอน ANSI 92 ฉันได้เรียนรู้ไวยากรณ์ Join On แล้วและตอนนี้ฉันสอน SQL แล้วและฉันขอแนะนำไวยากรณ์ JOIN ON ใหม่

แต่ข้อเสียที่ฉันเห็นคือการสืบค้นย่อยที่สัมพันธ์กันดูเหมือนจะไม่สมเหตุสมผลในแง่ของการรวม ANSI 92 เมื่อข้อมูลการเข้าร่วมถูกรวมไว้ใน WHERE และเคียวรีย่อยที่สัมพันธ์กันจะ "เข้าร่วม" ใน WHERE ทั้งหมดดูเหมือนถูกต้องและสอดคล้องกัน ในเกณฑ์การรวมตาราง ANSI 92 ไม่ได้อยู่ใน WHERE และเคียวรีย่อย "join" คือไวยากรณ์ดูเหมือนไม่สอดคล้องกัน ในทางกลับกันการพยายาม "แก้ไข" ความไม่ลงรอยกันนี้อาจทำให้แย่ลง


ในทางกลับกันคุณ [robaly shoudl ไม่ได้เขียนเคียวรีย่อยที่สัมพันธ์กันเลยเนื่องจากเป็น hogs perrformance พวกเขาเหมือนกับการวางเคอร์เซอร์ไว้ในแบบสอบถามของคุณ ฮึ.
HLGEM

3

ฉันไม่รู้คำตอบแน่นอน .. นี่คือสงครามศาสนา (มีระดับน้อยกว่า Mac-Pc หรืออื่น ๆ )

การคาดเดาก็คือจนกระทั่งเมื่อไม่นานมานี้ Oracle (และอาจเป็นผู้ขายรายอื่นด้วย) ไม่ได้ใช้มาตรฐาน ANSI-92 (ฉันคิดว่ามันอยู่ใน Oracle v9 หรือในนั้น) ดังนั้นสำหรับ DBAs / Db Developers ที่ทำงานใน บริษัท ต่างๆ ยังคงใช้เวอร์ชันเหล่านี้อยู่ (หรือต้องการให้โค้ดพกพาข้ามเซิร์ฟเวอร์ที่อาจใช้เวอร์ชันเหล่านี้อยู่ก็ต้องยึดตามมาตรฐานเดิม ...

เป็นเรื่องที่น่าเสียดายจริงๆเพราะไวยากรณ์การรวมแบบใหม่นั้นอ่านได้ง่ายกว่ามากและไวยากรณ์แบบเก่าสร้างผลลัพธ์ที่ผิด (ไม่ถูกต้อง) ในสถานการณ์ที่มีการจัดทำเอกสารไว้อย่างดีหลายประการ

  • โดยเฉพาะการเข้าร่วมภายนอกเมื่อมีเพรดิเคตการกรองตามเงื่อนไขในคอลัมน์ที่ไม่เกี่ยวข้องกับการเข้าร่วมจากตารางที่ด้าน "ด้านนอก" ของการรวม

ใช่ Oracle 9i; เปิดตัวในปี 2544 สายไปหน่อย!

1
MS SQL เพิ่มINNER JOINในปี 1995 แม้ว่าจะLEFT JOINไม่ถึงปี 2539 ก็ตามMySQL ได้สนับสนุนอย่างน้อยตั้งแต่ 3.23 เปิดตัวในปี 2542 PostgreSQL อย่างน้อยตั้งแต่ 7.2 เปิดตัวในปี 2002 Googling แบบสบาย ๆ บางตัวไม่ให้คำตอบสำหรับ Teradata

ใช่นั่นคือการประณามซึ่งพิสูจน์ความเหนือกว่าของ Oracle ในปี 1991: ระบบฐานข้อมูลเช่นการเข้าถึง MS ซึ่งใช้ไวยากรณ์ "ซ้าย" และ "ขวา" ไม่ใช่ SQL มาตรฐาน ANSI การโพสต์ SQL แบบนั้นเป็นโอกาสที่คนอื่นจะเยาะเย้ยคุณ ชนิดเช่น twitter และ facebook ในขณะนี้
david

2

ความเฉื่อยและการปฏิบัติจริง

ANSI-92 SQL ก็เหมือนกับการพิมพ์สัมผัส ในทางทฤษฎีบางอย่างมันอาจทำให้ทุกอย่างดีขึ้นในสักวันหนึ่ง แต่ตอนนี้ฉันสามารถพิมพ์ได้เร็วขึ้นมากโดยมองไปที่ปุ่มด้วยสี่นิ้ว ฉันจะต้องถอยหลังเพื่อที่จะไปข้างหน้าโดยไม่มีการรับประกันว่าจะไม่มีการจ่ายเงิน

การเขียน SQL เป็นเรื่องเกี่ยวกับ 10% ของงานของฉัน ถ้าฉันต้องการ ANSI-92 SQL เพื่อแก้ปัญหาที่ ANSI-89 SQL ไม่สามารถแก้ไขได้ฉันจะใช้มัน (อันที่จริงฉันใช้มันใน Access) ถ้าใช้ตลอดเวลาจะช่วยให้ฉันแก้ปัญหาที่มีอยู่ได้เร็วขึ้นฉันจะใช้เวลาในการดูดซึมมัน แต่ฉันสามารถแส้ ANSI-89 SQL ได้โดยไม่ต้องคิดเกี่ยวกับไวยากรณ์ ฉันได้รับเงินเพื่อแก้ปัญหา - การคิดเกี่ยวกับไวยากรณ์ SQL ทำให้เสียเวลาและเงินของนายจ้าง

สักวันตั๊กแตนหนุ่มคุณจะปกป้องการใช้ไวยากรณ์ ANSI-92 SQL กับคนหนุ่มสาวที่บ่นว่าคุณควรใช้ SQL3 (หรืออะไรก็ตาม) แล้วคุณจะเข้าใจ :-)


2
วิธีการที่อธิบายไว้ในที่นี้ฟังดูคล้ายกับ "แก้ไขเมื่อมันแตก" โรงเรียนแห่งความคิดซึ่งเป็นการละทิ้งแนวคิดในการบำรุงรักษาเชิงป้องกัน คุณจะได้รับเงินเพื่อแก้ปัญหาใช่ แต่คุณยังได้รับเงินเพื่อเพิ่มมูลค่าให้กับ บริษัท ของคุณ ANSI-89 ในกรณีของคุณให้คุณค่ามากกว่าในระยะสั้น แต่ในระยะยาวการไม่ลงทุนเวลาใน ANSI-92 จะเป็นตัวเลือกที่แพงกว่า
Travis

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

ฉันจะไม่เปลี่ยนไปใช้ Excel (ซึ่งคุณสามารถทำอะไรก็ได้ด้วยการคลิกเมาส์สามครั้งหรือน้อยกว่านั้น) เพราะฉันจำคำสั่ง Lotus 123 หลายพันคำที่ฉันต้องการได้และฉันก็สบายใจที่จะใช้มัน! ห๊ะ!
Charles Bretana

2

ฉันมีแบบสอบถามที่เขียนขึ้นสำหรับ SQL Server 6.5 ซึ่งไม่รองรับไวยากรณ์การเข้าร่วม SQL 92 นั่นคือ

select foo.baz
from foo
  left outer join bar
  on foo.a = bar.a

ถูกเขียนแทนเป็น

select foo.baz
from foo, bar
where foo.a *= bar.a

การสืบค้นได้ดำเนินการมาระยะหนึ่งแล้วและข้อมูลที่เกี่ยวข้องได้สะสมจนทำให้การสืบค้นทำงานช้าเกินไปใช้เวลาประมาณ 90 วินาทีในการดำเนินการให้เสร็จสมบูรณ์ เมื่อเกิดปัญหานี้เราได้อัปเกรดเป็น SQL Server 7

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

มีเหตุผลที่ดีในการเปลี่ยน

โพสต์ใหม่จากที่นี่


1

ฉันสามารถตอบได้จากมุมมองของนักพัฒนาทั่วไปโดยรู้ว่ามี SQL เพียงพอที่จะเข้าใจไวยากรณ์ทั้งสอง แต่ยังคงใช้ไวยากรณ์ที่แน่นอนของการแทรกทุกครั้งที่ฉันต้องการ ... :-P (ฉันไม่ได้ทำ SQL ทั้งวัน เพียงแก้ไขปัญหาบางครั้งเป็นครั้งคราว)

อันที่จริงฉันพบว่ารูปแบบแรกใช้งานง่ายกว่าโดยไม่มีลำดับชั้นที่ชัดเจนระหว่างสองตาราง ความจริงที่ฉันเรียนรู้ SQL ด้วยหนังสือเก่าอาจแสดงรูปแบบแรกอาจไม่ช่วย ... ;-)
และการอ้างอิงครั้งแรกที่ฉันพบในการค้นหาsql selectใน Google (ซึ่งส่งคืนคำตอบภาษาฝรั่งเศสเป็นส่วนใหญ่สำหรับฉัน ... ) ก่อนอื่นจะแสดงรูปแบบเก่า (จากนั้นอธิบายรูปแบบที่สอง)

เพียงแค่ให้คำแนะนำเกี่ยวกับคำถาม "ทำไม" ... ^ _ ^ ฉันควรอ่านหนังสือที่ดีและทันสมัย ​​(DB ไม่เชื่อเรื่องพระเจ้า) ในหัวข้อนี้ หากใครมีข้อเสนอแนะ ...


1

ฉันไม่สามารถพูดได้สำหรับทุกโรงเรียน แต่ที่มหาวิทยาลัยของฉันตอนที่เราทำโมดูล SQL ของหลักสูตรของเราพวกเขาไม่ได้สอน ANSI-92 พวกเขาสอน ANSI-89 - บนระบบ VAX แบบเก่าที่นั่น! ฉันไม่ได้สัมผัสกับ ANSI-92 จนกว่าฉันจะเริ่มขุดค้นใน Access โดยสร้างแบบสอบถามโดยใช้ตัวออกแบบแบบสอบถามจากนั้นขุดลงในโค้ด SQL เมื่อตระหนักว่าฉันไม่รู้ว่ามันเสร็จสิ้นการรวมหรือความหมายของไวยากรณ์ฉันเริ่มขุดลึกลงไปเพื่อที่ฉันจะได้เข้าใจ

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

แน่นอนว่ามีผู้เผยแพร่ศาสนาทางเทคนิคที่ชอบคนจรจัดและเข้าใจและมักจะเป็นคนประเภทที่ใช้หลักการ "ใหม่กว่า" และพยายามเปลี่ยนคนอื่น ๆ

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

แน่นอนนั่นเป็นเพียงความคิดเห็นของฉันจากประสบการณ์ของฉัน


ไม่ใช่แค่โปรแกรมเมอร์เท่านั้น ในหลาย ๆ สาขามันยากที่จะโน้มน้าวให้ผู้คนกลับมาฝึกใหม่เมื่อพวกเขามีความมั่นคงในอาชีพการงาน มีบุคคลที่โดดเด่นแน่นอนฉันถือว่าในสัดส่วนเดียวกันในทุกสาขา
Bill Karwin

2
เป็นการยากที่จะโน้มน้าวให้ใครบางคนเปลี่ยนจากสิ่งที่ประสบความสำเร็จไปสู่สิ่งที่แตกต่างซึ่งไม่มีประโยชน์ . net ข้างบ้านของเราเปลี่ยนจาก 1.0 เป็น 3.5 และแต่ละขั้นตอนจะอยู่ระหว่างด้วย ZERO cajoling แต่ละเวอร์ชันใหม่ดีกว่า ไม่สามารถพูดเช่นเดียวกันที่นี่

1

1) วิธีมาตรฐานในการเขียน OUTER JOIN เทียบกับ * = หรือ (+) =

2) เข้าร่วมตามธรรมชาติ

3) ขึ้นอยู่กับเครื่องมือฐานข้อมูลแนวโน้ม ANSI-92 จะดีที่สุด

4) การเพิ่มประสิทธิภาพด้วยตนเอง:

สมมติว่าเรามีไวยากรณ์ถัดไป (ANSI-89):

(1)select * from TABLE_OFFICES to,BIG_TABLE_USERS btu
where to.iduser=tbu.iduser and to.idoffice=1

สามารถเขียนได้ว่า:

(2)select * from TABLE_OFFICES to
inner join BIG_TABLE_USERS btu on to.iduser=tbu.iduser
where to.idoffice=1

แต่ยังเป็น:

(3)select * from TABLE_OFFICES to
inner join BIG_TABLE_USERS btu on to.iduser=tbu.iduser and to.idoffice=1

ทั้งหมด (1), (2), (3) ส่งคืนผลลัพธ์เดียวกันอย่างไรก็ตามได้รับการปรับให้เหมาะสมแตกต่างกันขึ้นอยู่กับเครื่องมือฐานข้อมูล แต่ส่วนใหญ่ทำ:

  • (1) ขึ้นอยู่กับกลไกจัดการฐานข้อมูลตัดสินใจการเพิ่มประสิทธิภาพ
  • (2) รวมทั้งสองตารางจากนั้นกรองต่อสำนักงาน
  • (3) จะกรอง BIG_TABLE_USERS โดยใช้ idoffice จากนั้นเข้าร่วมทั้งสองตาราง

5) ข้อความค้นหาที่ยาวขึ้นจะยุ่งน้อยลง


1

เหตุผลที่ผู้คนใช้ ANSI-89 จากประสบการณ์จริงของฉันกับโปรแกรมเมอร์รุ่นเก่าและเด็กและผู้ฝึกงานและผู้สำเร็จการศึกษาใหม่:

  • พวกเขาเรียนรู้ SQL จากโค้ดที่มีอยู่ที่เห็น (แทนที่จะเป็นหนังสือ) และเรียนรู้ ANSI-89 จากโค้ด
  • ANSI-89 เนื่องจากพิมพ์น้อย
  • พวกเขาไม่คิดเกี่ยวกับเรื่องนี้และใช้รูปแบบเดียวหรือแบบอื่นและไม่รู้ด้วยซ้ำว่าทั้งสองแบบถือว่าใหม่หรือเก่าและไม่สนใจอย่างใดอย่างหนึ่ง
  • ความคิดที่ว่ารหัสยังเป็นการสื่อสารไปยังโปรแกรมเมอร์คนถัดไปที่มาพร้อมกับการรักษารหัสนั้นไม่มีอยู่จริง พวกเขาคิดว่าพวกเขาคุยกับคอมพิวเตอร์และคอมพิวเตอร์ไม่สนใจ
  • ไม่รู้จักศิลปะของ "การเข้ารหัสที่สะอาด"
  • ความรู้เกี่ยวกับภาษาโปรแกรมและ SQL โดยเฉพาะนั้นแย่มากจนคัดลอกและวางสิ่งที่พบจากที่อื่นเข้าด้วยกัน
  • ความชอบส่วนบุคคล

โดยส่วนตัวแล้วฉันชอบ ANSI-92 และเปลี่ยนทุกการสืบค้นที่ฉันเห็นในไวยากรณ์ ANSI-89 บางครั้งเพื่อให้เข้าใจคำสั่ง SQL ในมือได้ดีขึ้น แต่ฉันตระหนักว่าคนส่วนใหญ่ที่ฉันทำงานด้วยไม่ชำนาญพอที่จะเขียนการเชื่อมต่อในหลาย ๆ ตาราง พวกเขาเขียนโค้ดให้ดีที่สุดเท่าที่จะทำได้และใช้สิ่งที่จำได้ในครั้งแรกที่พบคำสั่ง SQL


1

ต่อไปนี้เป็นจุดเปรียบเทียบ SQL-89 และ SQL-92 และการล้างความเข้าใจผิดในคำตอบอื่น ๆ

  1. NATURAL JOINSเป็นความคิดที่น่ากลัว โดยนัยและต้องการข้อมูลเมตาเกี่ยวกับตาราง ไม่มีอะไรเกี่ยวกับ SQL-92 ต้องใช้ของพวกเขาดังนั้นเพียงแค่ไม่สนใจพวกเขา ไม่เกี่ยวข้องกับการสนทนานี้
  2. USING เป็นความคิดที่ดีมีผลสองอย่าง:
    1. สร้างเพียงคอลัมน์เดียวในชุดผลลัพธ์จาก Equijoin
    2. มันบังคับใช้หลักการที่ดีและมีเหตุผล ใน SQL-89 คุณมีคนเขียนคอลัมน์idบนทั้งสองตาราง หลังจากที่คุณเข้าร่วมตารางแล้วสิ่งนี้จะกลายเป็นความคลุมเครือและต้องใช้นามแฝงอย่างชัดเจน นอกจากนี้idการเข้าร่วมเกือบจะมีข้อมูลที่แตกต่างกันอย่างแน่นอน หากคุณรวมบุคคลเข้ากับ บริษัท ตอนนี้คุณต้องใช้นามแฝงแบบหนึ่งidถึงperson_idหนึ่งและหนึ่งidต่อcompany_idโดยที่การเข้าร่วมจะทำให้เกิดคอลัมน์สองคอลัมน์ที่ไม่ชัดเจน USINGการใช้ตัวบ่งชี้ที่ไม่ซ้ำกันทั่วโลกสำหรับคีย์ตัวแทนของตารางที่มีการประชุมผลตอบแทนมาตรฐานที่มี
  3. สร้าง SQL-89 CROSS JOINไวยากรณ์เป็นนัย A CROSS JOINไม่ได้ลดการตั้งค่า แต่จะทำให้มันเติบโตโดยปริยาย FROM T1,T2เหมือนกับFROM T1 CROSS JOIN T2ที่สร้างการรวมคาร์ทีเซียนซึ่งมักจะไม่ใช่สิ่งที่คุณต้องการ การมีหัวกะทิเพื่อลดสิ่งนั้นออกไปให้มีWHEREเงื่อนไขที่ห่างไกลหมายความว่าคุณมีแนวโน้มที่จะทำผิดพลาดในระหว่างการออกแบบ
  4. SQL-89 ,และ SQL-92 Explicit JOINs มีความสำคัญต่างกัน JOINมีความสำคัญสูงกว่า ยิ่งไปกว่านั้นฐานข้อมูลบางอย่างเช่น MySQL ผิดพลาดเป็นเวลานานมาก . ดังนั้นการผสมทั้งสองสไตล์จึงเป็นความคิดที่ไม่ดีและสไตล์ที่ได้รับความนิยมมากในปัจจุบันคือสไตล์ SQL-92

1) หากคุณศึกษาแบบจำลองเชิงสัมพันธ์คุณจะประทับใจกับสิ่งนั้นไม่เพียง แต่เป็นการเข้าร่วมกับแนวคิดที่ยอดเยี่ยมเท่านั้น แต่ยังเป็นการเข้าร่วมประเภทเดียวที่คุณต้องการ 2) ดู 1 เช่นไม่จำเป็น 3) โดยไม่คำนึงถึงไวยากรณ์ (และทั้งสองเป็นไวยากรณ์ SQL-92) ตัวดำเนินการเชิงสัมพันธ์คือผลิตภัณฑ์ (คูณ) กล่าวคือไม่ใช่การเข้าร่วมจริงๆ (การรวมคาร์ทีเซียน 'ไม่ใช่สิ่งเดียว) 4. ดู 1 เช่นไม่จำเป็น
60

0

Oracle ไม่ได้ใช้ ANSI-92 เลย ฉันมีปัญหาหลายอย่างไม่น้อยเพราะตารางข้อมูลใน Oracle Apps มีคอลัมน์เป็นอย่างดี หากจำนวนคอลัมน์ในการรวมของคุณเกินประมาณ 1,050 คอลัมน์ (ซึ่งทำได้ง่ายมากในแอพ) คุณจะได้รับข้อผิดพลาดปลอมซึ่งไม่สมเหตุสมผลเลย:

ORA-01445: cannot select ROWID from a join view without a key-preserved table.

การเขียนแบบสอบถามใหม่เพื่อใช้ไวยากรณ์การเข้าร่วมแบบเก่าทำให้ปัญหาหายไปซึ่งดูเหมือนว่าจะชี้ให้เห็นถึงการตำหนิอย่างเต็มที่ในการใช้การรวม ANSI-92

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

อย่างไรก็ตามตอนนี้ฉันพบว่ามันยากกว่ามากที่จะยืนยันในเรื่องนี้ พวกเขาชี้ไปที่การใช้งานที่ไม่ดีของ Oracle และพูดว่า "เราจะทำในแบบของเราขอบคุณ"


1
อาจเป็นเรื่องง่ายที่จะทำ Cross Join แต่ก็เป็นสิ่งที่ไม่ได้เกิดขึ้นเองและไม่คลุมเครืออย่างแน่นอน นักพัฒนา SQL ที่เหมาะสมทุกคนสามารถมองเห็นได้ แต่การใช้และเข้าร่วมโดยธรรมชาติเป็นสิ่งล่อใจที่เรียกร้องให้คุณและทุบเรือลำเล็กของคุณบนโขดหินแห่งความปวดร้าวและความทุกข์ยาก

1
ประเด็นของฉันคือมันง่ายกว่าที่จะสร้างการรวมข้ามโดยไม่ตั้งใจให้สำเร็จโดยพลาดตำแหน่งที่อนุประโยคที่รวมสองตารางเข้าด้วยกัน การเข้าร่วมข้ามจะต้องพิจารณาใน ANSI-92 แต่ฉันยอมรับว่า NATURAL JOIN เป็นสิ่งที่น่ารังเกียจ :)
โจนาธาน

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

0

มาตรฐาน SQL ใหม่สืบทอดทุกอย่างจากมาตรฐานก่อนหน้านี้หรือที่เรียกว่า 'ห่วงแห่งความเข้ากันได้' ดังนั้นรูปแบบการเข้าร่วม 'old' / 'comma-Separated' / 'unqualified' จึงเป็นระบบ SQL-92 ที่ถูกต้องอย่างสมบูรณ์

ตอนนี้ฉันยืนยันว่า SQL-92 NATURAL JOINเป็นเพียงการเข้าร่วมที่คุณต้องการ ตัวอย่างเช่นฉันยืนยันว่ามันดีกว่าinner joinเพราะมันไม่สร้างคอลัมน์ที่ซ้ำกัน - ไม่มีตัวแปรช่วงในส่วนSELECTคำสั่งอีกต่อไปเพื่อทำให้คอลัมน์ไม่ชัดเจน! แต่ฉันไม่สามารถคาดหวังว่าจะเปลี่ยนใจและความคิดทุกอย่างได้ดังนั้นฉันจึงต้องทำงานร่วมกับนักเขียนโค้ดที่จะนำสิ่งที่ฉันคิดว่าเป็นรูปแบบการเข้าร่วมแบบดั้งเดิมมาใช้ต่อไป (และอาจอ้างถึงตัวแปรช่วงเป็น 'นามแฝง'!) นี่คือลักษณะของการทำงานเป็นทีมและไม่ได้ทำงานในสุญญากาศ

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

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