Không thể cắt bớt bảng được tham chiếu trong ràng buộc khóa ngoại Laravel

Về mặt logic, TRUNCATE TABLE tương đương với câu lệnh DELETE xóa tất cả các hàng, nhưng có những khác biệt thực tế trong một số trường hợp

TRUNCATE TABLE sẽ không thành công đối với bảng InnoDB nếu bất kỳ ràng buộc FOREIGN KEY nào từ các bảng khác tham chiếu đến bảng, trả về lỗi

ERROR 1701 (42000): Cannot truncate a table referenced in a foreign key constraint

Cho phép ràng buộc khóa ngoại giữa các cột trong cùng một bảng

Đối với một bảng InnoDB, nếu không có ràng buộc

ERROR 1701 (42000): Cannot truncate a table referenced in a foreign key constraint
0, InnoDB thực hiện cắt bớt nhanh bằng cách loại bỏ bảng gốc và tạo một bảng trống có cùng định nghĩa, nhanh hơn nhiều so với việc xóa từng hàng một. Bộ đếm AUTO_INCREMENT được đặt lại bởi TRUNCATE TABLE, bất kể có ràng buộc
ERROR 1701 (42000): Cannot truncate a table referenced in a foreign key constraint
0 hay không

Số hàng bị ảnh hưởng bởi TRUNCATE TABLE chỉ chính xác khi nó được ánh xạ tới câu lệnh

ERROR 1701 (42000): Cannot truncate a table referenced in a foreign key constraint
4

Đối với các công cụ lưu trữ khác, TRUNCATE TABLE khác với

ERROR 1701 (42000): Cannot truncate a table referenced in a foreign key constraint
4 theo những cách sau

  • Thao tác cắt bớt, thả và tạo lại bảng, thao tác này nhanh hơn nhiều so với việc xóa từng hàng một, đặc biệt đối với các bảng lớn
  • Các hoạt động cắt bớt gây ra một cam kết ngầm
  • Không thể thực hiện thao tác cắt bớt nếu phiên giữ khóa bảng đang hoạt động
  • Thao tác cắt bớt không trả lại giá trị có ý nghĩa cho số lượng hàng đã xóa. Kết quả thông thường là "0 hàng bị ảnh hưởng" nên được hiểu là "không có thông tin. "
  • Miễn là tệp định dạng bảng
    ERROR 1701 (42000): Cannot truncate a table referenced in a foreign key constraint
    
    7 hợp lệ, bảng có thể được tạo lại dưới dạng bảng trống với TRUNCATE TABLE, ngay cả khi tệp dữ liệu hoặc tệp chỉ mục đã bị hỏng
  • Trình xử lý bảng không nhớ giá trị AUTO_INCREMENT được sử dụng lần cuối nhưng bắt đầu đếm từ đầu. Điều này đúng ngay cả với MyISAM và InnoDB, thường không sử dụng lại các giá trị chuỗi
  • Khi được sử dụng với các bảng được phân vùng, TRUNCATE TABLE bảo toàn việc phân vùng; . par) không bị ảnh hưởng
  • Vì việc cắt bớt một bảng không sử dụng bất kỳ
    ERROR 1701 (42000): Cannot truncate a table referenced in a foreign key constraint
    
    4 nào, nên câu lệnh
    TRUNCATE [TABLE] tbl_name [{DROP | REUSE} STORAGE] [WAIT n | NOWAIT]
    
    1 không gọi trình kích hoạt
    TRUNCATE [TABLE] tbl_name [{DROP | REUSE} STORAGE] [WAIT n | NOWAIT]
    
    2
  • TRUNCATE TABLE sẽ chỉ đặt lại các giá trị trong bảng tóm tắt Lược đồ hiệu suất về 0 hoặc không và sẽ không xóa các hàng

Đối với mục đích ghi nhật ký nhị phân và sao chép, TRUNCATE TABLE được coi là DROP TABLE theo sau là TẠO BẢNG (DDL chứ không phải DML)

TRUNCATE TABLE không hoạt động trên lượt xem. Hiện tại, TRUNCATE TABLE xóa tất cả các bản ghi lịch sử khỏi bảng có phiên bản hệ thống

MariaDB bắt đầu với 10. 3. 0

CHỜ/ĐỢI NGAY

Đặt thời gian chờ khóa. Xem WAIT và NOWAIT

chế độ Oracle

Chế độ Oracle từ MariaDB 10. 3 cho phép sử dụng các từ khóa tùy chọn REUSE STORAGE hoặc DROP STORAGE

TRUNCATE [TABLE] tbl_name [{DROP | REUSE} STORAGE] [WAIT n | NOWAIT]

Chúng không ảnh hưởng đến hoạt động

Hiệu suất

TRUNCATE TABLE nhanh hơn DELETE, vì nó xóa và tạo lại một bảng

Với InnoDB, TRUNCATE TABLE sẽ chậm hơn nếu được đặt (mặc định). Điều này là do TRUNCATE TABLE hủy liên kết tệp không gian bảng bên dưới, đây có thể là một thao tác tốn kém. Xem MDEV-8069 để biết thêm chi tiết

Các vấn đề về hiệu suất có thể trở nên trầm trọng hơn trong trường hợp vùng đệm InnoDB rất lớn và được đặt. Trong trường hợp đó, sử dụng DROP TABLE theo sau là CREATE TABLE thay vì TRUNCATE TABLE có thể hoạt động tốt hơn. Cài đặt (mặc định là BẬT trước MariaDB 10. 5) cũng có thể giúp. Trong MariaDB 10. 2 chỉ, từ MariaDB 10. 2. 19, hiệu suất này cũng có thể được cải thiện bằng cách cài đặt. Xem MDEV-9459 để biết thêm chi tiết

Vì vậy, bạn vào tinker với lệnh php artisan tinker và xóa bảng CartItem bằng CartItem. lệnh cắt ngắn (). Mọi thứ đều ổn và bạn đã xóa tất cả dữ liệu khỏi Bảng CattItem

Sau đó, bạn thử xóa Cart Table bằng Cart. truncate() và bạn sẽ nhận được thông báo lỗi sau

Lỗi cú pháp hoặc vi phạm quyền truy cập. 1701 Không thể cắt bớt bảng được tham chiếu trong ràng buộc khóa ngoại

Hệ thống sẽ ngăn bạn xóa bảng cơ sở dữ liệu vì bảng bạn cố xóa có tham chiếu từ bảng nào đó

Giải pháp

Để tránh sự cố này, bạn chỉ cần vô hiệu hóa kiểm tra nước ngoài này bằng Schema. vô hiệu hóaForeignKeyConstraints();

Vì vậy, kịch bản của bạn sẽ được

Lược đồ. vô hiệu hóaForeignKeyConstraints();

Xe đẩy. cắt ngắn();

Lược đồ. enableForeignKeyConstraints();

Dữ liệu từ bảng Cart sẽ rõ ràng

Vui lòng lưu ý rằng việc này có thể gây ra sự cố cho hệ thống của bạn nếu bạn vẫn có bản ghi đang hoạt động trên bảng con. Cách tiếp cận này chỉ NÊN được sử dụng khi BẢNG CON đã bị xóa