标签:mysql foreign-keys records referential-integrity
有没有办法,当你有一个记录列表时,在你试图删除任何这些记录之前检查这些记录是否都有外键引用?
例如,如果我有一份借款人名单和一份书籍清单,如果他还有借书,你就不应该从系统中删除借款人. (我的实际系统比那复杂得多 – 更多的表格.)
我想删除任何有借书的借款人的删除选项(在该示例中).
如果我尝试删除带有外键引用的记录,我会收到一个错误:
Database access failed: Cannot delete or update a parent row: a foreign key constraint fails (
dbname
.tablename
, CONSTRAINTfkfieldid
FOREIGN KEY (fieldid
) REFERENCEStablename
(fieldid
))
一种解决方案是编写查询以检查记录列表中的每个记录是否在可以引用的任何可能表中具有任何外键引用.
但是,如果我希望在我的内容管理系统中显示来自表中的100条记录的列表,并且我必须运行100个子查询才能显示该列表,那么它显然效率很低!
最终用户在尝试删除记录时会感到困惑,但他们不能,因为这些数据在其他地方“正在使用”,所以我宁愿删除删除选项以避免混淆.
关于什么是最好的事情的任何想法?
谢谢.
解决方法:
您可以使用子查询或连接轻松完成此操作.
即.子查询
SELECT B.*, (SELECT COUNT(*) FROM loans L WHERE L.book_id = b.id) loan_count
FROM books B
或加入(请注意,如果您允许多个同时发放的贷款,此类图书将在结果中出现多次):
SELECT B.*, L.book_id AS loaned_out_if_not_null
FROM books B
LEFT JOIN loans L ON B.id = L.book_id
这当然可以通过GROUP BY缩短:
SELECT B.id, B.name, COUNT(L.book_id) AS loan_count
FROM books B
LEFT JOIN loans L ON B.id = L.book_id
GROUP BY B.id, B.name
如果您的数据库引擎支持CASE,则可以通过将结果与DISTINCT结合来避免结果中的多行(当然,DISTINCT也有开销):
SELECT DISTINCT B.*,
CASE WHEN L.book_id IS NOT NULL THEN 1 ELSE 0 END AS loaned_out_if_one
FROM books B
LEFT JOIN loans L ON B.id = L.book_id
其中,我会使用GROUP BY变体.
标签:mysql,foreign-keys,records,referential-integrity 来源: https://codeday.me/bug/20190705/1384197.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。