2010-12-22 29 views
11

Tìm kiếm một số thông tin chi tiết về việc liệu quy trình Upsert (chèn hay nếu tồn tại, sau đó cập nhật) được coi là thực hành không tốt trong lập trình cơ sở dữ liệu. Tôi làm việc trong máy chủ SQL nếu có bất kỳ sự liên quan nào.Cơ sở dữ liệu Upserts - Thực hành tốt hay xấu?

Tại một địa điểm tôi đã làm việc cách đây vài tháng, người quản lý cư trú DB guru đã nêu trong các tiêu chuẩn mã hóa db mới được viết (hầu hết trong số đó tôi đã đồng ý), rằng Upserts nên tránh.

Tôi thực sự không thể thấy lý do hợp lý cho điều này, và xem xét ý thức hợp lý của bản thân về thực hành lập trình tốt. Tôi nghĩ rằng chúng hữu ích cho việc quản lý dữ liệu thẳng về phía trước và giúp tránh các số quy trình được lưu trữ quá mức.

Tìm kiếm một số thông tin chi tiết/thảo luận sẽ giúp tôi đi đến kết luận về điều này.

Cảm ơn.

Cập nhật Đáp lại nhận xét:

Bối cảnh cụ thể tôi đề cập đến là việc tạo ra hoặc cập nhật của một đại diện dữ liệu đối tượng miền trong cơ sở dữ liệu. Ví dụ, một đối tượng "Person" tồn tại như một biểu diễn của bảng "Person" trong cơ sở dữ liệu. Tôi chỉ cần một cơ chế để tạo một Người mới hoặc cập nhật một người hiện có. Ở đây tôi có tùy chọn tạo thủ tục lưu sẵn Upsert hoặc hai thủ tục được lưu trữ riêng biệt - một cho Cập nhật và một cho Chèn.

Bất kỳ ưu điểm hay nhược điểm nào trong chế độ xem anyones?

+0

Từ quan điểm của Oracle, thay vào đó hãy sử dụng câu lệnh MERGE. – DCookie

+0

MERGE cũng tồn tại trong SQL Server (2005+ tôi tin) – RPM1984

Trả lời

11

Vấn đề chính là ghi đè lên bản ghi hiện có khi ý định thêm bản ghi mới vì bất kỳ điều gì đã được chọn làm khóa được sao chép. Nói tên đăng nhập chẳng hạn. Bạn thấy thông tin đăng nhập đó tồn tại, do đó bạn cập nhật khi bạn đã khắc phục lỗi khi đăng nhập trùng lặp.

Vấn đề thứ hai là khôi phục bản ghi đã xóa. Nói quá trình "A" truy vấn bản ghi, quá trình "B" xóa nó, và sau đó xử lý "A" gửi một thay đổi. Bản ghi đã được dự định để xóa bây giờ đã trở lại trong cơ sở dữ liệu thay vì chuyển một ngoại lệ về "A" mà nó đã bị xóa.

+0

Cảm ơn, đây là những gì tôi đã làm sau - hai ví dụ tốt về nơi mà loại mã này có thể gây ra vấn đề. – gb2d

1

Phụ thuộc vào những gì bạn nói. Dữ liệu? Vâng, đó là xác định bởi các quy trình thao tác dữ liệu, hay? Nếu tôi cần phải chèn HOẶC cập nhật, thì tôi cần phải làm điều đó. nếu nó là về các đối tượng lược đồ, tương tự.

+1

Thật vậy. Rất ít phương pháp hoặc thực hành là xấu của mình, bối cảnh và logic kinh doanh là hoàn toàn quan trọng ở đây. – Piskvor

+0

Ngữ cảnh cụ thể mà tôi tham chiếu là việc tạo hoặc cập nhật đại diện dữ liệu thực thể miền trong cơ sở dữ liệu. Ví dụ, một đối tượng "Person" tồn tại như một biểu diễn của bảng "Person" trong cơ sở dữ liệu. Tôi chỉ cần một cơ chế để tạo một Người mới hoặc cập nhật một người hiện có. Ở đây tôi có tùy chọn tạo thủ tục lưu sẵn Upsert hoặc hai thủ tục được lưu trữ riêng biệt - một cho Cập nhật và một cho Chèn. – gb2d

+0

Khá thường xuyên tôi có một phương pháp upsert với một tham số cho dù sáng tạo thực sự được cho phép trong trường hợp này (đôi khi tôi không muốn). – TomTom

7

Tôi thích chương trình có mục đích.

Hoặc tôi đang tạo thứ gì đó, trong trường hợp này tôi muốn chèn không thành công (trùng lặp) nếu đã có một thực thể ở đó. Hoặc, tôi đang cập nhật một cái gì đó mà tôi biết là có, trong trường hợp tôi muốn cập nhật thất bại (mà thực sự không xảy ra).

Với upsert/merge this get fuzzy. Tôi đã làm hoặc không thành công? Tôi đã thành công một phần? Một số các giá trị trong hàng là của tôi (từ chèn) và một số trong số họ đã có trước khi?

Có nói rằng, Upserts là hữu ích (đó là lý do tại sao họ đã được thực hiện để bắt đầu với) và cấm chúng sẽ chỉ là ngớ ngẩn. Điều đó giống như cấm các đường vì bọn tội phạm sử dụng chúng để tránh xa cảnh sát. Có một số lượng vô hạn các trường hợp mà upserts là cách duy nhất có thể làm được. Và bất cứ ai đã làm việc với việc đồng bộ hóa dữ liệu giữa các hệ thống đều biết điều này.

0

Phản đối trong ví dụ đầu tiên của hai quy trình - nơi một quá trình thứ hai "phục hồi" bản ghi đã xóa bằng cách thêm một bản ghi mới có cùng khóa - chỉ hợp lệ trong các trường hợp cụ thể do thiết kế kém HOẶC sẽ xảy ra bất kể nếu một thủ tục "upsert" đã viết bản ghi với khóa giống hệt nhau hoặc hai thủ tục riêng biệt đã viết bản ghi được chèn vào.

Trong trường hợp phải tránh khóa giống nhau, khóa nhận dạng tự động gia tăng được sử dụng trong phần chèn. Trong trường hợp không cần phải có khóa giống hệt nhau, thiết kế cơ sở dữ liệu tốt phải được thực hiện để tránh tạo "các kết nối ảo". Ví dụ, trong các số điện thoại của thế giới viễn thông thường được sử dụng lại và là một khóa "duy nhất". Chúng không thể là khóa chính vì người # 2 có thể "kế thừa" số điện thoại nhưng có thể không phải là "kế thừa" hóa đơn chưa thanh toán quá hạn hoặc lịch sử cuộc gọi của người thứ nhất, v.v. các thụt lề độc đáo sẽ được sử dụng trong bất kỳ logic kết nối nào để ngăn chặn chuỗi dữ liệu xấu.

Các vấn đề liên quan