Должна ли ссылочная целостность основываться на коде или базе данных? - PullRequest
0 голосов
/ 23 февраля 2020

Мой вопрос о том, как лучше всего обращаться с ссылочной целостностью для внешних ключей. Я кодирую в C# и запрашиваю из MySQL базы данных. Я сейчас решаю, какие ограничения внешнего ключа добавить. Лучше ли встроить ограничения в саму базу данных, или кодировать их, или сочетание обоих? В моем интерфейсе я делал MySqlTransactions в каждом методе, который обновляет таблицу со ссылками на другие таблицы, чтобы убедиться, что все обновляется и удаляется, когда это должно быть. Теоретически, этого должно быть достаточно для поддержания ссылочной целостности. Похоже, что альтернативой этому является установка всех ограничений, чтобы любой вызов таблицы с внешними ссылками обновлялся автоматически. Также кажется, что любая комбинация этих двух способов является причиной катастрофы, поскольку любое каскадное обновление будет и в коде, и в базе данных. Один лучше другого или есть волшебная c формула для их объединения?

Пример:

Я приведу один из моих методов в качестве примера. У меня есть таблица BankAccount и таблица BRN (номер банковского маршрута, который вы можете рассматривать как отделение банка). Таблица BRN состоит из ее идентификатора, номера маршрута и имени филиала. Таблица BankAccount состоит из его идентификатора, номера счета и внешнего ключа идентификатора BRN (помимо прочего, здесь нет ни малейшего значения). Если администратор хочет удалить 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 будет каскадом для его детей.

Я понимаю, что эта проблема может иметь несколько правильных решений, поэтому, возможно, лучший вопрос заключается в следующем: Как мне решить, какое направление лучше для моего проекта?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...