GUID как первичные ключи - автономный OLTP - PullRequest
5 голосов
/ 02 сентября 2008

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

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

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

Это плохая идея по какой-то причине? Будет ли доступ к этим таблицам через ключ GUID медленным?

Был ли у вас опыт работы с системами такого типа? Как вы решили эту проблему?

Спасибо!
Daniel

Ответы [ 15 ]

8 голосов
/ 02 сентября 2008

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

То, о чем вам нужно заботиться, - это читаемый человеком идентификатор. Люди не могут обменять руководства - можете ли вы представить себе попытку подтвердить номер заказа по телефону, если это гид? Таким образом, в автономном сценарии вам все еще может потребоваться сгенерировать что-то - например, идентификатор издателя (рабочей станции / пользователя) и некоторый порядковый номер, поэтому номер заказа может быть 123-5678 -.

Однако это может не соответствовать бизнес-требованиям наличия порядкового номера. На самом деле нормативные требования могут быть и влиять - некоторые правила (возможно, SOX) требуют, чтобы номера счетов-фактур были последовательными. В таких случаях может потребоваться сгенерировать своего рода номер проформы, который устанавливается позже при синхронизации систем. Вы можете получить доступ к таблицам, имеющим OrderId (Guid), OrderNo (int), ProformaOrderNo (varchar) - может возникнуть некоторая сложность.

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

3 голосов
/ 03 сентября 2008

@ SqlMenace

Существуют и другие проблемы с GUID, вы видите, что GUID не являются последовательными, поэтому вставки будут разбросаны повсеместно, это приведет к расщеплению страниц и фрагментации индекса

Не правда. Первичный ключ! = Кластерный индекс.

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

2 голосов
/ 02 сентября 2008

Это очень хорошее использование GUID. Единственным недостатком будет небольшая сложность в работе с GUID над INT и небольшая разница в размере (16 байт против 4 байт).

Я не думаю, что что-то из этого имеет большое значение.

1 голос
/ 19 августа 2009

Я просто собираюсь указать вам на Каковы улучшения производительности Sequential Guid по сравнению со стандартным Guid? , который охватывает разговор GUID.

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

Мне лично нравится ответ SGUID.

1 голос
/ 03 сентября 2008

Обязательно используйте guid.comb - заботится о индексировании. Если после этого вы столкнетесь с проблемами производительности, то вскоре станете экспертом по масштабированию.

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

1 голос
/ 03 сентября 2008

Вы правы, что это старая проблема, и она имеет два канонических решения:

  • Используйте уникальные идентификаторы в качестве первичного ключа. Обратите внимание, что если вы беспокоитесь о читабельности, вы можете использовать собственный уникальный идентификатор вместо использования GUID. Уникальный идентификатор будет использовать информацию о дате и машине для генерации уникального значения.

  • Используйте составной ключ «Актер» + идентификатор. Каждый пользователь получает числовой идентификатор субъекта, а ключи вновь вставленных строк используют идентификатор субъекта, а также следующий доступный идентификатор. Таким образом, если два актера оба вставят новую строку с идентификатором «100», ограничение первичного ключа не будет нарушено.

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

1 голос
/ 02 сентября 2008

Будет ли доступ к этим таблицам через медленный ключ GUID?

Существуют и другие проблемы с GUID, вы видите, что GUID не являются последовательными, поэтому вставки будут разбросаны повсеместно, это приведет к расщеплению страниц и фрагментации индекса

В SQL Server 2005 MS ввел NEWSEQUENTIALID (), чтобы исправить это, единственная проблема для вас может заключаться в том, что вы можете использовать NEWSEQUENTIALID в качестве значения по умолчанию в таблице

0 голосов
/ 03 сентября 2008

@ Portman По умолчанию PK == Кластерный индекс, создание ограничения первичного ключа автоматически создаст кластерный индекс, вам нужно указать некластеризованный, если вы не хотите кластеризовать его.

0 голосов
/ 03 сентября 2008

Первая мысль, которая приходит на ум: Разве MS не разработала модели DataSet и DataAdapter для поддержки подобных сценариев?

Полагаю, я читал, что MS изменила модель набора записей ADO на текущую модель DataSet, поэтому она отлично работает и в автономном режиме. И есть также это Службы синхронизации для ADO.NET

Мне кажется, я видел код, который использует модель DataSet, которая также использует внешние ключи, и они по-прежнему отлично синхронизируются при использовании DataAdapter. Хотя я не пробовал Sync Services, но я думаю, что вы тоже сможете извлечь из этого выгоду.

Надеюсь, это поможет.

0 голосов
/ 03 сентября 2008

я бы начал смотреть на SQL Server Compact Edition для этого! Это помогает со всеми вашими проблемами.

Архитектура хранения данных с SQL Server 2005 Compact Edition

Специально разработан для

Применение полевых сил (FFA). FFAs обычно разделяют один или несколько следующие атрибуты

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

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

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

...