Таблично-независимые иностранные ключи? - PullRequest
3 голосов
/ 24 июня 2009

Сначала я прочитал этот вопрос StackOverflow , поэтому нет необходимости указывать мне на него.

Я сейчас работаю над похожей проблемой. В частности, у меня есть база данных с таблицей аудита, которая используется для хранения информации аудита о других таблицах в БД. Основная форма этой таблицы:

ID, EntityID, EntityTypeID, ActionTypeID, DateTime

Теперь, как вы можете догадаться, универсальный характер EntityID означает, что отношения с внешним ключом к этой таблице и из нее сложны в управлении, особенно если вы используете систему ORM в миксе.

Конечно, решение grunt-work заключается в том, чтобы выполнять необходимые запросы вручную и использовать ORM-компоненты там, где они работают, с чем я в порядке.

Тем не менее, проблема подняла у меня вопрос о том, существует ли там какая-либо СУБД, которая позволяет определять отношение внешнего ключа в форме: Таблица: ID для определения.

Другими словами, в такой СУБД столбец EntityTypeID может содержать такие значения, как

«Таблица A: 1» и «Таблица B: некий ключ»

Итак ...

Есть ли СУБД, которая делает это?

Ответы [ 4 ]

5 голосов
/ 24 июня 2009

Таблицы аудита обычно не могут иметь ограничения ссылочной целостности. Таблица аудита A записывает информацию о строке данных R в некоторой таблице T и содержит серию записей для R, каждая из которых представляет R в определенное время. Когда R впоследствии изменяется, информация в A не изменяется и не может предотвратить изменения в R. Когда R впоследствии удаляется, присутствие записей аудита в A не позволяет остановить это удаление.

1 голос
/ 26 июня 2009

Кстати, очевидно, что вы можете реализовать аналогичную функцию только с помощью СУБД - реализовав некоторую логику, обновляющую структуру таблиц аудита по структуре всех других таблиц. Вы должны:

  1. Извлечение структуры всех таблиц, которые вы собираетесь проверять
  2. Найдите «корни иерархии» между ними: на самом деле вы должны сохранить только таблицы, первичный ключ которых не помечен как внешний ключ в другой стол.
  3. Создание (или реструктуризация) таблиц аудита для каждого из корней иерархии. Здесь вам нужен шаблон со сменным набором столбцов, содержащий ключ исходной таблицы.

Так что в общем, это не простая задача. Даже если у вас есть такой инструмент, как SQL, DOM способен извлечь схему и построить ее части.

0 голосов
/ 26 июня 2009

Я думаю, что ни одна СУБД не поддерживает подобную функцию. Реляционная структура - это то, что вы должны сначала предоставить им, и они обычно не помогают вам ее установить.

С другой стороны, я могу описать замечательную особенность DataObjects.Net, которая довольно тесно связана с этим вопросом: автоматическая регистрация общих экземпляров .

Представьте, что у вас есть 3 постоянных типа:

[HierarchyRoot]
public class A : Entity 
{
  [Field, Key]
  long Id { get; set; }

  // ...
}

[HierarchyRoot]
public class B : Entity 
{
  [Field, Key]
  int Id { get; set; }

  // ...
}

// Note: it is a descendant of B
public class C : B
{
  // ...
}

И добавьте еще один постоянный класс:

[HierarchyRoot]
public class AuditData<T> : Entity
  where T: Entity
{
  [Field]
  [Association(OnTargetRemove = OnRemoveAction.None)] // This ensures 
  // FK won't be created
  T Source { get; set; }

  // ...
}

DataObjects.Net автоматически предоставит постоянство для двух экземпляров этого типа:

  • AuditData (Of A)
  • AuditData (Of B)

Но это не позволит вам создать AuditData (Of C), так как есть AuditData (Of B). Таким образом, он принимает решение о том, что регистрировать, основываясь на ограничениях общего типа. Также показано, что создание внешнего ключа легко избежать.

0 голосов
/ 24 июня 2009

Вы можете посмотреть вариант хранения аудита в отдельной базе данных, например, в объектно-ориентированной базе данных, например db4o . Это может дать вам дополнительную гибкость с точки зрения хранения

...