Распределенный первичный ключ - UUID, простой автоинкремент или пользовательские последовательные значения? - PullRequest
5 голосов
/ 31 августа 2011

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

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

РЕДАКТИРОВАТЬ2: я принял ответ, поскольку я думаю, что это будет лучшим решением на данный момент.Но я подумал, что хотел бы ответить на два других вопроса, которые отвечают на мой запрос о соединении чисел.Их можно найти здесь: Объедините два целых числа для создания уникального числа & Объедините целые числа в C # .Если бы я собирался попробовать кодировать число (как показано ниже, например, 51122222), я думаю, это было бы полезно.Хотя, возможно, просто использовать что-то вроде String.Format в c # было бы достаточно быстро для моего небольшого приложения.

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

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

Элементы
ItemID (PK)?
Строка имени
Строка содержимого

ItemHistory
ItemHistoryID (PK)?
ItemID (FK)?
EventName String
CreatedOn DateTime

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

Первая версия будет стандартным настольным приложением, в настоящее время я планирую использовать C # с внешним интерфейсом WPF и SQLite для базы данных.В конце концов, я также хочу создать версию для своего телефона Android.Вот тут-то и появляется распределенная часть. У меня не всегда есть сигнал, поэтому мне нужно, чтобы приложение работало в автономном режиме и разрешало синхронизацию при повторном подключении к сети.

Вот мои идеи о том, как действоватьс идентификаторами:

  1. Используйте UUID для идентификаторов, чтобы не возникало конфликтов слияния
  2. Используйте поле автоинкремента и установите начальный номер для каждой версии приложения с некоторым увеличениемнапример, 1 для первого приложения, 10000 для второго, 20000 для третьего и т. д.
  3. Используйте поле автоинкремента со значением смещения, чтобы избежать конфликтов без больших пробелов между числами (для этого mysql имеет auto_increment_increment и auto_increment_offset)
  4. Создайте свой собственный идентификатор, который кодирует идентификатор для каждой базы данных, чтобы они могли иметь собственное значение автоинкремента и не вызывать конфликт.Я нашел кого-то еще, кто имел ту же идею: Какой тип данных рекомендуется для столбцов идентификаторов?

Хотя вариант 1 будет работать, и я использовал его в прошлом, я хочу, чтобыпосмотрите на возможность других вариантов, чтобы избежать проблем с UUID.Я хотел бы иметь решение, которое будет легче читать во время отладки и может быть отсортировано.

Вариант 2 будет работать, но он налагает ограничение на количество записей.Я знаю, что в моем небольшом приложении оно почти никогда не превысит такого количества, но я хотел бы попробовать и посмотреть, есть ли решение, которое не требует такого ограничения.Вариант 3 позволяет обойти ограничение, используя чередующиеся числа, но я думаю, что вам нужно знать, сколько баз данных будет использоваться, иначе вы могли бы заполнить все числа.Используя начало 1 и приращение 1 в DB1 и начало 2 и приращение 2 в DB2 будет альтернативно использовать каждое число.Вы могли бы использовать 50 в качестве приращения, но тогда у вас просто есть другое ограничение, но теперь это число приложений, которые могут его использовать.Опять же, я знаю, что это предел, который не будет затронут в моей ситуации, но может стать проблемой в приложении, которое внезапно становится очень популярным.

Вариант 4, похоже, может решить эту проблему для меня, но я не уверен, сработает ли он на практике или нет.У меня была одна идея - разрешить установку префикса в каждом приложении, чтобы его можно было использовать с автоматически увеличивающимся значением.например, ПК1, ПК2 для записей на ПК и, возможно, PHONE1, PHONE2 и т. д. для записей с Android.Это работало бы, но использование чисел в строках вызывает проблему сортировки: 1, 11, 100 отображаются рядом друг с другом, то есть используются менее начальные нули, а затем снова возвращаются к ограниченному количеству записей.

Я задавался вопросом, можно ли будет использовать число для идентификатора БД и автоматического увеличения.например, PC = 1 и PHONE = 2. тогда у нас есть 11, 12, 13 и т. д. для ПК, возможно, 111 для 11-й записи и 2304 для 304-й записи на PHONE.Но я не знаю, как это можно сделать или если это легко сделать, и это не приведет к избыточным накладным расходам для генерации значений.

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

Итак, наконец, вопрос, есть ли способ создать систему первичного ключа для распределенного приложения, которая позволяет сортироватьи не применяет ограничения (помимо размера самого типа данных, например, max integer)?

РЕДАКТИРОВАТЬ: Вот немного больше информации о приложении, которое я планирую написать.Я хочу создать что-то, что позволит мне хранить практически любой тип информации, которую я могу получить, в систему будет включена возможность помечать записи, чтобы я мог искать по теме.Типами информации, которую я вижу до сих пор, могут быть рекомендации по книгам, DVD, веб-сайтам и т. Д. Или, может быть, местные советы для места, где я живу.Одна общая идея состоит в том, чтобы прекратить хранить эти биты информации на разных компьютерах / ноутбуках / телефонах в разных форматах.

1 Ответ

2 голосов
/ 31 августа 2011

в широком смысле, есть два подхода.

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

  2. вы используете случайные значения (включая UID).это намного проще, но требует больше места.из "столкновений в день рождения" мы знаем, что если вам нужно сохранить N значений, тогда должен быть выбран случайный ключ из (более) диапазона N * N - http://en.wikipedia.org/wiki/Birthday_problem., работающего в обратном направлении, 64-разрядное целое число может содержатьоколо 32 бит данных, если использовать их в качестве случайного ключа - это около 4 миллиардов значений.но это с вероятностью 50% столкновений.Вы хотите гораздо более низкую вероятность, поэтому практический предел составляет около 10 миллионов записей.

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

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

очевидно, если у вас есть текстовое значение, то вам необходимо соответствующим образом изменить его, но UUIDs разработаны так, чтобы в любом случае иметь «достаточно» значений http://en.wikipedia.org/wiki/Universally_unique_identifier

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...