SQL-дизайн вокруг отсутствия ссылок на внешние ключи базы данных - PullRequest
21 голосов
/ 05 ноября 2008

Что бы там ни было, у нас есть решение, которое опирается на несколько баз данных, которые все ссылаются на общую базу данных администрирования. Базы данных поставляются как часть модулей, и не все модули требуются для установки (возможно, поэтому у нас есть несколько баз данных в первую очередь). Однако требуется база данных администратора ... поэтому она всегда будет там.

Я хотел бы внести некоторую ссылочную целостность и порядок в хаос, но я застрял в неспособности SQL-сервера создавать внешние ключи кросс-баз данных. В базе данных НЕТ большого количества оттока, но информация будет вставлена ​​/ обновлена ​​(гм) нетехническими пользователями.

Мой выбор, который я вижу:

a) Использование псевдо-внешнего ключа с использованием триггеров (хорошо, но немного работы)

b) Использование триггеров для репликации из администратора в другие базы данных (четкий рецепт для катастрофы)

c) Внедрить псевдо-внешний ключ в коде / DAL (плохо работает с ORM)

d) Не беспокойтесь об этом на уровне БД, используйте хороший дизайн интерфейса, чтобы убедиться, что никто не делает глупостей, и ограничьте доступ / задержку дыхания при прямом доступе SQL.

Честно говоря, я склонен идти с "D", но решил, что я пойду за мнения умнее меня ...

Ответы [ 9 ]

4 голосов
/ 05 ноября 2008

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

4 голосов
/ 05 ноября 2008

У нас точно такая же проблема, и, откровенно говоря, это отстой. Наше единственное решение, которое мы сочли эффективным, - это вариант D и использование бизнес-уровня, чтобы попытаться сохранить синхронизацию (в транзакциях и т. Д.)

3 голосов
/ 05 ноября 2008

У нас есть такая модульность в наших продуктах, но наши требования к базе данных объединяются во время установки. Например, наш пакет администратора и продукт A могут быть первоначальной покупкой клиентом, когда они устанавливают два модуля в базу данных X. Если они позже приобретают продукт B, компонент базы данных размещается прямо поверх базы данных X, добавляя в DRI, где это необходимо.

Единственный случай, когда я видел потребность в отдельных базах данных с точки зрения проектирования, - это когда вы рисуете жесткую грань между бизнес-единицами (например, корпорацией), и в этот момент проблема действительно является типом разделения. Great Plains Dynamics делает это, когда у них есть одна административная база данных и несколько корпоративных баз данных. Однако каждый модуль в GP для данной корпорации находится в этой единой базе данных.

Конечно, если вы застряли с отдельными базами данных, я бы согласился, что D - лучший вариант.

1 голос
/ 06 ноября 2008

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

Мне часто приходилось сталкиваться с этим в межведомственных ситуациях с базами данных, когда вещи могли не синхронизироваться, потому что разрозненные системы еще не были полностью интегрированы или из-за проблем безопасности требовалось, чтобы у них были отдельные администраторы.

В этих случаях я обычно полагаюсь на отчеты об исключениях, сгенерированные ежечасно, которые проверяют состояние вещей и сообщают только о наличии проблем. Задания агента SQL Server имеют мощные возможности планирования. Я всегда использовал таблицы журналов и SQLAnswersMail для создания небольших небольших электронных писем в формате HTML (где URL-ссылки в электронных письмах могли даже привести вас на страницы администрирования для исправления проблем) различным системным администраторам, но существует множество способов обработать эту кошку.

1 голос
/ 06 ноября 2008

Вы должны реализовать сервис-ориентированную архитектуру. Где различные службы в системе работают с их схемой базы данных. Затем пусть ваши приложения запускаются независимо от каких-либо баз данных, но позволяют работать с этими службами.

1 голос
/ 05 ноября 2008

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

Если вы скажете: «Ну и дела, есть много работы, которую все еще можно выполнить без администратора базы данных». тогда я спросил бы, почему вы считаете, что однонаправленная репликация настолько дико экзотична, что это явный рецепт катастрофы?

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

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

1 голос
/ 05 ноября 2008

В зависимости от реализации вашей базы данных, вы часто сможете связывать таблицы из другой базы данных (AdminDB) и размещать их в различных базах данных вашего модуля.

В Microsoft Access вы можете связать таблицы, щелкнув правой кнопкой мыши и выбрав источник данных ODBC. В Oracle они называют это ссылкой на базу данных . Я готов поспорить, что SQLServer имеет некоторую форму этой реализации , за исключением реализации пользовательской репликации для одной таблицы.

Как только вы свяжетесь в своих внешних таблицах администратора с базами данных вашего модуля (или наоборот), вы сможете определить ограничения, как если бы таблицы были в одной и той же схеме.

Второй вариант может быть еще проще. Что если вы использовали одну и ту же схему для всех модулей и базы данных администратора? Вы знаете, что база данных администратора присутствует, поэтому просто запустите сценарий создания таблицы для этой схемы. Пока нет конфликтов имен таблиц / представлений / хранимых процедур, все должно работать, просто изменив dblogin во всех модулях для соответствия.

0 голосов
/ 16 июля 2011

Я думаю, что самое забавное ... в том, что вы можете сделать небольшую копию своей базы данных MS Access, включить RI в Access ... и затем увеличить ее, и Microsoft Access дает вам возможность выбирать между использованием триггеров или DRI. и я вполне уверен, что Microsoft Access напишет для вас основные части триггеров.

Пока мы обсуждаем эту тему, я ненавижу MS Access ... но единственное, что превосходит Access, - это то, что вы можете принудительно применять RI к запросу QUERY (sql select, aka view) .. Я действительно хочу, чтобы MS SQL Server обладает той же функциональностью.

0 голосов
/ 05 ноября 2008

Интересно, есть ли в SQL Server такая функция, как материализованные представления Oracle? Это объект, который вы определяете с помощью запроса, например представления, но результаты запроса сохраняются в виде таблицы. Существуют различные механизмы автоматического обновления.

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

...