Khi nào nên sử dụng CẬP NHẬT


420

Tôi sử dụng "TRÊN XÓA CASCADE" thường xuyên nhưng tôi không bao giờ sử dụng "TRÊN CẬP NHẬT CASCADE" vì tôi không chắc chắn trong tình huống nào nó sẽ hữu ích.

Để thảo luận, hãy xem một số mã.

CREATE TABLE parent (
    id INT NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (id)
);

CREATE TABLE child (
    id INT NOT NULL AUTO_INCREMENT, parent_id INT,
    INDEX par_ind (parent_id),
    FOREIGN KEY (parent_id)
        REFERENCES parent(id)
        ON DELETE CASCADE
);

Đối với "BẬT XÓA CASCADE", nếu cha mẹ có một idbị xóa, một bản ghi trong con với parent_id = parent.idsẽ tự động bị xóa. Điều này sẽ không có vấn đề.

  1. Điều này có nghĩa là "TRÊN CẬP NHẬT CASCADE" sẽ làm điều tương tự khi idcha mẹ được cập nhật?

  2. Nếu (1) là đúng, điều đó có nghĩa là không cần sử dụng "TRÊN CẬP NHẬT CASCADE" nếu parent.idkhông thể cập nhật (hoặc sẽ không bao giờ được cập nhật) như khi nó AUTO_INCREMENTluôn luôn được đặt thành TIMESTAMP. Có đúng không?

  3. Nếu (2) không đúng, trong trường hợp nào khác, chúng ta nên sử dụng "TRÊN CẬP NHẬT CASCADE"?

  4. Điều gì sẽ xảy ra nếu tôi (vì một số lý do) cập nhật thành child.parent_idmột thứ không tồn tại, sau đó nó sẽ tự động bị xóa?

Vâng, tôi biết, một số câu hỏi ở trên có thể được kiểm tra theo chương trình để hiểu nhưng tôi cũng muốn biết liệu đây có phải là nhà cung cấp cơ sở dữ liệu hay không.

Xin hãy làm sáng tỏ.


Câu trả lời:


468

Đúng là nếu khóa chính của bạn chỉ là giá trị nhận dạng tự động tăng lên, bạn sẽ không có sử dụng thực sự cho ON CẬP NHẬT CASCADE.

Tuy nhiên, giả sử rằng khóa chính của bạn là mã vạch UPC 10 chữ số và vì mở rộng, bạn cần thay đổi nó thành mã vạch UPC 13 chữ số. Trong trường hợp đó, TRÊN CẬP NHẬT CASCADE sẽ cho phép bạn thay đổi giá trị khóa chính và bất kỳ bảng nào có tham chiếu khóa ngoài đến giá trị sẽ được thay đổi tương ứng.

Trong tham chiếu đến # 4, nếu bạn thay đổi ID con thành một cái gì đó không tồn tại trong bảng cha mẹ (và bạn có tính toàn vẹn tham chiếu), bạn sẽ gặp lỗi khóa ngoại.


6
Chỉ cần sử dụng ON UPDATE CASCADEbản thân để cập nhật các khóa chính trong một bảng cũ không sử dụng khóa tăng tự động
BlueRaja - Danny Pflughoeft

86
  1. Có, điều đó có nghĩa là ví dụ: nếu bạn làm UPDATE parent SET id = 20 WHERE id = 10tất cả trẻ em Parent_id thì 10 cũng sẽ được cập nhật thành 20

  2. Nếu bạn không cập nhật trường mà khóa ngoại tham chiếu, cài đặt này không cần thiết

  3. Không thể nghĩ ra cách sử dụng nào khác.

  4. Bạn không thể làm điều đó vì ràng buộc khóa ngoại sẽ thất bại.


29

Tôi nghĩ rằng bạn đã đóng đinh rất nhiều điểm!

Nếu bạn tuân theo các thực tiễn tốt nhất về thiết kế cơ sở dữ liệu và khóa chính của bạn không bao giờ có thể cập nhật được (điều mà tôi nghĩ luôn luôn phải như vậy), thì bạn không bao giờ thực sự cần ON UPDATE CASCADEmệnh đề.

Zed đã nói rõ rằng, nếu bạn sử dụng khóa tự nhiên (ví dụ: trường thông thường từ bảng cơ sở dữ liệu của bạn) làm khóa chính, thì có thể có một số tình huống bạn cần cập nhật khóa chính. Một ví dụ khác gần đây sẽ là ISBN (Số sách tiêu chuẩn quốc tế) đã thay đổi từ 10 thành 13 chữ số + ký tự cách đây không lâu.

Đây không phải là trường hợp nếu bạn chọn sử dụng các khóa thay thế (ví dụ như được tạo ra một cách nhân tạo) làm khóa chính của bạn (sẽ là lựa chọn ưa thích của tôi trong tất cả các trường hợp trừ những trường hợp hiếm gặp nhất).

Vì vậy, cuối cùng: nếu khóa chính của bạn không bao giờ thay đổi, thì bạn không bao giờ cần ON UPDATE CASCADEmệnh đề.

Marc


Các phím "nhân tạo do hệ thống tạo ra" là gì? UUID?
HPWD

1
@HPWD: chỉ là khóa "nhân tạo" (giá trị không dựa trên hoặc xuất phát từ dữ liệu thực tế của bạn) do hệ thống tạo ra - đó có thể là GUID, hoặc INT hoặc BIGINT - hoặc bất cứ điều gì thực sự - không vấn đề Điểm chính là: giá trị đó không liên quan đến dữ liệu thực tế của bạn - và hệ thống đang tự động tạo ra giá trị đó cho bạn.
marc_s

@ marc-s cảm ơn bạn đã dành thời gian để viết nó ra. Câu trả lời của bạn làm cho ý nghĩa hoàn hảo.
HPWD

2
Theo tôi, một bảng một cột với các khóa tự nhiên là một sự thay thế tốt và rõ ràng cho các enum theo quan điểm của tôi (ít nhất là trong các hương vị MySQL DB). Ví dụ, hãy xem xét một bảng colorsvới hàng blue, purple, yellow, và một bảng productsvới một product_colorcột, là FK'ed vào colorsbảng. Điều đó hạn chế các lựa chọn như enum, nhưng không giống như số nguyên tăng tự động, nó không yêu cầu tham gia để có được tên màu. Trong trường hợp như vậy, on update cascadelà một ý tưởng tốt, nếu bạn quyết định purplenên được gọi violetthay thế.
okdewit

18

Vài ngày trước tôi đã gặp vấn đề với các yếu tố kích hoạt và tôi đã tìm ra rằng nó ON UPDATE CASCADEcó thể hữu ích. Hãy xem ví dụ này (PostgreSQL):

CREATE TABLE club
(
    key SERIAL PRIMARY KEY,
    name TEXT UNIQUE
);

CREATE TABLE band
(
    key SERIAL PRIMARY KEY,
    name TEXT UNIQUE
);

CREATE TABLE concert
(
    key SERIAL PRIMARY KEY,
    club_name TEXT REFERENCES club(name) ON UPDATE CASCADE,
    band_name TEXT REFERENCES band(name) ON UPDATE CASCADE,
    concert_date DATE
);

Trong vấn đề của mình, tôi đã phải xác định một số thao tác bổ sung (kích hoạt) để cập nhật bảng của buổi hòa nhạc. Các hoạt động đó đã phải sửa đổi club_name và band_name. Tôi đã không thể làm điều đó, vì tham khảo. Tôi không thể sửa đổi buổi hòa nhạc và sau đó đối phó với các câu lạc bộ và ban nhạc. Tôi cũng không thể làm theo cách khác. ON UPDATE CASCADElà chìa khóa để giải quyết vấn đề.


3
Nhận xét tốt. Tôi thấy trên tầng cập nhật cũng hữu ích, trong mọi trường hợp bạn phải thay đổi ID của mình. Tôi cũng đồng ý với những người khác rằng sự thay đổi này không nên quá điển hình. Ví dụ, trong trường hợp bạn trích dẫn, tôi nghĩ rằng trong khối lượng dữ liệu lớn, có lẽ liên quan đến khóa ngoại sử dụng trường văn bản có thể không dẫn đến hiệu suất nhanh nhất của công cụ cơ sở dữ liệu. Quan sát, rằng nếu quan hệ nước ngoài trong bảng hòa nhạc sử dụng club.SERIAL và band.SERIAL, những thay đổi trong tên sẽ không ảnh hưởng đến mối quan hệ giữa các bảng. Tuy nhiên, tôi thấy TRÊN CẬP NHẬT CASCADE là một công cụ tuyệt vời để giải quyết các trường hợp khẩn cấp. Trân trọng
David L

4
Đây là một thiết kế đáng nghi ngờ, mặc dù là một ví dụ khá giả tạo. Điểm giữ hai SERIALcột trong clubbandlàm khóa chính là gì nếu bạn tham chiếu names thay vì khóa chính của mỗi bảng?
sm

Nói tóm lại, điều này hữu ích nếu bạn sao chép trường từ bảng khác và bạn cần cập nhật.
Kamil Tomšík

4

Nhận xét của tôi chủ yếu liên quan đến điểm # 3: trong trường hợp nào thì CẬP NHẬT CASCADE có thể áp dụng nếu chúng tôi cho rằng khóa cha không thể cập nhật được? Đây là một trường hợp.

Tôi đang xử lý một kịch bản sao chép trong đó nhiều cơ sở dữ liệu vệ tinh cần được hợp nhất với một bản gốc. Mỗi vệ tinh đang tạo dữ liệu trên cùng một bảng, do đó, việc hợp nhất các bảng với chủ sẽ dẫn đến vi phạm ràng buộc về tính duy nhất. Tôi đang cố gắng sử dụng TRÊN CẬP NHẬT CASCADE như một phần của giải pháp trong đó tôi tăng lại các khóa trong mỗi lần hợp nhất. TRÊN CẬP NHẬT CASCADE nên đơn giản hóa quá trình này bằng cách tự động hóa một phần của quy trình.


3

Đó là một câu hỏi xuất sắc, tôi đã có cùng một câu hỏi ngày hôm qua. Tôi đã nghĩ về vấn đề này, cụ thể là TÌM KIẾM nếu tồn tại một cái gì đó như "TRÊN CẬP NHẬT CASCADE" và may mắn thay, các nhà thiết kế của SQL cũng đã nghĩ về điều đó. Tôi đồng ý với Ted.strauss và tôi cũng nhận xét trường hợp của Noran.

Khi nào tôi sử dụng nó? Giống như Ted chỉ ra, khi bạn đang xử lý một số cơ sở dữ liệu cùng một lúc và việc sửa đổi trong một trong số chúng, trong một bảng, có bất kỳ loại sao chép nào trong cái mà Ted gọi là "cơ sở dữ liệu vệ tinh", không thể được giữ nguyên với bản gốc ID và vì bất kỳ lý do nào bạn phải tạo một cái mới, trong trường hợp bạn không thể cập nhật dữ liệu trên cái cũ (ví dụ do quyền hoặc trong trường hợp bạn đang tìm kiếm độ bền trong trường hợp quá nhanh không xứng đáng với sự tôn trọng tuyệt đối và hoàn toàn đối với toàn bộ quy tắc bình thường hóa, đơn giản vì đây sẽ là một tiện ích rất ngắn)

Vì vậy, tôi đồng ý ở hai điểm:

(A.) Có, trong nhiều lần, một thiết kế tốt hơn có thể tránh được nó; NHƯNG

(B.) Trong các trường hợp di chuyển, sao chép cơ sở dữ liệu hoặc giải quyết các trường hợp khẩn cấp, đó là một CÔNG CỤ TUYỆT VỜI may mắn đã ở đó khi tôi đi tìm kiếm nếu nó tồn tại.

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.