Tại sao tiêu chuẩn SQL ANSI-92 không được áp dụng tốt hơn ANSI-89?


107

Tại mọi công ty tôi đã làm việc, tôi nhận thấy rằng mọi người vẫn đang viết các truy vấn SQL của họ theo tiêu chuẩn ANSI-89:

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

thay vì tiêu chuẩn ANSI-92:

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

Đối với một truy vấn cực kỳ đơn giản như thế này, không có sự khác biệt lớn về khả năng đọc, nhưng đối với các truy vấn lớn, tôi thấy rằng việc nhóm các tiêu chí tham gia của tôi với liệt kê ra bảng giúp dễ dàng hơn nhiều để xem nơi tôi có thể gặp vấn đề trong tham gia của mình và hãy để tôi giữ tất cả lọc của tôi trong mệnh đề WHERE của tôi. Chưa kể rằng tôi cảm thấy rằng các phép nối bên ngoài trực quan hơn nhiều so với cú pháp (+) trong Oracle.

Khi tôi cố gắng truyền bá ANSI-92 cho mọi người, có bất kỳ lợi ích hiệu suất cụ thể nào khi sử dụng ANSI-92 hơn ANSI-89 không? Tôi sẽ tự mình thử nó, nhưng các thiết lập Oracle mà chúng tôi có ở đây không cho phép chúng tôi sử dụng KẾ HOẠCH GIẢI THÍCH - sẽ không muốn mọi người cố gắng tối ưu hóa mã của họ, phải không?


7
Một ưu điểm chính của ký hiệu nối SQL-92 là có một cách viết chuẩn và tương đối lành mạnh để viết LEFT OUTER JOIN và các biến thể. Mỗi DBMS có cú pháp biến thể riêng của nó (thường là xấu; thực ra, tôi nghĩ, không có ngoại lệ, các ký hiệu là xấu) và thường có ngữ nghĩa hơi khác nhau. SQL-92 đã khắc phục điều đó và ký hiệu mới đáng sử dụng chỉ dựa trên những cơ sở đó. Tôi nghĩ nó rõ ràng hơn dù sao, một khi bạn đã quen với nó. Phải mất một chút thời gian để làm quen, nhưng nó không khó và một khi đã chuyển đổi, sẽ không quay lại.
Jonathan Leffler

ngữ nghĩa, shemantics, anti-shemantics!
Sam

Tôi là một chút muộn để đảng ở đây, nhưng không ai dường như đã chỉ ra rằng Oracle mình khuyên bạn nên sử dụng mệnh đề FROM OUTER JOIN Cú pháp chứ không phải là Oracle tham gia điều hành
bornfromanegg

Tôi đã thêm một câu trả lời mới đó là rất nhiều cập nhật và đơn giản, với độ rõ nét qua quan niệm sai lầm khác trong các câu trả lời ở đây stackoverflow.com/a/47720615/124486
Evan Carroll

Câu trả lời:


77

Theo "Điều chỉnh hiệu suất SQL" của Peter Gulutzan và Trudy Pelzer, trong số sáu hoặc tám thương hiệu RDBMS mà họ đã thử nghiệm, không có sự khác biệt về tối ưu hóa hoặc hiệu suất của SQL-89 so với các phép nối kiểu SQL-92. Người ta có thể giả định rằng hầu hết các công cụ RDBMS chuyển đổi cú pháp thành một đại diện bên trong trước khi tối ưu hóa hoặc thực thi truy vấn, vì vậy cú pháp có thể đọc được của con người không có gì khác biệt.

Tôi cũng cố gắng truyền bá cú pháp SQL-92. Mười sáu năm sau khi nó được phê duyệt, đã đến lúc mọi người bắt đầu sử dụng nó! Và tất cả các thương hiệu của cơ sở dữ liệu SQL hiện đều hỗ trợ nó, vì vậy không có lý do gì để tiếp tục sử dụng (+)cú pháp Oracle không chuẩn hoặc cú pháp *=Microsoft / Sybase.

Về lý do tại sao rất khó để phá bỏ thói quen SQL-89 của cộng đồng nhà phát triển, tôi chỉ có thể giả định rằng có một "cơ sở kim tự tháp" lớn của các lập trình viên viết mã bằng cách sao chép và dán, sử dụng các ví dụ cổ xưa từ sách, bài báo trên tạp chí hoặc cơ sở mã khác, và những người này không học cú pháp mới một cách trừu tượng. Một số người học theo mẫu, và một số người học vẹt.

Mặc dù vậy, tôi đang dần thấy mọi người sử dụng cú pháp SQL-92 thường xuyên hơn tôi trước đây. Tôi đã trả lời các câu hỏi SQL trực tuyến từ năm 1994.


6
Tôi hoàn toàn đồng ý. Tôi làm việc với nhiều lập trình viên SQL, những người đã học SQL của họ cách đây 15 năm hoặc hơn (như chính tôi đã làm) và những người không biết gì về bất kỳ sự đổi mới nào kể từ khi họ bắt đầu. Họ cũng không quan tâm đến việc tìm hiểu.
Tony Andrews

8
Đồng ý, nhưng hãy nói thêm rằng có những tình huống được ghi chép đầy đủ trong đó cú pháp Nối ANSI-89 cũ tạo ra kết quả không chính xác ... cụ thể là Nối bên ngoài khi có các vị từ lọc có điều kiện trên các cột liên quan không tham gia từ phía "bên ngoài" của phép nối.
Charles Bretana

1
Tôi không biết nội dung cụ thể của MS SQL, nhưng đó là bằng chứng giai thoại tốt cho thấy cú pháp SQL-92 là đáng giá. Làm việc cho tôi!
Bill Karwin

2
To lớn? Hãy đăng tác phẩm của bạn. Đặt cược tốt nhất của tôi là nó không phải là một so sánh táo với táo, nhưng không trả lời bằng "oh vâng nó là" Chỉ cần trả lời với một trường hợp thử nghiệm, chúng tôi có thể tái tạo, phiên bản, cấp độ vá lỗi, v.v.

2
Bên cạnh đó, bằng chứng "giai thoại" dù sao cũng không phải là một biện pháp khoa học. Nó luôn luôn được thực hiện với một hạt muối.
Bill Karwin

16

Chuẩn ANSI092 bao gồm một số cú pháp khá tồi tệ. Kết hợp tự nhiên là một và Mệnh đề sử dụng là một điều khoản khác. IMHO, việc thêm một cột vào bảng sẽ không làm hỏng mã nhưng THAM GIA TỰ NHIÊN sẽ phá vỡ một cách nghiêm trọng nhất. Cách "tốt nhất" để phá vỡ là do lỗi biên dịch. Ví dụ: nếu bạn CHỌN * ở đâu đó, việc thêm một cột có thểkhông biên dịch được. Cách tốt nhất tiếp theo để thất bại sẽ là lỗi thời gian chạy. Điều đó còn tồi tệ hơn vì người dùng của bạn có thể nhìn thấy nó, nhưng nó vẫn cho bạn một cảnh báo tốt rằng bạn đã làm hỏng thứ gì đó. Nếu bạn sử dụng ANSI92 và viết các truy vấn với các phép nối TỰ NHIÊN, nó sẽ không bị hỏng tại thời điểm biên dịch và không bị hỏng khi chạy, truy vấn sẽ đột ngột bắt đầu tạo ra kết quả sai. Những loại bọ này rất quỷ quyệt. Báo cáo bị sai, có khả năng công bố tài chính không chính xác.

Đối với những người không quen thuộc với NATURAL Joins. Chúng nối hai bảng trên mọi tên cột tồn tại trong cả hai bảng. Điều này thực sự tuyệt vời khi bạn có một phím 4 cột và bạn chán gõ phím đó. Sự cố xảy ra khi Table1 có một cột tồn tại từ trước có tên là DESCRIPTION và bạn thêm một cột mới vào Table2 có tên, ồ tôi không biết, một cái gì đó vô hại như, mmm, DESCRIPTION và bây giờ bạn đang kết hợp hai bảng trên VARCHAR2 (1000) trường là biểu mẫu miễn phí.

Điều khoản SỬ DỤNG có thể dẫn đến hoàn toàn không rõ ràng ngoài vấn đề được mô tả ở trên. Trong một bài đăng SO khác , một người nào đó đã hiển thị SQL ANSI-92 này và yêu cầu trợ giúp đọc nó.

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

Điều này là hoàn toàn mơ hồ. Tôi đặt cột UserID trong cả Bảng công ty và bảng người dùng và không có gì phàn nàn. Điều gì sẽ xảy ra nếu cột UserID trong các công ty là ID của người cuối cùng sửa đổi hàng đó?

Tôi nghiêm túc, Bất cứ ai có thể giải thích tại sao sự mơ hồ như vậy là cần thiết? Tại sao nó được xây dựng thẳng vào tiêu chuẩn?

Tôi nghĩ Bill đúng khi có một lượng lớn các nhà phát triển sao chép / dán vào đó thông qua mã hóa. Trên thực tế, tôi có thể thừa nhận rằng tôi là một người như thế khi nói đến ANSI-92. Mọi ví dụ tôi từng thấy đều cho thấy nhiều phép nối được lồng trong dấu ngoặc đơn. Trung thực, điều đó làm cho việc chọn ra các bảng trong sql trở nên khó khăn nhất. Nhưng sau đó một nhà phát triển SQL92 giải thích rằng điều đó thực sự sẽ buộc một thứ tự nối. CHÚA GIÊSU ... tất cả những Copy Pasters mà tôi đã thấy bây giờ đang thực sự buộc một thứ tự gia nhập - một công việc tốt hơn 95% thời gian còn lại cho những người tối ưu hóa, đặc biệt là copy / paster.

Tomalak đã hiểu đúng khi anh ấy nói,

mọi người không chuyển sang cú pháp mới chỉ vì nó ở đó

Nó phải cung cấp cho tôi một cái gì đó và tôi không thấy điều gì ngược lại. Và nếu có một phần ngược lại, phần âm bản là một con chim hải âu quá lớn để có thể bị bỏ qua.


3
Tôi có xu hướng sử dụng BẬT vì nó ít mơ hồ hơn SỬ DỤNG hoặc THAM GIA TỰ NHIÊN. Đối với dấu ngoặc đơn, những người học "SQL" trên Microsoft Access sẽ sử dụng dấu ngoặc đơn của Access nếu bạn bỏ qua chúng. (Các dấu ngoặc kép xung quanh SQL nên là dấu ngoặc kép.)
Powerlord

1
Ho Điều khoản SỬ DỤNG là gì? ;-) Tôi đến từ phần máy chủ SQL, vì vậy điều này thực sự không có trên radar của tôi. Như R. Bemrose đã nói, có điều khoản ON, hoạt động tốt, không bao giờ để lại cho tôi một phép nối mà tôi không thể diễn đạt theo cú pháp. Không cần phải điều chỉnh thiết kế DB của tôi thành cú pháp truy vấn để tiết kiệm một số thao tác nhập.
Tomalak

3
Nếu bạn không biết rõ về dữ liệu của mình để sử dụng NATURAL JOIN hoặc USING khi thích hợp, có lẽ bạn không nên viết SQL cho nó. -1 cho sự thiếu hiểu biết.
Rob

4
IMHO, gia nhập tự nhiên rơi vào cùng một túi SELECT *(sau đó tìm ra khách hàng dựa trên thứ tự hiện trường) - Nó chỉ cảm thấy hơi cẩu thả
Cơ bản

2
Vấn đề bạn mô tả với các phép nối tự nhiên là vấn đề với thiết kế cơ sở dữ liệu của bạn - không phải vấn đề với tiêu chuẩn. bạn nên biết về dữ liệu của mình và đã thiết lập các tiêu chuẩn cho tên cột.
Travis

14

Một số lý do xuất hiện trong tâm trí:

  • mọi người làm điều đó theo thói quen
  • mọi người lười biếng và thích tham gia "kiểu cũ" vì chúng liên quan đến việc nhập ít hơn
  • người mới bắt đầu thường gặp vấn đề khi xoay quanh cú pháp nối SQL-92
  • mọi người không chuyển sang cú pháp mới chỉ vì nó ở đó
  • mọi người không biết về những lợi ích mà cú pháp mới (nếu bạn muốn gọi nó như vậy), chủ yếu là nó cho phép bạn lọc một bảng trước khi bạn thực hiện một phép nối bên ngoài, chứ không phải sau nó khi tất cả những gì bạn có là mệnh đề WHERE.

Về phần mình, tôi thực hiện tất cả các phép nối theo cú pháp SQL-92 và tôi chuyển đổi mã khi có thể. Đó là cách làm rõ ràng hơn, dễ đọc hơn và mạnh mẽ hơn. Nhưng thật khó để thuyết phục ai đó sử dụng kiểu mới, khi họ cho rằng nó gây tổn hại cho họ về công việc gõ nhiều hơn trong khi không thay đổi kết quả truy vấn.


3
Đối với nhiều người, nhìn vào SQL làm họ khó chịu. Việc thay đổi bất kỳ mã làm việc nào cũng có nguy cơ tạo ra lỗi, đặc biệt là khi lập trình viên đang quay lưng lại với nhau. :-)
Bill Karwin

Hm ... đối với tôi, ngay cả khi nhìn vào các biểu thức chính quy phức tạp cũng không có hại gì cả. SQL không thể làm hại tôi. ;-)
Tomalak

"Những người mới bắt đầu thường gặp vấn đề ..." ĐÓ LÀ một điểm bán hàng

2
Vì lý do nào đó, tôi không chắc đó là bình luận "pro" hay "contra" ... Có lẽ máy dò trớ trêu của tôi đã bị hỏng.
Tomalak 20/02/09

10

Đáp lại bài viết THAM GIA VÀ SỬ DỤNG THIÊN NHIÊN ở trên.

TẠI SAO bạn sẽ thấy cần phải sử dụng những thứ này - chúng không có sẵn trong ANSI-89 và đã được thêm vào ANSI-92 như những gì tôi chỉ có thể xem như một phím tắt.

Tôi sẽ không bao giờ để tham gia một cách ngẫu nhiên và sẽ luôn chỉ định bảng / bí danh và id.

Đối với tôi, cách duy nhất để đi là ANSI-92. Nó dài dòng hơn và cú pháp không được những người theo dõi ANSI-89 thích nhưng nó tách biệt rõ ràng các THAM GIA của bạn khỏi BỘ LỌC của bạn.


Tôi không xem NATURAL JOIN như một lối tắt mà là một Segway để lập trình DB hướng đối tượng trong DB quan hệ.
Armand

5

Trước tiên, hãy để tôi nói rằng trong SQL Server, cú pháp nối ngoài (* =) không cho kết quả chính xác mọi lúc. Đôi khi nó giải thích rằng đó là một phép nối chéo chứ không phải một phép nối bên ngoài. Vì vậy, có một lý do chính đáng để ngừng sử dụng nó. Và cú pháp nối bên ngoài đó là một tính năng không được dùng nữa và sẽ không có trong phiên bản SQL Server tiếp theo sau SQL Server 2008. Bạn vẫn có thể thực hiện các phép nối bên trong nhưng tại sao mọi người lại muốn làm vậy? Chúng không rõ ràng và khó bảo trì hơn nhiều. Bạn không dễ dàng biết được đâu là một phần của phép nối và đâu thực sự là mệnh đề where.

Một lý do tại sao tôi tin rằng bạn không nên sử dụng cú pháp cũ là hiểu các phép nối và những gì chúng làm và không làm là một bước quan trọng đối với bất kỳ ai viết mã SQL. Bạn không nên viết bất kỳ mã SQL nào mà không hiểu kỹ các phép nối. Nếu bạn hiểu rõ về chúng, bạn có thể sẽ đi đến kết luận rằng cú pháp ANSI-92 rõ ràng hơn và dễ duy trì hơn. Tôi chưa bao giờ gặp một chuyên gia SQL nào không sử dụng cú pháp ANSI-92 thay vì cú pháp cũ.

Hầu hết những người tôi đã gặp hoặc từng giao dịch sử dụng mã cũ, thực sự không hiểu các phép nối và do đó gặp rắc rối khi truy vấn cơ sở dữ liệu. Đây là kinh nghiệm cá nhân của tôi nên tôi không nói nó luôn đúng. Nhưng với tư cách là một chuyên gia dữ liệu, tôi đã phải sửa chữa quá nhiều thứ rác rưởi này trong suốt nhiều năm không thể tin được.


1
Rất vui được gặp bạn. Hạnh phúc là người đầu tiên của bạn.

4

Tôi đã được dạy ANSI-89 ở trường và làm việc trong ngành công nghiệp trong một vài năm. Sau đó, tôi rời khỏi thế giới tuyệt vời của DBMS trong 8 năm. Nhưng sau đó tôi quay lại và nội dung ANSI 92 mới này đang được dạy. Tôi đã học cú pháp Join On và bây giờ tôi thực sự dạy SQL và tôi khuyên bạn nên sử dụng cú pháp JOIN ON mới.

Nhưng nhược điểm mà tôi thấy là các truy vấn con tương quan dường như không có ý nghĩa nếu xét theo các phép nối ANSI 92. Khi thông tin kết hợp được đưa vào WHERE và các truy vấn con tương quan được "tham gia" trong WHERE, tất cả đều có vẻ đúng và nhất quán. Trong ANSI 92, tiêu chí tham gia bảng không nằm trong WHERE và truy vấn con "tham gia", cú pháp có vẻ không nhất quán. Mặt khác, cố gắng "sửa chữa" sự mâu thuẫn này có lẽ sẽ chỉ làm cho nó tồi tệ hơn.


Mặt khác, bạn không nên viết các truy vấn con tương quan vì chúng là những con heo chạy sai. Chúng giống như đặt một con trỏ vào truy vấn của bạn. Ặc.
HLGEM

3

Tôi không biết câu trả lời chắc chắn .. đây là một cuộc chiến tôn giáo (ngoại chứng ở mức độ thấp hơn Mac-Pc hoặc những người khác)

Một phỏng đoán là cho đến gần đây, Oracle, (và có thể cả các nhà cung cấp khác) đã không áp dụng tiêu chuẩn ANSI-92 (tôi nghĩ rằng nó đã có trong Oracle v9 hoặc ở đó) và do đó, đối với các Nhà phát triển DBA / Db làm việc tại các công ty vẫn đang sử dụng các phiên bản này, (hoặc muốn mã di động trên các máy chủ có thể đang sử dụng các phiên bản này, chúng phải tuân theo tiêu chuẩn cũ ...

Thực sự đáng tiếc, vì cú pháp nối mới dễ đọc hơn nhiều và cú pháp cũ tạo ra kết quả sai (không chính xác) dẫn đến một số tình huống được ghi chép đầy đủ.

  • Cụ thể, kết hợp bên ngoài khi có các vị từ lọc có điều kiện trên các cột liên quan không tham gia từ bảng ở phía "bên ngoài" của phép nối.

Có, Oracle 9i; phát hành vào năm 2001. Một chút muộn cho bữa tiệc!

1
MS SQL được bổ sung INNER JOINvào năm 1995, mặc dù LEFT JOINphải đến năm 1996. MySQL đã hỗ trợ nó ít nhất kể từ 3.23, phát hành vào năm 1999; PostgreSQL ít nhất là từ 7.2, được phát hành vào năm 2002. Một số Googling thông thường không đưa ra câu trả lời cho tôi cho Teradata.

Vâng, đó là lời kết án chứng tỏ sự vượt trội của Oracle vào năm 1991: các hệ thống cơ sở dữ liệu như truy cập MS sử dụng cú pháp "Left" và "Right" không phải là SQL chuẩn ANSI. Đăng SQL như vậy là cơ hội để người khác chế nhạo bạn. Kiểu như twitter và facebook bây giờ.
david

2

Quán tính và tính thực dụng.

ANSI-92 SQL giống như kiểu gõ cảm ứng. Về mặt lý thuyết, nó có thể làm mọi thứ tốt hơn vào một ngày nào đó, nhưng bây giờ tôi có thể gõ phím nhanh hơn nhiều khi nhìn vào các phím bằng bốn ngón tay. Tôi sẽ cần phải quay ngược lại để đi tiếp, không có gì đảm bảo rằng sẽ có một sự đền đáp.

Viết SQL là khoảng 10% công việc của tôi. Nếu tôi cần ANSI-92 SQL để giải quyết vấn đề mà ANSI-89 SQL không thể giải quyết thì tôi sẽ sử dụng nó. (Thực tế là tôi sử dụng nó trong Access.) Nếu việc sử dụng nó mọi lúc sẽ giúp tôi giải quyết các vấn đề hiện tại nhanh hơn nhiều, thì tôi sẽ dành thời gian để đồng hóa nó. Nhưng tôi có thể sử dụng ANSI-89 SQL mà không cần suy nghĩ về cú pháp. Tôi được trả tiền để giải quyết các vấn đề - nghĩ về cú pháp SQL là một sự lãng phí thời gian của tôi và tiền của chủ nhân của tôi.

Một ngày nào đó, Grasshopper trẻ, bạn sẽ bảo vệ việc sử dụng cú pháp ANSI-92 SQL của mình trước những người trẻ tuổi than vãn rằng bạn nên sử dụng SQL3 (hoặc bất cứ điều gì). Và rồi bạn sẽ hiểu. :-)


2
Cách tiếp cận được mô tả ở đây nghe có vẻ RẤT RẤT giống như trường phái tư tưởng "sửa chữa nó khi nó bị hỏng", tránh xa ý tưởng bảo trì phòng ngừa. Bạn được trả tiền để giải quyết vấn đề, vâng, nhưng bạn cũng được trả tiền để cung cấp nhiều giá trị hơn cho công ty của bạn. ANSI-89 trong trường hợp của bạn cung cấp giá trị lớn hơn trong ngắn hạn, nhưng về lâu dài không đầu tư thời gian vào ANSI-92 sẽ là lựa chọn đắt tiền hơn.
Travis

Gắn bó với những gì bạn đã luôn làm đi kèm với một cái giá phải trả cho anh chàng nghèo phải duy trì mã của bạn khi bạn ra đi. Điều đó không có nghĩa là bạn nên chuyển sang hương vị của tháng, nhưng việc áp dụng các phương pháp hay nhất hầu như luôn mang lại hiệu quả trong khả năng bảo trì.

Tôi sẽ không chuyển sang Excel (nơi bạn có thể làm bất cứ điều gì chỉ với ba lần nhấp chuột trở xuống), bởi vì tôi đã ghi nhớ hàng nghìn lệnh Lotus 123 mà tôi cần và tôi cảm thấy thoải mái khi sử dụng chúng! Hả!
Charles Bretana

2

Tôi có một truy vấn ban đầu được viết cho SQL Server 6.5, không hỗ trợ cú pháp nối SQL 92, tức là

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

thay vào đó được viết là

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

Truy vấn đã tồn tại được một thời gian và dữ liệu liên quan đã tích lũy khiến truy vấn chạy quá chậm, mất 90 giây để hoàn thành. Vào thời điểm sự cố này phát sinh, chúng tôi đã nâng cấp lên SQL Server 7.

Sau khi liên kết với các chỉ mục và các Easter-egg khác, tôi đã thay đổi cú pháp nối để tuân thủ SQL 92. Thời gian truy vấn giảm xuống còn 3 giây.

Có một lý do chính đáng để chuyển đổi.

Đăng lại từ đây .


1

Tôi có thể trả lời từ quan điểm của một nhà phát triển bình thường, chỉ biết đủ SQL để hiểu cả hai cú pháp, nhưng vẫn truy cập vào địa chỉ cú pháp chính xác của insert mỗi khi tôi cần ... :-P (Tôi không làm SQL cả ngày , thỉnh thoảng chỉ sửa một số vấn đề.)

Thực ra, tôi thấy biểu mẫu đầu tiên trực quan hơn, không có thứ bậc rõ ràng giữa hai bảng. Thực tế là tôi đã học SQL với những cuốn sách cũ, hiển thị ở dạng đầu tiên, có lẽ không giúp ích được gì ... ;-)
Và tài liệu tham khảo đầu tiên tôi tìm thấy trên một tìm kiếm sql select trong Google (trả về hầu hết các câu trả lời bằng tiếng Pháp cho tôi ... ) đầu tiên hiển thị biểu mẫu cũ hơn (sau đó giải thích biểu mẫu thứ hai).

Chỉ đưa ra một số gợi ý về câu hỏi "tại sao" ... ^ _ ^ Tôi nên đọc một cuốn sách hay, hiện đại (DB bất khả tri) về chủ đề này. Nếu ai đó có gợi ý ...


1

Tôi không thể nói cho tất cả các trường nhưng ở trường đại học của tôi khi chúng tôi làm mô-đun SQL trong khóa học của mình, họ không dạy ANSI-92, họ dạy ANSI-89 - trên một hệ thống VAX cũ ở đó! Tôi đã không tiếp xúc với ANSI-92 cho đến khi tôi bắt đầu tìm hiểu trong Access khi đã xây dựng một số truy vấn bằng cách sử dụng trình thiết kế truy vấn và sau đó đào sâu vào mã SQL. Nhận ra rằng tôi không biết nó đang hoàn thành các phép nối như thế nào hoặc hàm ý của cú pháp, tôi bắt đầu đào sâu hơn để có thể hiểu nó.

Do tài liệu có sẵn không chính xác trực quan trong nhiều trường hợp và mọi người có xu hướng bám vào những gì họ biết và trong nhiều trường hợp không cố gắng học nhiều hơn những gì họ cần để hoàn thành công việc của mình, đó là dễ thấy tại sao việc áp dụng lại mất nhiều thời gian như vậy.

Tất nhiên, có những nhà truyền giáo kỹ thuật thích mày mò và hiểu biết và nó có xu hướng là những người áp dụng các nguyên tắc "mới hơn" và cố gắng chuyển đổi phần còn lại.

Thật kỳ lạ, đối với tôi, có vẻ như rất nhiều lập trình viên ra trường và không ngừng thăng tiến; nghĩ rằng bởi vì đây là những gì họ đã được dạy, đây là cách nó được thực hiện. Chỉ cho đến khi bạn cởi bỏ chớp mắt của mình, bạn mới nhận ra rằng trường học chỉ nhằm dạy bạn những điều cơ bản và cung cấp cho bạn đủ hiểu biết để tự học những thứ còn lại và bạn thực sự hầu như không làm xước bề mặt của những gì cần biết; bây giờ công việc của bạn là tiếp tục con đường đó.

Tất nhiên, đó chỉ là ý kiến ​​của tôi dựa trên kinh nghiệm của tôi.


Nó không chỉ là các lập trình viên. Trong nhiều lĩnh vực, thật khó để thuyết phục mọi người đào tạo lại khi họ đã thành danh trong sự nghiệp. Tất nhiên, có những cá nhân đặc biệt, tôi cho rằng tỷ lệ tương tự trong mọi lĩnh vực.
Bill Karwin 19/08/08

2
Thật khó để thuyết phục ai đó chuyển từ một thứ thành công sang một thứ khác biệt mà không mang lại lợi ích gì. Phía .net của chúng tôi đã thay đổi từ 1,0 thành 3,5 và mỗi bước ở giữa là KHÔNG cajoling. Mỗi phiên bản mới đều tốt hơn. Không thể nói như vậy ở đây.

1

1) Cách chuẩn để viết OUTER JOIN, so với * = hoặc (+) =

2) THAM GIA TỰ NHIÊN

3) Phụ thuộc vào công cụ cơ sở dữ liệu, ANSI-92 có xu hướng tối ưu hơn.

4) Tối ưu hóa thủ công:

Giả sử rằng chúng ta có cú pháp tiếp theo (ANSI-89):

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

Nó có thể được viết là:

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

Nhưng cũng như:

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

Tất cả chúng (1), (2), (3) trả về cùng một kết quả, tuy nhiên chúng được tối ưu hóa khác nhau, điều đó phụ thuộc vào công cụ cơ sở dữ liệu nhưng hầu hết chúng đều làm:

  • (1) tùy thuộc vào công cụ cơ sở dữ liệu quyết định việc tối ưu hóa.
  • (2) nó kết hợp cả hai bảng sau đó thực hiện bộ lọc cho mỗi văn phòng.
  • (3) nó lọc BIG_TABLE_USERS bằng idoffice sau đó nối cả hai bảng.

5) Các truy vấn dài hơn ít lộn xộn hơn.


1

Những lý do mọi người sử dụng ANSI-89 từ kinh nghiệm thực tế của tôi với các lập trình viên già và trẻ, thực tập sinh và sinh viên mới tốt nghiệp:

  • Họ học SQL từ mã hiện có mà họ thấy (thay vì sách) và học ANSI-89 từ mã
  • ANSI-89 vì gõ ít hơn
  • Họ không nghĩ về nó và sử dụng kiểu này hay kiểu khác và thậm chí không biết kiểu nào trong cả hai được coi là mới hay cũ và cũng không quan tâm
  • Ý tưởng rằng mã cũng là một giao tiếp cho lập trình viên tiếp theo cùng với việc duy trì mã không tồn tại. Họ nghĩ rằng họ nói chuyện với máy tính và máy tính không quan tâm.
  • Nghệ thuật "mã hóa sạch" chưa được biết đến
  • Kiến thức về ngôn ngữ lập trình và SQL cụ thể là kém đến mức họ sao chép và dán những gì họ tìm thấy ở nơi khác
  • Sở thích cá nhân

Cá nhân tôi thích ANSI-92 hơn và thay đổi mọi truy vấn tôi thấy trong cú pháp ANSI-89 đôi khi chỉ để hiểu rõ hơn Câu lệnh SQL trong tầm tay. Nhưng tôi nhận ra rằng phần lớn những người tôi làm việc cùng không đủ kỹ năng để viết các phép nối trên nhiều bảng. Họ viết mã tốt nhất có thể và sử dụng những gì họ đã ghi nhớ trong lần đầu tiên gặp câu lệnh SQL.


1

Dưới đây là một số điểm so sánh SQL-89 và SQL-92 và xóa một số quan niệm sai lầm trong các câu trả lời khác.

  1. NATURAL JOINSlà một ý tưởng kinh khủng. Chúng là ẩn và chúng yêu cầu siêu thông tin về bảng. Không có gì về SQL-92 yêu cầu sử dụng chúng nên chỉ cần bỏ qua chúng . Chúng không liên quan đến cuộc thảo luận này.
  2. USING là một ý tưởng tuyệt vời, nó có hai tác dụng:
    1. Nó chỉ tạo ra một cột trên tập kết quả từ một tương đương.
    2. Nó thực thi một quy ước âm thanh và lành mạnh. Trong SQL-89, bạn có người viết cột idtrên cả hai bảng. Sau khi bạn nối các bảng, điều này trở nên mơ hồ và nó yêu cầu phải có răng cưa rõ ràng. Hơn nữa, các idtham gia gần như chắc chắn có dữ liệu khác nhau. Nếu bạn tham gia người này sang công ty, bây giờ bạn có một bí danh idđể person_id, và một idđể company_id, mà không có tham gia sẽ tạo ra hai cột mơ hồ. Sử dụng số nhận dạng duy nhất trên toàn cầu cho khóa đại diện của bảng là quy ước mà phần thưởng tiêu chuẩn USING.
  3. Cú pháp SQL-89 là một cú pháp ngầm CROSS JOIN. A CROSS JOINkhông làm giảm tập hợp, nó ngầm phát triển nó. FROM T1,T2cũng giống như FROM T1 CROSS JOIN T2, tạo ra một phép nối Descartes thường không phải là những gì bạn muốn. Có tính chọn lọc để giảm điều đó bị loại bỏ thành một WHEREđiều kiện xa có nghĩa là bạn có nhiều khả năng mắc lỗi trong quá trình thiết kế.
  4. SQL-89 ,và SQL-92 rõ ràng JOINcó quyền ưu tiên khác nhau. JOINcó mức độ ưu tiên cao hơn. Thậm chí tệ hơn, một số cơ sở dữ liệu như MySQL đã mắc lỗi này trong một thời gian rất dài. . Vì vậy, trộn hai kiểu là một ý tưởng tồi, và kiểu phổ biến hơn ngày nay là kiểu SQL-92.

1) Nếu bạn nghiên cứu mô hình quan hệ, bạn sẽ đánh giá cao điều đó, không chỉ là liên kết tự nhiên là một ý tưởng tuyệt vời, nó là loại liên kết duy nhất mà bạn cần. 2) Xem 1 tức là không cần thiết. 3) Bất kể cú pháp (và cả hai đều là cú pháp SQL-92), toán tử quan hệ là sản phẩm (nhân) tức là không thực sự là một phép nối (phép nối Descartes 'thậm chí không phải là một thứ). 4. Xem 1 tức là không cần thiết.
onedaywhen

0

Oracle hoàn toàn không triển khai ANSI-92. Tôi đã gặp một số vấn đề, đặc biệt là bởi vì các bảng dữ liệu trong Ứng dụng Oracle được hỗ trợ rất tốt với các cột. Nếu số cột trong các liên kết của bạn vượt quá khoảng 1050 cột (điều này rất dễ thực hiện trong Ứng dụng), thì bạn sẽ gặp phải lỗi giả này hoàn toàn không có ý nghĩa logic:

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

Việc viết lại truy vấn để sử dụng cú pháp nối kiểu cũ làm cho vấn đề biến mất, điều này dường như chỉ ra ngón tay đổ lỗi cho việc triển khai các phép nối ANSI-92.

Cho đến khi tôi gặp phải vấn đề này, tôi vẫn là người kiên định quảng bá ASNI-92, vì những lợi ích trong việc giảm nguy cơ kết hợp chéo ngẫu nhiên, điều này quá dễ thực hiện với cú pháp kiểu cũ.

Tuy nhiên, bây giờ, tôi thấy khó khăn hơn nhiều để kiên quyết với nó. Họ chỉ ra cách triển khai tồi tệ của Oracle và nói "Chúng tôi sẽ làm theo cách của chúng tôi, cảm ơn."


1
Có thể dễ dàng để thực hiện Cross Join, nó cũng là điều không xảy ra một cách tự nhiên và chắc chắn không mơ hồ. Bất kỳ nhà phát triển SQL tử tế nào cũng có thể phát hiện ra nó. Nhưng SỬ DỤNG và THAM GIA TỰ NHIÊN là những kẻ cám dỗ đang kêu gọi bạn và đập con thuyền nhỏ của bạn trên những tảng đá của đau khổ và đau khổ.

1
Ý tôi là, việc tạo thành công một phép nối chéo ngẫu nhiên sẽ dễ dàng hơn bằng cách bỏ sót mệnh đề where nối hai bảng với nhau. Một phép nối chéo phải được cân nhắc trong ANSI-92. Nhưng tôi đồng ý rằng NATURAL JOIN là một điều ghê tởm. :)
Jonathan

Tôi hiểu quan điểm của bạn. Nhưng nó không chỉ xảy ra bất thường. Khi bạn gỡ lỗi truy vấn của mình, bạn nhận thấy sự cố và khắc phục nó. Nếu bạn sử dụng phép nối tự nhiên, không có thay đổi -at all- đối với chính truy vấn, nó có thể thay đổi do bảng thay đổi.

0

Tiêu chuẩn SQL mới kế thừa mọi thứ từ tiêu chuẩn trước đó, hay còn gọi là 'xiềng xích của khả năng tương thích'. Vì vậy, kiểu nối 'cũ' / 'được phân tách bằng dấu phẩy' / 'không đủ tiêu chuẩn' là kiểu sytax SQL-92 hoàn toàn hợp lệ.

Bây giờ, tôi tranh luận rằng SQL-92 NATURAL JOINlà kết hợp duy nhất bạn cần. Ví dụ, tôi cho rằng nó tốt hơn inner joinvì nó không tạo ra các cột trùng lặp - không có nhiều biến phạm vi trong SELECTcác mệnh đề để phân định các cột! Nhưng tôi không thể mong đợi sẽ thay đổi mọi trái tim và suy nghĩ, vì vậy tôi cần làm việc với các lập trình viên, những người sẽ tiếp tục áp dụng những gì mà cá nhân tôi coi là kiểu nối kế thừa (và họ thậm chí có thể gọi các biến phạm vi là 'bí danh'!). Đây là bản chất của làm việc nhóm và không hoạt động trong chân không.

Một trong những lời chỉ trích của ngôn ngữ SQL là kết quả tương tự có thể đạt được bằng cách sử dụng một số cú pháp tương đương về mặt ngữ nghĩa (một số sử dụng đại số quan hệ, một số sử dụng phép tính quan hệ), trong đó việc chọn cái 'tốt nhất' chỉ đơn giản là tùy thuộc vào phong cách cá nhân. . Vì vậy, tôi cảm thấy thoải mái với sự tham gia 'kiểu cũ' như tôi đang làm INNER. Liệu tôi có dành thời gian để viết lại chúng NATURALhay không tùy thuộc vào ngữ cảnh.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.