Мой вопрос о том, как лучше всего обращаться с ссылочной целостностью для внешних ключей. Я кодирую в 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 будет каскадом для его детей.
Я понимаю, что эта проблема может иметь несколько правильных решений, поэтому, возможно, лучший вопрос заключается в следующем: Как мне решить, какое направление лучше для моего проекта?