首页 > 解决方案 > 参照完整性应该基于代码还是数据库?

问题描述

我的问题是关于处理外键参照完整性的最佳方法。我正在用 C# 编码并从 MySQL 数据库中查询。我正在决定要添加哪些外键限制。将约束内置到数据库本身中更好,还是对它们进行编码,或者两者兼而有之?在我的界面中,我一直在使用对其他表的引用更新表的每个方法中创建 MySqlTransactions,以确保在应该更新和删除所有内容时更新和删除所有内容。从理论上讲,这应该足以保持参照完整性。似乎另一种方法是设置所有约束,以便对具有外部引用的表的任何调用都会自动更新。似乎两者的任何组合都是灾难的根源,因为任何级联更新都在代码和数据库中。一个比另一个更好,还是有一个神奇的公式可以将它们结合起来?

例子:

我将以我的一种方法为例。我有一个 BankAccount 表和一个 BRN(银行路由号码,您可以将其视为银行分行)表。BRN 表由其 ID、路由号和分支名称组成。BankAccount 表由其 ID、帐号和 BRN ID 外键组成(以及其他一些与此处无关的内容)。如果管理员想要删除 BRN 及其所有子帐户记录,该方法将如下所示:

public void DeleteBRN(long? brnID)
        {
            using (MySqlConnection conn = new MySqlConnection(connStr))
            {
                conn.Open();
                using (MySqlCommand cmd = conn.CreateCommand())
                {
                    try
                    {
                        // (1) Begin Transaction
                        cmd.Transaction = conn.BeginTransaction();

                        // (2) Delete specified BRN row from database

                        if (brnID != null)
                        {
                            deleteBRN_TransactionHelper(brnID, cmd);
                        }
                        else
                        {
                            return;
                        }

                        // (3.1) Get all child bank accounts of specified BRN ID

                        List<BankAccount> accounts = GetAccountsFromBRNID(brnID);

                        // (3.2) Loop through list of accounts and delete each record

                        for (int i = 0; i < accounts.Count; i++)
                        {
                            deleteBankAccount_TransactionHelper(accounts[i].ID, cmd);
                        }

                        // (4) Commit changes

                        // todo check if successful
                        cmd.Transaction.Commit();

                    }
                    catch (Exception e)
                    {
                         // handle / rethrow
                    } 
                    finally
                    {
                        conn.Close();
                    }
                }
            } 
        }

或者,我可以在数据库中添加约束,以便对任何 BRN 记录所做的更改将级联到其子项。

我意识到这个问题可能有多个正确的解决方案,所以也许一个更好的问题是:我如何决定哪个方向最适合我的项目?

标签: mysqlforeign-keysmysql-workbenchreferential-integrity

解决方案


推荐阅读