Lỗi phát triển cơ sở dữ liệu được thực hiện bởi các nhà phát triển ứng dụng [đã đóng]


566

Các lỗi phát triển cơ sở dữ liệu phổ biến được thực hiện bởi các nhà phát triển ứng dụng là gì?


Gần như trùng lặp với stackoverflow.com/questions
4326659 / Hy

Câu trả lời:


1002

1. Không sử dụng các chỉ số thích hợp

Đây là một điều tương đối dễ dàng nhưng nó vẫn xảy ra mọi lúc. Khóa ngoại nên có chỉ mục trên chúng. Nếu bạn đang sử dụng một trường trong một trường, WHEREbạn nên (có thể) có một chỉ mục trên đó. Các chỉ mục như vậy thường bao gồm nhiều cột dựa trên các truy vấn bạn cần thực hiện.

2. Không thực thi toàn vẹn tham chiếu

Cơ sở dữ liệu của bạn có thể khác nhau ở đây nhưng nếu cơ sở dữ liệu của bạn hỗ trợ tính toàn vẹn tham chiếu - có nghĩa là tất cả các khóa ngoại được đảm bảo để trỏ đến một thực thể tồn tại - bạn nên sử dụng nó.

Nó khá phổ biến để thấy sự thất bại này trên cơ sở dữ liệu MySQL. Tôi không tin MyISAM hỗ trợ nó. InnoDB nào. Bạn sẽ tìm thấy những người đang sử dụng MyISAM hoặc những người đang sử dụng InnoDB nhưng dù sao cũng không sử dụng nó.

Thêm ở đây:

3. Sử dụng các khóa chính tự nhiên thay vì thay thế (kỹ thuật)

Khóa tự nhiên là khóa dựa trên dữ liệu có ý nghĩa bên ngoài là duy nhất (bề ngoài). Ví dụ phổ biến là mã sản phẩm, mã tiểu bang hai chữ cái (Hoa Kỳ), số an sinh xã hội, v.v. Các khóa chính thay thế hoặc kỹ thuật là những khóa hoàn toàn không có ý nghĩa gì ngoài hệ thống. Chúng được phát minh hoàn toàn để xác định thực thể và thường là các trường tăng tự động (SQL Server, MySQL, các loại khác) hoặc các chuỗi (đáng chú ý nhất là Oracle).

Theo tôi bạn nên luôn luôn sử dụng các khóa thay thế. Vấn đề này đã được đưa ra trong những câu hỏi sau:

Đây là một chủ đề gây tranh cãi mà bạn sẽ không nhận được thỏa thuận chung. Mặc dù bạn có thể tìm thấy một số người, những người cho rằng khóa tự nhiên trong một số trường hợp vẫn ổn, nhưng bạn sẽ không tìm thấy bất kỳ lời chỉ trích nào về khóa thay thế ngoài việc được cho là không cần thiết. Đó là một nhược điểm nhỏ nếu bạn hỏi tôi.

Hãy nhớ rằng, thậm chí các quốc gia có thể ngừng tồn tại (ví dụ, Nam Tư).

4. Viết các truy vấn yêu cầu DISTINCTlàm việc

Bạn thường thấy điều này trong các truy vấn do ORM tạo. Nhìn vào đầu ra nhật ký từ Hibernate và bạn sẽ thấy tất cả các truy vấn bắt đầu bằng:

SELECT DISTINCT ...

Đây là một chút phím tắt để đảm bảo bạn không trả về các hàng trùng lặp và do đó nhận được các đối tượng trùng lặp. Đôi khi bạn sẽ thấy mọi người làm điều này là tốt. Nếu bạn thấy nó quá nhiều thì đó là một lá cờ đỏ thực sự. Không phải DISTINCTlà xấu hoặc không có ứng dụng hợp lệ. Nó thực hiện (trên cả hai tổng số) nhưng nó không phải là một đại diện thay thế hoặc một điểm dừng để viết các truy vấn chính xác.

Từ lý do tại sao tôi ghét DISTINCT :

Theo tôi, mọi thứ bắt đầu trở nên tồi tệ khi một nhà phát triển đang xây dựng truy vấn đáng kể, nối các bảng lại với nhau và đột nhiên anh ta nhận ra rằng có vẻ như anh ta đang bị trùng lặp (hoặc thậm chí nhiều hơn) và phản ứng tức thì của anh ta ... "giải pháp" cho "vấn đề" này của anh ấy là ném từ khóa DISTINCT và POOF tất cả những rắc rối của anh ấy biến mất.

5. Tổng hợp ủng hộ hơn tham gia

Một lỗi phổ biến khác của các nhà phát triển ứng dụng cơ sở dữ liệu là không nhận ra tổng hợp đắt hơn (nghĩa là GROUP BYmệnh đề) có thể được so sánh với các phép nối.

Để cho bạn biết mức độ phổ biến của nó, tôi đã viết về chủ đề này nhiều lần ở đây và đã bị đánh giá thấp rất nhiều cho nó. Ví dụ:

Từ câu lệnh SQL - Nhóm tham gia vào nhóm vs vs bởi và có :

Truy vấn đầu tiên:

SELECT userid
FROM userrole
WHERE roleid IN (1, 2, 3)
GROUP by userid
HAVING COUNT(1) = 3

Thời gian truy vấn: 0,312 giây

Truy vấn thứ hai:

SELECT t1.userid
FROM userrole t1
JOIN userrole t2 ON t1.userid = t2.userid AND t2.roleid = 2
JOIN userrole t3 ON t2.userid = t3.userid AND t3.roleid = 3
AND t1.roleid = 1

Thời gian truy vấn: 0,016 s

Đúng rồi. Phiên bản tham gia tôi đề xuất nhanh hơn hai mươi lần so với phiên bản tổng hợp.

6. Không đơn giản hóa các truy vấn phức tạp thông qua các khung nhìn

Không phải tất cả các nhà cung cấp cơ sở dữ liệu đều hỗ trợ các khung nhìn nhưng đối với những người làm như vậy, họ có thể đơn giản hóa rất nhiều các truy vấn nếu được sử dụng một cách thận trọng. Ví dụ: trong một dự án tôi đã sử dụng mô hình Đảng chung cho CRM. Đây là một kỹ thuật mô hình cực kỳ mạnh mẽ và linh hoạt nhưng có thể dẫn đến nhiều tham gia. Trong mô hình này có:

  • Đảng : nhân dân và tổ chức;
  • Vai trò của Đảng : những việc mà các bên đã làm, ví dụ Nhân viên và Chủ lao động;
  • Mối quan hệ vai trò của Đảng : làm thế nào những vai trò đó liên quan đến nhau.

Thí dụ:

  • Ted là một Người, là một tiểu nhóm của Đảng;
  • Ted có nhiều vai trò, một trong số đó là Nhân viên;
  • Intel là một tổ chức, là một tiểu nhóm của một Đảng;
  • Intel có nhiều vai trò, một trong số đó là Nhà tuyển dụng;
  • Intel sử dụng Ted, nghĩa là có mối quan hệ giữa các vai trò tương ứng của họ.

Vì vậy, có năm bảng được tham gia để liên kết Ted với chủ nhân của mình. Bạn cho rằng tất cả nhân viên là Người (không phải tổ chức) và cung cấp quan điểm của người trợ giúp này:

CREATE VIEW vw_employee AS
SELECT p.title, p.given_names, p.surname, p.date_of_birth, p2.party_name employer_name
FROM person p
JOIN party py ON py.id = p.id
JOIN party_role child ON p.id = child.party_id
JOIN party_role_relationship prr ON child.id = prr.child_id AND prr.type = 'EMPLOYMENT'
JOIN party_role parent ON parent.id = prr.parent_id = parent.id
JOIN party p2 ON parent.party_id = p2.id

Và đột nhiên bạn có một cái nhìn rất đơn giản về dữ liệu bạn muốn nhưng trên một mô hình dữ liệu rất linh hoạt.

7. Không vệ sinh đầu vào

Đây là một trong những rất lớn. Bây giờ tôi thích PHP nhưng nếu bạn không biết những gì bạn đang làm thì thực sự dễ dàng tạo ra các trang web dễ bị tấn công. Không có gì tóm tắt nó tốt hơn câu chuyện về Bobby Bàn nhỏ .

Dữ liệu được cung cấp bởi người dùng bằng URL, dữ liệu biểu mẫu và cookie phải luôn được coi là thù địch và vệ sinh. Hãy chắc chắn rằng bạn đang nhận được những gì bạn mong đợi.

8. Không sử dụng báo cáo đã chuẩn bị

Các câu lệnh được chuẩn bị là khi bạn biên dịch một truy vấn trừ đi dữ liệu được sử dụng trong các phần chèn, cập nhật và WHEREmệnh đề và sau đó cung cấp nó sau đó. Ví dụ:

SELECT * FROM users WHERE username = 'bob'

đấu với

SELECT * FROM users WHERE username = ?

hoặc là

SELECT * FROM users WHERE username = :username

tùy thuộc vào nền tảng của bạn.

Tôi đã thấy cơ sở dữ liệu đến đầu gối của họ bằng cách làm điều này. Về cơ bản, mỗi khi bất kỳ cơ sở dữ liệu hiện đại nào gặp phải một truy vấn mới, nó phải biên dịch nó. Nếu nó gặp một truy vấn mà nó đã thấy trước đó, thì bạn đang cho cơ sở dữ liệu cơ hội lưu trữ truy vấn đã biên dịch và kế hoạch thực hiện. Bằng cách thực hiện truy vấn rất nhiều, bạn cho cơ sở dữ liệu cơ hội để tìm ra điều đó và tối ưu hóa cho phù hợp (ví dụ: bằng cách ghim truy vấn đã biên dịch trong bộ nhớ).

Sử dụng các câu lệnh được chuẩn bị cũng sẽ cung cấp cho bạn số liệu thống kê có ý nghĩa về tần suất sử dụng một số truy vấn nhất định.

Các câu lệnh được chuẩn bị cũng sẽ bảo vệ bạn tốt hơn trước các cuộc tấn công tiêm nhiễm SQL.

9. Không bình thường hóa đủ

Chuẩn hóa cơ sở dữ liệu về cơ bản là quá trình tối ưu hóa thiết kế cơ sở dữ liệu hoặc cách bạn sắp xếp dữ liệu của mình thành các bảng.

Mới tuần này tôi đã chạy qua một số mã trong đó ai đó đã mã hóa một mảng và chèn nó vào một trường duy nhất trong cơ sở dữ liệu. Bình thường hóa đó sẽ là coi phần tử của mảng đó là một hàng riêng biệt trong bảng con (nghĩa là mối quan hệ một-nhiều).

Điều này cũng xuất hiện trong phương pháp tốt nhất để lưu trữ danh sách ID người dùng :

Tôi đã thấy trong các hệ thống khác rằng danh sách được lưu trữ trong một mảng PHP được tuần tự hóa.

Nhưng thiếu bình thường hóa có nhiều dạng.

Hơn:

10. Bình thường hóa quá nhiều

Điều này có vẻ như mâu thuẫn với điểm trước nhưng bình thường hóa, giống như nhiều thứ, là một công cụ. Nó là một phương tiện để kết thúc và không phải là kết thúc trong chính nó. Tôi nghĩ rằng nhiều nhà phát triển quên điều này và bắt đầu coi "phương tiện" là "kết thúc". Kiểm thử đơn vị là một ví dụ điển hình của việc này.

Tôi đã từng làm việc trên một hệ thống có hệ thống phân cấp rất lớn cho các khách hàng có nội dung như sau:

Licensee ->  Dealer Group -> Company -> Practice -> ...

sao cho bạn phải tham gia khoảng 11 bảng với nhau trước khi bạn có thể nhận được bất kỳ dữ liệu có ý nghĩa nào. Đó là một ví dụ tốt về bình thường hóa đi quá xa.

Hơn nữa, cẩn thận và được coi là không chuẩn hóa có thể có lợi ích hiệu suất rất lớn nhưng bạn phải thực sự cẩn thận khi làm điều này.

Hơn:

11. Sử dụng vòng cung độc quyền

Một cung độc quyền là một lỗi phổ biến trong đó một bảng được tạo bằng hai hoặc nhiều khóa ngoại trong đó một và chỉ một trong số chúng có thể là không rỗng. Sai lầm lớn. Đối với một điều, nó trở nên khó khăn hơn nhiều để duy trì tính toàn vẹn dữ liệu. Rốt cuộc, ngay cả với tính toàn vẹn tham chiếu, không có gì ngăn cản hai hoặc nhiều khóa ngoại này được đặt (các ràng buộc kiểm tra phức tạp mặc dù).

Từ một hướng dẫn thực tế để thiết kế cơ sở dữ liệu quan hệ :

Chúng tôi đã khuyến cáo mạnh mẽ chống lại việc xây dựng hồ quang độc quyền bất cứ khi nào có thể, vì lý do chính đáng là họ có thể lúng túng khi viết mã và gây ra nhiều khó khăn bảo trì hơn.

12. Không thực hiện phân tích hiệu suất trên các truy vấn nào cả

Chủ nghĩa thực dụng trị vì tối cao, đặc biệt là trong thế giới cơ sở dữ liệu. Nếu bạn tuân thủ các nguyên tắc đến mức chúng trở thành giáo điều thì có lẽ bạn đã mắc sai lầm. Lấy ví dụ về các truy vấn tổng hợp từ trên. Phiên bản tổng hợp có thể trông "đẹp" nhưng hiệu suất của nó thì kém. Một so sánh hiệu suất nên đã kết thúc cuộc tranh luận (nhưng không phải vậy) nhưng quan trọng hơn: việc đưa ra những quan điểm thiếu hiểu biết như vậy ở nơi đầu tiên là không biết gì, thậm chí nguy hiểm.

13. Quá phụ thuộc vào các cấu trúc của UNION ALL và đặc biệt là UNION

Một UNION trong các thuật ngữ SQL chỉ đơn thuần ghép các tập dữ liệu đồng dạng, nghĩa là chúng có cùng loại và số cột. Sự khác biệt giữa chúng là UNION ALL là một cách ghép đơn giản và nên được ưu tiên bất cứ khi nào có thể trong khi UNION sẽ ngầm thực hiện một DISTINCT để loại bỏ các bộ dữ liệu trùng lặp.

ĐOÀN, như DISTINCT, có vị trí của họ. Có những ứng dụng hợp lệ. Nhưng nếu bạn thấy mình làm rất nhiều trong số đó, đặc biệt là trong các truy vấn con, thì có lẽ bạn đã làm sai điều gì đó. Đó có thể là một trường hợp xây dựng truy vấn kém hoặc mô hình dữ liệu được thiết kế kém buộc bạn phải làm những việc như vậy.

UNION, đặc biệt khi được sử dụng trong các phép nối hoặc truy vấn con phụ thuộc, có thể làm tê liệt cơ sở dữ liệu. Cố gắng tránh chúng bất cứ khi nào có thể.

14. Sử dụng điều kiện OR trong truy vấn

Điều này có vẻ vô hại. Rốt cuộc, AND vẫn ổn. HOẶC cũng nên ổn chứ? Sai lầm. Về cơ bản, một điều kiện AND giới hạn tập dữ liệu trong khi điều kiện OR phát triển nó nhưng không theo cách cho vay để tối ưu hóa. Đặc biệt là khi các điều kiện OR khác nhau có thể giao nhau, do đó buộc trình tối ưu hóa có hiệu quả đối với hoạt động DISTINCT trên kết quả.

Xấu:

... WHERE a = 2 OR a = 5 OR a = 11

Tốt hơn:

... WHERE a IN (2, 5, 11)

Bây giờ trình tối ưu hóa SQL của bạn có thể biến truy vấn đầu tiên thành truy vấn thứ hai một cách hiệu quả. Nhưng nó có thể không. Đừng làm điều đó.

15. Không thiết kế mô hình dữ liệu của họ để cho vay các giải pháp hiệu suất cao

Đây là một điểm khó để định lượng. Nó thường được quan sát bởi hiệu ứng của nó. Nếu bạn thấy mình viết các truy vấn sởn gai ốc cho các nhiệm vụ tương đối đơn giản hoặc các truy vấn tìm hiểu thông tin tương đối đơn giản không hiệu quả, thì có lẽ bạn có một mô hình dữ liệu kém.

Trong một số cách, điểm này tóm tắt tất cả những cái trước đó nhưng đó là một câu chuyện cảnh báo rằng việc thực hiện những việc như tối ưu hóa truy vấn thường được thực hiện trước tiên khi cần thực hiện lần thứ hai. Trước hết, bạn nên đảm bảo bạn có một mô hình dữ liệu tốt trước khi cố gắng tối ưu hóa hiệu suất. Như Knuth đã nói:

Tối ưu hóa sớm là gốc rễ của mọi tội lỗi

16. Sử dụng sai giao dịch cơ sở dữ liệu

Tất cả các thay đổi dữ liệu cho một quá trình cụ thể nên là nguyên tử. Tức là nếu hoạt động thành công, nó làm như vậy đầy đủ. Nếu thất bại, dữ liệu được giữ nguyên. - Không nên có khả năng thay đổi 'nửa vời'.

Lý tưởng nhất, cách đơn giản nhất để đạt được điều này là toàn bộ thiết kế hệ thống nên cố gắng hỗ trợ tất cả các thay đổi dữ liệu thông qua các câu lệnh INSERT / UPDATE / DELETE duy nhất. Trong trường hợp này, không cần xử lý giao dịch đặc biệt, vì công cụ cơ sở dữ liệu của bạn sẽ tự động làm như vậy.

Tuy nhiên, nếu bất kỳ quy trình nào yêu cầu nhiều câu lệnh được thực hiện như một đơn vị để giữ dữ liệu ở trạng thái nhất quán, thì Kiểm soát giao dịch thích hợp là cần thiết.

  • Bắt đầu một giao dịch trước khi tuyên bố đầu tiên.
  • Cam kết giao dịch sau khi tuyên bố cuối cùng.
  • Trên bất kỳ lỗi nào, Phục hồi giao dịch. Và rất NB! Đừng quên bỏ qua / hủy bỏ tất cả các câu lệnh sau lỗi.

Cũng nên chú ý cẩn thận đến các mạng con về cách kết nối cơ sở dữ liệu của bạn và công cụ cơ sở dữ liệu tương tác trong vấn đề này.

17. Không hiểu mô hình 'dựa trên tập hợp'

Ngôn ngữ SQL tuân theo một mô hình cụ thể phù hợp với các loại vấn đề cụ thể. Các tiện ích mở rộng dành riêng cho nhà cung cấp khác nhau, ngôn ngữ đấu tranh để xử lý các vấn đề không đáng kể trong các ngôn ngữ như Java, C #, Delphi, v.v.

Sự thiếu hiểu biết này thể hiện ở một vài cách.

  • Áp đặt không đúng cách quá nhiều logic thủ tục hoặc mệnh lệnh bắt buộc trên cơ sở dữ liệu.
  • Sử dụng con trỏ không phù hợp hoặc quá mức. Đặc biệt là khi một truy vấn duy nhất sẽ đủ.
  • Giả định không chính xác rằng kích hoạt bắn một lần mỗi hàng bị ảnh hưởng trong các bản cập nhật nhiều hàng.

Xác định sự phân chia trách nhiệm rõ ràng và cố gắng sử dụng công cụ thích hợp để giải quyết từng vấn đề.


9
Trên các tuyên bố của MySQL về khóa ngoại, bạn có quyền rằng MyISAM không hỗ trợ chúng, nhưng bạn ngụ ý rằng chỉ sử dụng MyISAM là thiết kế tồi. Một lý do tôi đã sử dụng MyISAM là InnoDB không hỗ trợ tìm kiếm FullText và tôi không nghĩ điều đó không hợp lý.
Derek H

1
Tôi phải hỏi về # 6. Sử dụng các khung nhìn như thế này là một trong những điều yêu thích của tôi, nhưng gần đây tôi đã học được rằng, với chỉ số MySQL trên các bảng bên dưới chỉ được tuân theo nếu cấu trúc của khung nhìn cho phép sử dụng thuật toán hợp nhất. Mặt khác, một bảng tạm thời được sử dụng và tất cả các chỉ mục của bạn đều vô dụng. Thậm chí còn đáng báo động hơn khi bạn nhận ra rằng một loạt các hoạt động gây ra hành vi này. Đó là một cách tuyệt vời để biến truy vấn 0,01 giây thành 100 giây. Có ai khác ở đây có kinh nghiệm với điều này? Kiểm tra các liên kết trong bình luận tiếp theo của tôi.
Peter Bailey

5
Hoàn toàn không đồng ý với # 3. Vâng, các quốc gia có thể ngừng tồn tại, nhưng mã quốc gia sẽ tiếp tục đại diện cho điều tương tự. Tương tự với mã tiền tệ hoặc Hoa Kỳ. Thật ngu ngốc khi sử dụng khóa thay thế trong những trường hợp này và tạo thêm chi phí trong các truy vấn của bạn vì bạn phải bao gồm một tham gia bổ sung. Tôi sẽ nói rằng sẽ an toàn hơn khi nói rằng có lẽ bạn nên sử dụng thay thế cho dữ liệu cụ thể của người dùng (do đó, không phải quốc gia, tiền tệ và Hoa Kỳ).
Thomas

1
RE: # 11 Ràng buộc kiểm tra cần thiết để thực thi tính toàn vẹn dữ liệu là không đáng kể. Có những lý do khác để tránh thiết kế đó, nhưng nhu cầu về ràng buộc kiểm tra "phức tạp" không phải là một trong số đó.
Thomas

2
Với số 3 bạn không trung thực. Có nhiều nhược điểm của khóa nhân tạo hơn là "bạn có thể không cần nó". Cụ thể, sử dụng khóa tự nhiên sẽ cung cấp cho bạn khả năng kiểm soát thứ tự dữ liệu trong bảng của bạn được ghi vào đĩa. Nếu bạn biết bảng của bạn sẽ được truy vấn như thế nào, bạn có thể lập chỉ mục cho nó để các hàng được truy cập đồng thời sẽ kết thúc trong cùng một trang. Hơn nữa, bạn có thể thực thi toàn vẹn dữ liệu bằng cách sử dụng một chỉ mục tổng hợp duy nhất. Nếu bạn cần điều này, bạn sẽ phải thêm nó vào chỉ mục khóa nhân tạo của bạn. Nếu nói chỉ số tổng hợp là pkey của bạn thì đó là 2 con chim bị giết bằng một viên đá.
Shane H

110

Lỗi thiết kế cơ sở dữ liệu và lập trình do các nhà phát triển thực hiện

  • Thiết kế và sử dụng cơ sở dữ liệu ích kỷ. Các nhà phát triển thường coi cơ sở dữ liệu là kho đối tượng liên tục cá nhân của họ mà không xem xét nhu cầu của các bên liên quan khác trong dữ liệu. Điều này cũng áp dụng cho các kiến ​​trúc sư ứng dụng. Thiết kế cơ sở dữ liệu kém và tính toàn vẹn dữ liệu khiến các bên thứ ba làm việc với dữ liệu khó khăn và có thể làm tăng đáng kể chi phí vòng đời của hệ thống. Báo cáo và MIS có xu hướng là một người anh em họ nghèo trong thiết kế ứng dụng và chỉ được thực hiện như một suy nghĩ sau.

  • Lạm dụng dữ liệu không chuẩn hóa. Việc lạm dụng dữ liệu không chuẩn hóa và cố gắng duy trì dữ liệu trong ứng dụng là một công thức cho các vấn đề toàn vẹn dữ liệu. Sử dụng không bình thường một cách tiết kiệm. Không muốn thêm một tham gia vào một truy vấn không phải là một lý do cho việc không chuẩn hóa.

  • Sợ viết SQL. SQL không phải là khoa học tên lửa và thực sự khá giỏi trong việc thực hiện công việc của mình. Các lớp ánh xạ O / R khá tốt trong việc thực hiện 95% các truy vấn đơn giản và phù hợp với mô hình đó. Đôi khi SQL là cách tốt nhất để thực hiện công việc.

  • Chính sách 'Không thủ tục lưu trữ' giáo điều. Bất kể bạn có tin rằng các thủ tục được lưu trữ là xấu xa hay không, thái độ giáo điều này không có chỗ trong một dự án phần mềm.

  • Không hiểu thiết kế cơ sở dữ liệu. Bình thường hóa là bạn của bạn và nó không phải là khoa học tên lửa. Tham gia và cardinality là những khái niệm khá đơn giản - nếu bạn tham gia vào phát triển ứng dụng cơ sở dữ liệu thì thực sự không có lý do gì để không hiểu chúng.


2
Người ta có thể lập luận rằng các giao dịch nên được thực hiện trong cơ sở dữ liệu giao dịch và báo cáo và MIS nên được thực hiện trong một cơ sở dữ liệu phân tích riêng biệt. Do đó, bạn có được điều tốt nhất của cả hai thế giới và mọi người đều hạnh phúc (ngoại trừ người nghèo khổ phải viết kịch bản chuyển đổi dữ liệu để xây dựng cái sau ra khỏi cái trước).
Chris Simpson

Không chỉ là người nghèo viết ETL - bất kỳ ai sử dụng dữ liệu từ hệ thống, dữ liệu kém chất lượng trong ứng dụng MIS được đóng hộp vì một số mối quan hệ chính không thực sự được ghi lại tại nguồn, bất kỳ ai tham gia vào các hoạt động hòa giải vô tận xảy ra sau đó từ chất lượng dữ liệu kém.
Mối quan tâmOfTunbridgeWells

Tôi không thể không đồng ý nhiều hơn với điểm một. Cơ sở dữ liệu là để kiên trì, chúng không dành cho giao tiếp giữa các quá trình. Hầu như luôn có giải pháp tốt hơn cho vấn đề đó. Trừ khi có một yêu cầu rõ ràng cho nó, bạn tuyệt đối NÊN đối xử với cơ sở dữ liệu như thể không có ai ngoại trừ ứng dụng của bạn sẽ sử dụng nó. Ngay cả khi có một yêu cầu rõ ràng, hãy thực hiện một số câu chuyện về người dùng và phân tích nguyên nhân gốc rễ trên đó và bạn sẽ thường xuyên khám phá ra một cách tốt hơn để lấp đầy ý định của người yêu cầu. Sau đó, một lần nữa, tôi làm việc tại một công ty nơi cụm từ CQRS có phần phổ biến
George Mauer

3
Ví dụ tầm thường: Tôi có một hệ thống quản lý chính sách bảo hiểm và cần nạp trạng thái 5 triệu yêu cầu vào hệ thống tái bảo hiểm nhượng lại để tính thu hồi tiềm năng. Các hệ thống này là các gói COTS máy chủ-máy khách cũ hơn, được thiết kế để giao tiếp với các hệ thống máy tính lớn hơn cũ. Cả hai phải được hòa giải cho mục đích kiểm soát tài chính. Công việc này được thực hiện một lần mỗi tháng. Theo logic của bạn, tôi sẽ viết một loạt các câu chuyện của người dùng xác định các yêu cầu và yêu cầu các nhà cung cấp trích dẫn về việc thêm một trình bao bọc dịch vụ web vào các sản phẩm hiện có của họ.
Mối quan tâmOfTunbridgeWells

2
Sau đó, DBA của bạn là lười biếng hoặc không đủ năng lực.
Mối quan tâmOfTunbridgeWells

80
  1. Không sử dụng kiểm soát phiên bản trên lược đồ cơ sở dữ liệu
  2. Làm việc trực tiếp với cơ sở dữ liệu trực tiếp
  3. Không đọc và hiểu các khái niệm cơ sở dữ liệu nâng cao hơn (chỉ mục, chỉ mục cụm, ràng buộc, quan điểm cụ thể hóa, v.v.)
  4. Không kiểm tra khả năng mở rộng ... dữ liệu thử nghiệm chỉ có 3 hoặc 4 hàng sẽ không bao giờ cung cấp cho bạn hình ảnh thực sự về hiệu suất trực tiếp thực

1
Tôi thứ hai, rất nhiều, # 1 và # 2. Bất cứ khi nào tôi thực hiện thay đổi đối với DB, tôi kết xuất lược đồ của nó và phiên bản nó; Tôi có ba thiết lập cơ sở dữ liệu, một dev, một staging và một live - KHÔNG CÓ bao giờ được "thử nghiệm" trên DB trực tiếp !!
Ixmatus

Tại Red Gate, chúng tôi đã thực hiện các bước để cải thiện điểm đầu tiên của bạn với Kiểm soát nguồn SQL! Từ những cuộc trò chuyện tôi đã có trong quá trình nghiên cứu, tôi nghĩ mọi người không còn phát triển dựa trên cơ sở dữ liệu sản xuất nữa, nhưng thường thì các bản sửa lỗi "khẩn cấp" được thực hiện mà thường tìm đường quay trở lại môi trường phát triển, đó là một vấn đề khác.
David Atkinson

46

Sử dụng quá mức và / hoặc phụ thuộc vào các thủ tục được lưu trữ.

Một số nhà phát triển ứng dụng xem các thủ tục được lưu trữ như một phần mở rộng trực tiếp của mã tầng giữa / mặt trước. Điều này dường như là một đặc điểm phổ biến trong các nhà phát triển ngăn xếp của Microsoft, (tôi là một, nhưng tôi đã phát triển từ đó) và tạo ra nhiều quy trình được lưu trữ để thực hiện logic nghiệp vụ và xử lý quy trình công việc phức tạp. Điều này được thực hiện tốt hơn nhiều ở nơi khác.

Các thủ tục được lưu trữ rất hữu ích khi đã được chứng minh một cách chính xác rằng một số yếu tố kỹ thuật thực sự cần phải sử dụng chúng (ví dụ: hiệu suất và bảo mật) Ví dụ: giữ tập hợp / lọc các tập dữ liệu lớn "gần với dữ liệu".

Gần đây tôi đã phải giúp duy trì và nâng cao một ứng dụng máy tính để bàn Delphi lớn, trong đó 70% logic và quy tắc kinh doanh được triển khai trong 1400 thủ tục lưu trữ SQL Server (phần còn lại trong trình xử lý sự kiện UI). Đây là một cơn ác mộng, chủ yếu là do việc giới thiệu thử nghiệm đơn vị hiệu quả cho TSQL, thiếu đóng gói và các công cụ kém (Trình gỡ lỗi, biên tập viên).

Làm việc với một nhóm Java trong quá khứ tôi nhanh chóng phát hiện ra rằng thường thì hoàn toàn ngược lại trong môi trường đó. Một kiến ​​trúc sư Java đã từng nói với tôi: "Cơ sở dữ liệu dành cho dữ liệu, không phải mã.".

Ngày nay tôi nghĩ thật sai lầm khi không xem xét các procs được lưu trữ, nhưng chúng nên được sử dụng một cách tiết kiệm (không phải mặc định) trong các tình huống mà chúng cung cấp các lợi ích hữu ích (xem các câu trả lời khác).


4
Các thủ tục được lưu trữ có xu hướng trở thành một hòn đảo bị tổn thương trong bất kỳ dự án nào được sử dụng, do đó một số nhà phát triển đưa ra quy tắc "Không có thủ tục được lưu trữ". Vì vậy, có vẻ như có một cuộc xung đột mở đặt cược cho họ. Câu trả lời của bạn làm cho một trường hợp tốt khi thực sự chọn một cách, hoặc cách khác.
Warren P

Lợi ích: bảo mật - bạn không phải cung cấp cho ứng dụng khả năng "xóa * khỏi ..."; chỉnh sửa - DBA có thể điều chỉnh các truy vấn mà không phải biên dịch lại / triển khai toàn bộ ứng dụng; phân tích - thật dễ dàng để biên dịch lại một loạt các procs sau khi thay đổi mô hình dữ liệu để đảm bảo chúng vẫn còn hiệu lực; và cuối cùng, việc xem xét SQL được thực thi bởi công cụ cơ sở dữ liệu (không phải ứng dụng của bạn) thì khái niệm "cơ sở dữ liệu là dành cho dữ liệu, không phải mã" chỉ bị trì hoãn.
NotMe

Vì vậy, bạn sẽ đưa ra logic kinh doanh của mình trong giao diện người dùng, nơi nó được tách ra khỏi dữ liệu bị thao túng? Đây dường như không phải là một ý tưởng hay, đặc biệt là thao tác dữ liệu hiệu quả nhất khi được thực hiện bởi máy chủ cơ sở dữ liệu thay vì các chuyến đi khứ hồi từ UI. Điều đó cũng có nghĩa là việc kiểm soát ứng dụng khó khăn hơn vì bạn không thể dựa vào cơ sở dữ liệu kiểm soát dữ liệu của ứng dụng và có khả năng có các phiên bản UI khác nhau ngoài kia với các thao tác dữ liệu khác nhau đang diễn ra. Không tốt. Tôi không để bất cứ thứ gì chạm vào dữ liệu của mình ngoại trừ thông qua thủ tục được lưu trữ.
David T. Macknet

Nếu có nhu cầu tách logic kinh doanh khỏi UI, kiến ​​trúc đa tầng có thể được sử dụng. Hoặc, một thư viện với các đối tượng kinh doanh và logic, được sử dụng bởi các ứng dụng / UI khác nhau. Các thủ tục được lưu trữ sẽ khóa dữ liệu / logic nghiệp vụ của bạn vào một cơ sở dữ liệu cụ thể, việc thay đổi cơ sở dữ liệu trong trường hợp này rất tốn kém. Và chi phí rất lớn là xấu.
quá

@too: Thay đổi cơ sở dữ liệu trong hầu hết các trường hợp là rất tốn kém. Không bao giờ nghĩ đến việc mất đi các tính năng hiệu suất và bảo mật mà một DBMS cụ thể cung cấp. Hơn nữa, các tầng bổ sung thêm độ phức tạp và giảm hiệu suất và các lớp bổ sung được gắn với ngôn ngữ cụ thể của bạn. Cuối cùng, nhiều khả năng ngôn ngữ đang được sử dụng sẽ thay đổi so với máy chủ cơ sở dữ liệu.
NotMe

41

Vấn đề số một? Họ chỉ kiểm tra trên cơ sở dữ liệu đồ chơi. Vì vậy, họ không biết rằng SQL của họ sẽ thu thập dữ liệu khi cơ sở dữ liệu trở nên lớn và ai đó phải đi cùng và sửa nó sau (âm thanh mà bạn có thể nghe thấy là nghiến răng).


2
Kích thước của cơ sở dữ liệu có liên quan, nhưng vấn đề lớn hơn là tải - ngay cả khi bạn kiểm tra dữ liệu thực, bạn không kiểm tra hiệu năng của các truy vấn của mình khi cơ sở dữ liệu đang tải, có thể là một công cụ mở mắt thực sự.
davidcl

Tôi muốn nói rằng kích thước cơ sở dữ liệu là vấn đề lớn hơn tải. Tôi đã thấy nhiều lần, rằng thiếu các chỉ số quan trọng - chưa bao giờ là vấn đề về hiệu năng trong các thử nghiệm, bởi vì toàn bộ cơ sở dữ liệu phù hợp với bộ nhớ
Thủy thủ Danubian


28

Hiệu suất kém gây ra bởi các truy vấn tương quan

Hầu hết thời gian bạn muốn tránh các truy vấn con tương quan. Một truy vấn con có tương quan nếu, trong truy vấn con, có một tham chiếu đến một cột từ truy vấn bên ngoài. Khi điều này xảy ra, truy vấn con được thực hiện ít nhất một lần cho mỗi hàng được trả về và có thể được thực thi nhiều lần hơn nếu các điều kiện khác được áp dụng sau khi điều kiện có chứa truy vấn con tương quan được áp dụng.

Tha thứ cho ví dụ giả định và cú pháp của Oracle, nhưng giả sử bạn muốn tìm tất cả các nhân viên đã được thuê trong bất kỳ cửa hàng nào của bạn kể từ lần cuối cùng cửa hàng bán được ít hơn 10.000 đô la mỗi ngày.

select e.first_name, e.last_name
from employee e
where e.start_date > 
        (select max(ds.transaction_date)
         from daily_sales ds
         where ds.store_id = e.store_id and
               ds.total < 10000)

Truy vấn con trong ví dụ này tương quan với truy vấn bên ngoài bởi store_id và sẽ được thực thi cho mọi nhân viên trong hệ thống của bạn. Một cách mà truy vấn này có thể được tối ưu hóa là chuyển truy vấn con sang chế độ xem nội tuyến.

select e.first_name, e.last_name
from employee e,
     (select ds.store_id,
             max(s.transaction_date) transaction_date
      from daily_sales ds
      where ds.total < 10000
      group by s.store_id) dsx
where e.store_id = dsx.store_id and
      e.start_date > dsx.transaction_date

Trong ví dụ này, truy vấn trong mệnh đề from hiện là dạng xem nội tuyến (một số cú pháp cụ thể của Oracle) và chỉ được thực hiện một lần. Tùy thuộc vào mô hình dữ liệu của bạn, truy vấn này có thể sẽ thực thi nhanh hơn nhiều. Nó sẽ thực hiện tốt hơn truy vấn đầu tiên khi số lượng nhân viên tăng lên. Truy vấn đầu tiên thực sự có thể hoạt động tốt hơn nếu có ít nhân viên và nhiều cửa hàng (và có lẽ nhiều cửa hàng không có nhân viên) và bảng Daily_sales được lập chỉ mục trên store_id. Đây không phải là một kịch bản có khả năng nhưng cho thấy cách truy vấn tương quan có thể thực hiện tốt hơn so với một thay thế.

Tôi đã thấy các nhà phát triển cơ sở tương quan các truy vấn con nhiều lần và nó thường có tác động nghiêm trọng đến hiệu suất. Tuy nhiên, khi loại bỏ một truy vấn con tương quan, hãy chắc chắn xem xét kế hoạch giải thích trước và sau để đảm bảo bạn không làm cho hiệu suất kém hơn.


1
Điểm tuyệt vời và để nhấn mạnh một trong những điểm liên quan của bạn - kiểm tra các thay đổi của bạn. Tìm hiểu cách sử dụng các kế hoạch giải thích (và xem cơ sở dữ liệu thực sự đang làm gì để thực hiện truy vấn của bạn và chi phí là bao nhiêu), thực hiện các thử nghiệm của bạn trên một tập dữ liệu lớn và không làm cho SQL của bạn quá phức tạp và không thể đọc được / không thể hiểu được để tối ưu hóa điều đó không thực sự cải thiện hiệu suất thực sự.
Rob Whelan

21

Theo kinh nghiệm của tôi:
Không giao tiếp với các DBA có kinh nghiệm.


17

Sử dụng Access thay vì cơ sở dữ liệu "thực". Có rất nhiều cơ sở dữ liệu nhỏ và thậm chí miễn phí tuyệt vời như SQL Express , MySQLSQLite sẽ hoạt động và mở rộng quy mô tốt hơn nhiều. Ứng dụng thường cần mở rộng theo những cách bất ngờ.


16

Quên thiết lập mối quan hệ giữa các bảng. Tôi nhớ phải dọn dẹp cái này khi tôi bắt đầu làm việc tại công ty hiện tại.


14

Sử dụng Excel để lưu trữ (số lượng lớn) dữ liệu.

Tôi đã thấy các công ty nắm giữ hàng ngàn hàng và sử dụng nhiều bảng tính (do giới hạn hàng là 65535 trên các phiên bản Excel trước).


Excel rất phù hợp cho các báo cáo, trình bày dữ liệu và các tác vụ khác, nhưng không nên được coi là cơ sở dữ liệu.


14

Tôi muốn thêm: Yêu thích mã "Thanh lịch" hơn mã hiệu suất cao. Mã hoạt động tốt nhất đối với cơ sở dữ liệu thường xấu đối với mắt của nhà phát triển ứng dụng.

Tin rằng vô nghĩa về tối ưu hóa sớm. Cơ sở dữ liệu phải xem xét hiệu suất trong thiết kế ban đầu và trong bất kỳ sự phát triển tiếp theo nào. Hiệu suất là 50% thiết kế cơ sở dữ liệu (40% là toàn vẹn dữ liệu và 10% cuối cùng là bảo mật) theo ý kiến ​​của tôi. Cơ sở dữ liệu không được xây dựng từ dưới lên để thực hiện sẽ hoạt động kém khi người dùng thực và lưu lượng truy cập thực được đặt vào cơ sở dữ liệu. Tối ưu hóa sớm không có nghĩa là không tối ưu hóa! Điều đó không có nghĩa là bạn nên viết mã hầu như sẽ luôn hoạt động kém bởi vì bạn thấy nó dễ dàng hơn (ví dụ, các con trỏ không bao giờ được phép trong cơ sở dữ liệu sản xuất trừ khi tất cả các lỗi khác đều thất bại). Điều đó có nghĩa là bạn không cần nhìn vào việc vắt kiệt chút hiệu suất cuối cùng cho đến khi bạn cần. Rất nhiều điều được biết về những gì sẽ hoạt động tốt hơn trên cơ sở dữ liệu,


2
+1 - Lập trình cơ sở dữ liệu liên quan đến tối ưu hóa hành vi của các thành phần cơ khí. Tuy nhiên, lưu ý rằng Knuth nói rằng tối ưu hóa sớm là gốc rễ của mọi tội lỗi khoảng 97% thời gian (hoặc từ ngữ cho hiệu ứng đó). Thiết kế cơ sở dữ liệu là một lĩnh vực mà bạn thực sự phải suy nghĩ về vấn đề này.
Mối quan tâmOfTunbridgeWells

2
Ahem ... những gì bạn đang nói là tối ưu hóa không sớm. Một số xem xét về việc sử dụng thực sự được yêu cầu ngay từ đầu trong thiết kế cơ sở dữ liệu (và thiết kế ứng dụng cũng vậy). Quy tắc của Knuth thực sự không tầm thường để tuân theo, bởi vì bạn phải quyết định những gì sớm và những gì không - thực sự bắt nguồn từ "không thực hiện tối ưu hóa mà không có dữ liệu". Các quyết định liên quan đến hiệu suất ban đầu mà bạn đang nói đến dữ liệu - một số thiết kế nhất định sẽ đặt ra các giới hạn không thể chấp nhận được đối với hiệu suất trong tương lai và bạn có thể tính toán chúng.
Rob Whelan

13

Không sử dụng truy vấn tham số. Chúng khá tiện dụng trong việc ngăn chặn SQL Injection .

Đây là một ví dụ cụ thể về việc không vệ sinh dữ liệu đầu vào, được đề cập trong câu trả lời khác.


3
Ngoại trừ vệ sinh đầu vào là sai. Vệ sinh ngụ ý đặt nó ở một nơi nào đó có thể nguy hiểm. Tham số hóa có nghĩa là giữ nó ra khỏi con đường gây hại hoàn toàn.
Dustin

12

Tôi ghét nó khi các nhà phát triển sử dụng các câu lệnh chọn lồng nhau hoặc thậm chí các hàm trả về kết quả của câu lệnh chọn bên trong phần "CHỌN" của truy vấn.

Tôi thực sự ngạc nhiên Tôi không thấy điều này ở bất cứ nơi nào khác ở đây, có lẽ tôi đã bỏ qua nó, mặc dù @adam có một vấn đề tương tự được chỉ ra.

Thí dụ:

SELECT
    (SELECT TOP 1 SomeValue FROM SomeTable WHERE SomeDate = c.Date ORDER BY SomeValue desc) As FirstVal
    ,(SELECT OtherValue FROM SomeOtherTable WHERE SomeOtherCriteria = c.Criteria) As SecondVal
FROM
    MyTable c

Trong trường hợp này, nếu MyTable trả về 10000 hàng, kết quả sẽ như thể truy vấn chỉ chạy 20001 truy vấn, vì nó phải chạy truy vấn ban đầu cộng với truy vấn từng bảng khác nhau cho mỗi dòng kết quả.

Các nhà phát triển có thể thoát khỏi công việc này trong môi trường phát triển khi họ chỉ trả về một vài hàng dữ liệu và các bảng phụ thường chỉ có một lượng dữ liệu nhỏ, nhưng trong môi trường sản xuất, loại truy vấn này có thể trở nên tốn kém theo cấp số nhân dữ liệu được thêm vào các bảng.

Một ví dụ tốt hơn (không nhất thiết phải hoàn hảo) sẽ là một cái gì đó như:

SELECT
     s.SomeValue As FirstVal
    ,o.OtherValue As SecondVal
FROM
    MyTable c
    LEFT JOIN (
        SELECT SomeDate, MAX(SomeValue) as SomeValue
        FROM SomeTable 
        GROUP BY SomeDate
     ) s ON c.Date = s.SomeDate
    LEFT JOIN SomeOtherTable o ON c.Criteria = o.SomeOtherCriteria

Điều này cho phép các trình tối ưu hóa cơ sở dữ liệu trộn lẫn dữ liệu lại với nhau, thay vì yêu cầu trên mỗi bản ghi từ bảng chính và tôi thường tìm thấy khi phải sửa mã khi sự cố này được tạo, tôi thường kết thúc việc tăng tốc độ truy vấn lên 100% hoặc nhiều hơn trong khi đồng thời giảm sử dụng CPU và bộ nhớ.


12

Đối với cơ sở dữ liệu dựa trên SQL:

  1. Không tận dụng các INDEX CLUSTERED hoặc chọn (các) cột sai cho CLUSTER.
  2. Không sử dụng kiểu dữ liệu SERIAL (autonumber) làm KEY PRIMARY để tham gia vào FOREIGN KEY (INT) trong mối quan hệ bảng cha / con.
  3. Không CẬP NHẬT THỐNG KÊ trên bảng khi nhiều bản ghi đã được CHỨNG MINH hoặc XÓA.
  4. Không sắp xếp lại các bảng (nghĩa là dỡ, thả, tạo lại, tải và lập chỉ mục lại) khi nhiều hàng đã được chèn hoặc xóa (một số động cơ giữ các hàng bị xóa trong một bảng có cờ xóa.)
  5. Không tận dụng FRAGMENT TRÊN EXPRESSION (nếu được hỗ trợ) trên các bảng lớn có tỷ lệ giao dịch cao.
  6. Chọn sai kiểu dữ liệu cho một cột!
  7. Không chọn một tên cột thích hợp.
  8. Không thêm các cột mới ở cuối bảng.
  9. Không tạo các chỉ mục thích hợp để hỗ trợ các truy vấn được sử dụng thường xuyên.
  10. tạo các chỉ mục trên các cột với một vài giá trị có thể và tạo các chỉ mục không cần thiết.
    ... thêm để được thêm vào.

1
Một ngụy biện: 2) thực sự là thực hành xấu. Tôi thấy những gì bạn đang nhận được - bạn muốn có một chỉ mục duy nhất trên số tự động đó và sử dụng nó làm khóa thay thế. Nhưng khóa chính không phải là số tự động, vì đó không phải là khóa chính IS: khóa chính là "bản ghi là gì", (ngoại trừ những thứ như giao dịch bán hàng) KHÔNG phải là số tự động, mà là một số bit duy nhất thông tin về các thực thể được mô hình hóa.
David T. Macknet

lý do chính cho việc sử dụng số tự động cho khóa chính và khóa ngoài là để đảm bảo rằng phép nối giữa cha mẹ và con có thể được duy trì bất kể thay đổi trong bất kỳ cột nào khác. sử dụng khóa chính khác, như tên khách hàng hoặc dữ liệu khác có thể gặp rủi ro!
Frank R.

@David: Tôi đã sửa chữa! cột là một chính có ý nghĩa để xác định vị trí hàng!
Frank R.

Đó là một vấn đề về ngữ nghĩa, vào cuối ngày ... và Microsoft thích các khóa chính là vô nghĩa, hơn là có ý nghĩa. Những cuộc tranh luận xung quanh nó nổi giận, nhưng tôi rơi vào trại "có ý nghĩa". :)
David T. Macknet

9
  • Không sao lưu trước khi sửa một số vấn đề bên trong cơ sở dữ liệu sản xuất.

  • Sử dụng các lệnh DDL trên các đối tượng được lưu trữ (như bảng, dạng xem) trong các thủ tục được lưu trữ.

  • Sợ sử dụng Proc được lưu trữ hoặc sợ sử dụng truy vấn ORM ở bất cứ nơi nào hiệu quả hơn / phù hợp để sử dụng.

  • Bỏ qua việc sử dụng một trình lược tả cơ sở dữ liệu, có thể cho bạn biết chính xác truy vấn ORM của bạn cuối cùng được chuyển thành gì và do đó xác minh logic hoặc thậm chí để gỡ lỗi khi không sử dụng ORM.


8

Không làm đúng mức bình thường hóa . Bạn muốn đảm bảo rằng dữ liệu không bị trùng lặp và bạn sẽ chia dữ liệu thành khác nhau khi cần. Bạn cũng cần đảm bảo rằng bạn không theo dõi quá trình bình thường hóa vì điều đó sẽ ảnh hưởng đến hiệu suất.


Làm thế nào đến nay là quá xa? Nếu không có dữ liệu nào bị trùng lặp, làm thế nào bạn có thể đưa nó đi xa hơn?
Finnw

Bình thường hóa là sự cân bằng của việc loại bỏ dữ liệu dư thừa và tăng tính linh hoạt so với hiệu suất giảm và độ phức tạp tăng. Tìm sự cân bằng chính xác cần kinh nghiệm và nó thay đổi theo thời gian. Xem en.wikipedia.org/wiki/Database_n normalization để biết thông tin về thời điểm không chuẩn hóa
Nathan Voxland

8

Coi cơ sở dữ liệu chỉ là một cơ chế lưu trữ (tức là thư viện bộ sưu tập được tôn vinh) và do đó phụ thuộc vào ứng dụng của họ (bỏ qua các ứng dụng khác có chung dữ liệu)


Một hệ quả của việc này là giảm tải quá nhiều công việc truy vấn cho ứng dụng thay vì giữ nó trong db nơi nó thuộc về. LINQ đặc biệt xấu về điều này.
3Dave

8
  • Loại bỏ một ORM như Hibernate ra khỏi tay, vì những lý do như "nó quá kỳ diệu" hoặc "không có trong cơ sở dữ liệu của tôi ".
  • Dựa quá nhiều vào một ORM như Hibernate và cố gắng đánh bóng nó ở nơi không phù hợp.

8

1 - Không cần thiết sử dụng hàm trên một giá trị trong mệnh đề where với kết quả của chỉ mục đó không được sử dụng.

Thí dụ:

where to_char(someDate,'YYYYMMDD') between :fromDate and :toDate

thay vì

where someDate >= to_date(:fromDate,'YYYYMMDD') and someDate < to_date(:toDate,'YYYYMMDD')+1

Và ở mức độ thấp hơn: Không thêm các chỉ mục chức năng vào các giá trị cần chúng ...

2 - Không thêm các ràng buộc kiểm tra để đảm bảo tính hợp lệ của dữ liệu. Các ràng buộc có thể được sử dụng bởi trình tối ưu hóa truy vấn và chúng THỰC SỰ giúp đỡ để đảm bảo rằng bạn có thể tin tưởng vào bất biến của mình. Không có lý do gì để không sử dụng chúng.

3 - Thêm các cột không chuẩn hóa vào các bảng khỏi sự lười biếng thuần túy hoặc áp lực thời gian. Mọi thứ thường không được thiết kế theo cách này, nhưng phát triển thành này. Kết quả cuối cùng, không có thất bại, là một tấn công việc cố gắng dọn dẹp mớ hỗn độn khi bạn bị cắn bởi tính toàn vẹn dữ liệu bị mất trong các diễn biến trong tương lai.

Hãy nghĩ về điều này, một bảng không có dữ liệu rất rẻ để thiết kế lại. Một bảng có vài triệu bản ghi không có tính toàn vẹn ... không quá rẻ để thiết kế lại. Do đó, thực hiện thiết kế chính xác khi tạo cột hoặc bảng được khấu hao theo tỷ lệ.

4 - không quá nhiều về cơ sở dữ liệu mỗi se nhưng thực sự gây phiền nhiễu. Không quan tâm đến chất lượng mã của SQL. Thực tế là SQL của bạn được thể hiện bằng văn bản không giúp bạn ẩn logic trong hàng đống thuật toán thao tác chuỗi. Hoàn toàn có thể viết SQL bằng văn bản theo cách mà người lập trình viên của bạn thực sự có thể đọc được.


7

Điều này đã được nói trước đây, nhưng: chỉ mục, chỉ mục, chỉ mục . Tôi đã thấy rất nhiều trường hợp ứng dụng web doanh nghiệp hoạt động kém đã được khắc phục bằng cách chỉ cần thực hiện một chút hồ sơ (để xem bảng nào đang bị ảnh hưởng nhiều), sau đó thêm chỉ mục vào các bảng đó. Điều này thậm chí không đòi hỏi nhiều về kiến ​​thức viết SQL và mức chi trả là rất lớn.

Tránh trùng lặp dữ liệu như bệnh dịch hạch. Một số người ủng hộ rằng một chút trùng lặp sẽ không bị tổn thương và sẽ cải thiện hiệu suất. Xin chào, tôi không nói rằng bạn phải tra tấn lược đồ của mình thành Dạng thông thường thứ ba, cho đến khi nó quá trừu tượng đến nỗi ngay cả DBA cũng không biết chuyện gì đang xảy ra. Chỉ cần hiểu rằng bất cứ khi nào bạn sao chép một tập hợp tên hoặc mã zip hoặc mã vận chuyển, các bản sao SILL sẽ không đồng bộ với nhau. Nó sẽ xảy ra. Và sau đó bạn sẽ tự đá mình khi bạn chạy tập lệnh bảo trì hàng tuần.

Và cuối cùng: sử dụng một quy ước đặt tên rõ ràng, nhất quán, trực quan. Theo cùng một cách mà một đoạn mã được viết tốt sẽ có thể đọc được, một lược đồ hoặc truy vấn SQL tốt sẽ có thể đọc được và thực tế cho bạn biết những gì nó đang làm, ngay cả khi không có nhận xét. Bạn sẽ cảm ơn bản thân trong sáu tháng, khi bạn phải bảo trì trên bàn. "SELECT account_number, billing_date FROM national_accounts"làm việc với vô cùng dễ dàng hơn so với "CHỌN ACCNTNBR, BILLDAT TỪ NTNLACCTS".


Nếu bạn thiết lập chúng một cách chính xác thì chúng sẽ không nhưng điều này liên quan đến việc sử dụng các kích hoạt mà nhiều người bị dị ứng.
HLGEM

6

Không thực hiện truy vấn CHỌN tương ứng trước khi chạy truy vấn XÓA (đặc biệt là trên cơ sở dữ liệu sản xuất)!


5

Lỗi phổ biến nhất tôi từng thấy trong hai mươi năm: không lên kế hoạch trước. Nhiều nhà phát triển sẽ tạo cơ sở dữ liệu và các bảng, sau đó liên tục sửa đổi và mở rộng các bảng khi họ xây dựng các ứng dụng. Kết quả cuối cùng thường là một mớ hỗn độn và không hiệu quả và khó làm sạch hoặc đơn giản hóa sau này.


1
Tôi có thể tưởng tượng sự khủng khiếp xảy ra trong những tình huống này ... Cơ sở dữ liệu Schemaless phù hợp hơn nhiều cho việc tạo mẫu nhanh và phát triển lặp, nhưng giống như mọi thứ khác, sự linh hoạt như vậy đi kèm với sự đánh đổi khác nhau.
Zsolt Török

4

a) Các giá trị
truy vấn mã hóa cứng trong chuỗi b) Đưa mã truy vấn cơ sở dữ liệu vào hành động "OnButtonPress" trong ứng dụng Windows Forms

Tôi đã thấy cả hai.


4
"Đặt mã truy vấn DB trong hành động" OnButtonPress "trong ứng dụng Windows Form" Lỗi cơ sở dữ liệu ở đây là gì?
đệ quy

@recursive: đó là một lỗ hổng SQL SQL rất lớn. Bất cứ ai cũng có thể gửi SQL tùy ý đến máy chủ của bạn và nó sẽ được chạy nguyên văn.
Bill Karwin

Đồng ý với @recursive. Chúng thực sự không liên quan gì đến các vấn đề DB.
p.campbell

b) là một lỗi kiến ​​trúc. Tất nhiên, dù sao đi nữa, mã hóa truy vấn trực tiếp trong ứng dụng của bạn là một ý tưởng tồi.
3Dave

4

Không chú ý đầy đủ đến việc quản lý các kết nối cơ sở dữ liệu trong ứng dụng của bạn. Sau đó, bạn tìm ra ứng dụng, máy tính, máy chủ và mạng bị tắc.


4
  1. Nghĩ rằng họ là các DBA và nhà thiết kế / mô hình dữ liệu khi họ không có sự truyền bá chính thức dưới bất kỳ hình thức nào trong các lĩnh vực đó.

  2. Nghĩ rằng dự án của họ không yêu cầu DBA vì những thứ đó hoàn toàn dễ dàng / tầm thường.

  3. Thất bại trong việc phân biệt chính xác giữa các công việc nên được thực hiện trong cơ sở dữ liệu và công việc nên được thực hiện trong ứng dụng.

  4. Không xác nhận sao lưu, hoặc không sao lưu.

  5. Nhúng SQL thô vào mã của họ.



3

Không có hiểu biết về mô hình đồng thời cơ sở dữ liệu và làm thế nào điều này ảnh hưởng đến sự phát triển. Thật dễ dàng để thêm các chỉ mục và điều chỉnh các truy vấn sau khi thực tế. Tuy nhiên, các ứng dụng được thiết kế mà không có sự xem xét thích hợp cho các điểm nóng, tranh chấp tài nguyên và hoạt động chính xác (Giả sử những gì bạn vừa đọc vẫn hợp lệ!) Có thể yêu cầu thay đổi đáng kể trong cơ sở dữ liệu và tầng ứng dụng để sửa sau.


3

Không hiểu làm thế nào một DBMS hoạt động dưới mui xe.

Bạn không thể lái gậy đúng cách mà không hiểu cách ly hợp hoạt động. Và bạn không thể hiểu làm thế nào để sử dụng Cơ sở dữ liệu mà không hiểu rằng bạn thực sự chỉ đang ghi vào một tệp trên đĩa cứng của bạn.

Đặc biệt:

  1. Bạn có biết Chỉ số cụm là gì không? Bạn đã nghĩ về nó khi bạn thiết kế lược đồ của bạn?

  2. Bạn có biết làm thế nào để sử dụng chỉ mục đúng cách? Làm thế nào để sử dụng lại một chỉ mục? Bạn có biết Chỉ số bao phủ là gì không?

  3. Thật tuyệt vời, bạn có chỉ số. Làm thế nào lớn là 1 hàng trong chỉ mục của bạn? Chỉ số sẽ lớn đến mức nào khi bạn có nhiều dữ liệu? Điều đó sẽ dễ dàng phù hợp với bộ nhớ? Nếu nó không vô dụng như một chỉ mục.

  4. Bạn đã bao giờ sử dụng GIẢI THÍCH trong MySQL chưa? Tuyệt quá. Bây giờ hãy thành thật với chính mình: Bạn đã hiểu một nửa những gì bạn đã thấy chưa? Không, bạn có thể đã không. Khắc phục điều đó.

  5. Bạn có hiểu Cache truy vấn không? Bạn có biết điều gì làm cho một truy vấn không lưu trữ được không?

  6. Bạn đang sử dụng MyISAM? Nếu bạn CẦN tìm kiếm toàn văn, MyISAM's dù sao cũng là rác rưởi. Sử dụng nhân sư. Sau đó chuyển sang Inno.


2
Một sự tương tự tốt hơn có thể là người ta không thể khắc phục sự cố truyền dẫn thủ công mà không hiểu về ly hợp. Rất nhiều người lái xe đúng cách mà không biết cách ly hợp hoạt động.
Michael Easter

3
  1. Sử dụng ORM để cập nhật hàng loạt
  2. Chọn nhiều dữ liệu hơn mức cần thiết. Một lần nữa, thường được thực hiện khi sử dụng ORM
  3. Bắn sqls trong một vòng lặp.
  4. Không có dữ liệu thử nghiệm tốt và nhận thấy sự suy giảm hiệu suất chỉ trên dữ liệu trực tiếp.
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.