3

В настоящее время я работаю над системой, которая в некоторых случаях должна работать в локальной базе данных в течение дня, а затем реплицироваться на центральный сервер ночью. Это не может все запускаются из одной центральной базы данных, так как локальные сайты периодически не контактируют с ней. Данные на центральном сервере для просматривают и сообщают только в головном офисе, поэтому ничто не нуждается в обратном воспроизведении на сайте.GUID/UUID для этого сценария? Или сложный ключ? Или другое

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

Вот пример очень урезать версии схемы без беспокоиться о удаленной репликации (который будет хорошо работать для большинства клиентов): -

(я покажу только таблицу истории для таблица Area, чтобы держать вещи короткие):

[Site] 
SiteKey [PK] (Gauranteed 100% unique across all sites text based key) 

[User] 
SiteKey [FK -> Site] 
UserID [PK] 

[Area] 
SiteKey [FK -> Site] 
AreaID [PK] 
Description 
UpdatedDtm 
UpdatedUserID [FK -> User] 

[AreaHistory] 
Site [FK -> Site] 
AreaID [FK -> Area] 
Description 
UpdatedDtm 
UpdatedUserID [FK -> User] 
AuditedDtm 

[Location] 
AreaID [FK -> Area] 
LocationID [PK] 
Description 
UpdatedDtm 
UpdatedUserID [FK -> User] 

[Sensor] 
LocationID [PK/FK -> Location] 
SensorNo [PK] 
UpdatedDtm 
UpdatedUserID [FK -> User] 

[Reading] 
LocationID [PK/FK -> Sensor] 
SensorNo [PK/FK -> Sensor] 
ReadingDtm [PK] 

Что хорошо, пока я не приду «слить» базу данных с базой данных на центральном сервере. Я, очевидно, собираюсь столкнуться в таблице Location, потому что я смешиваю данные с идентификаторами, сгенерированными на других сайтах.

Первый способ, которым я думал, вокруг этой проблемы в том, чтобы сделать это:

гс краткое):

[Location] 
SiteKey [FK -> Location, FK -> User] ** ADDED THIS 
AreaID [FK -> Area] 
LocationID [PK] 
Description 
UpdatedDtm 
UpdatedUserID [FK -> User] 

[Sensor] 
SiteKey [FK -> Location, FK -> User] ** ADDED THIS 
LocationID [PK/FK -> Location] 
SensorNo [PK] 
UpdatedDtm 
UpdatedUserID [FK -> User] 

[Reading] 
SiteKey [FK -> Sensor] ** ADDED THIS 
LocationID [PK/FK -> Sensor] 
SensorNo [PK/FK -> Sensor] 
ReadingDtm [PK] 

В принципе, каждая таблица получает SiteKey делает каждую строку уникальной для сайта.

Альтернатива это (с помощью UUID, в некоторых местах): -

[User] 
SiteKey [FK -> Site] 
UserUUID [PK] 

[Area] 
SiteKey [FK -> Site] 
AreaUUID [PK] 
Description 
UpdatedDtm 
UpdatedUserUUID [FK -> User] 

[AreaHistory] 
Site [FK -> Site] 
AreaUUID [FK -> Area] 
Description 
UpdatedDtm 
UpdatedUserUUID [FK -> User] 
AuditedDtm 

[Location] 
AreaUUID [FK -> Area] 
LocationUUID [PK] 
Description 
UpdatedDtm 
UpdatedUserUUID [FK -> User] 

[Sensor] 
LocationUUID [PK/FK -> Location] 
SensorNo [PK] 
UpdatedDtm 
UpdatedUserUUID [FK -> User] 

[Reading] 
LocationUUID [PK/FK -> Sensor] 
SensorNo [PK/FK -> Sensor] 
ReadingDtm [PK] 

Запомни вырубается, но она иллюстрирует проблему.

Есть ли альтернативы, которые могут отсутствовать? Я подумал о повторном наборе ID, но, похоже, представил новые, еще более худшие кошмары.

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

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

Если это имеет значение, я использую PostgreSQL.

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

+0

После прочтения предоставленной ссылки вам нечего добавить. Лично я бы пошел на вариант UUID. Пространство и скорость будут только увеличиваться в ближайшие годы, это не должно быть проблемой. Техническое обслуживание также увеличится в ближайшие годы, это должно быть большой проблемой. –

+0

Правда, в этой ссылке много информации, однако я задавался вопросом, не было ли в моей ситуации, когда у меня есть уникальный SiteKey, если использовать это как составную часть составного ключа для всех таблиц, было «неплохо». – Mark

ответ

2

Я более или менее пришел к выводу, что ИМХО для этого сценария с использованием UUID - это немного «быстрое исправление», может быть, даже немного взлома. Я решил, что для меня в этом случае использование составного ключа будет более чистым.Используя UUID, я могу использовать только предварительно настроенный SiteKey для каждого идентификатора.

1

В большинстве сценариев репликации требуется использование GUID/UUID. Я бы добавил один к каждому столу. Прочитайте о последствиях использования одного и способах их наилучшего предотвращения в вашем конкретном бэкэнде базы данных.

0

Учитывая то, что вы сказали, я бы использовал GUID (и более предвзятым к этому по мере увеличения количества таблиц). Обратите внимание, что в SQL Server, потому что хорошо иметь кластерный индекс на узком увеличении ключа, и часто это также является первичным ключом, общий GUID не так эффективен, поскольку он вызывает проблемы, связанные с невозрастающим характером. Существует NEWSEQUENTIALID(), который генерирует только последовательный GUIDs:

INT vs Unique-Identifier for ID field in database

Я использовать технику ГРЕБНЯ ID, перед которым также была способность к Задан быть извлечена из GUID, давая вам метку время создания (хотя он не обязательно бесплатный, поскольку он не является действительно индексируемым сам по себе) (поскольку вы уже принимаете дополнительные байты для GUID vs. int)

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

1

Я также добавить еще один набор вне-коробки ответов, которые вы можете захотеть, по крайней мере, думать о:

  1. Если вы хотите сохранить сайт как часть составного ключа в базовые данные - с генерированием кода, представлениями и обновляемыми триггерами (по крайней мере, на SQL Server), можно сделать обновляемые представления, которые не имеют открытого ключа сайта. Таким образом, вы можете скрыть это из уровня приложения (это предполагает, что приложение не будет отображаться на сайте).

  2. На самом деле не реплицируйте, а консолидируйте данные в базу данных отчетов и размещайте сайт ТОЛЬКО на уровне отчетности. Уверен, что ваша схема отличается, но она предназначена для отчетности, так что даже нужен такой же RI?

  3. Не только ваша база данных отчетов не должна иметь одинаковую схему, она может иметь сильно отличающуюся денормализованную схему, такую ​​как хранилище данных, которая оптимизирована для специальных потребностей в отчетности.

Смежные вопросы