Уникальные идентификаторы для пользователей - PullRequest
7 голосов
/ 08 апреля 2010

Если у меня обычно таблица из ста пользователей, я бы просто установил столбец userID с автоматическим приращением в качестве первичного ключа. Но если вдруг у нас будет миллион пользователей или 5 миллионов пользователей, это станет действительно трудным делом, потому что я хотел бы начать становиться более распределенным, и в этом случае первичный ключ с автоинкрементом будет бесполезен, поскольку каждый узел будет создавать одинаковые первичные ключи. 1001 *

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

Кто-нибудь знает решение?

Спасибо

Ответы [ 9 ]

11 голосов
/ 08 апреля 2010

Я бы сказал, что пока сохраняем автоинкремент для идентификатора пользователя.

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

Другими словами, решить проблему, когда она у вас есть. «преждевременная оптимизация - корень зла».

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

8 голосов
/ 08 апреля 2010

Стандартным решением здесь является использование GUID. Однако они не будут работать так же хорошо с точки зрения индексации.

2 голосов
/ 08 апреля 2010

если вам нужны миллионы идентификаторов и много узлов, сделайте первичный ключ составным из:

NodeID  int   --unique for each node 2 or 4 byte  
UserID  int   --auto increment 8 byte, repeats for each node

что намного лучше, чем GUID (меньше, использует меньше памяти и будет быстрее)

2 голосов
/ 08 апреля 2010

Идентификаторы GUID хороши, но могут столкнуться (хотя и редко).

Это может быть нестандартное решение, но я собираюсь выкинуть его туда:

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

Допустим, у вас есть 3 сервера. Запишите идентификаторы следующим образом:

Сервер 1: 0 - 9 999 999
Сервер 2: 10 000 000 - 19 999 999
Сервер 3: 20 000 000 - 29 999 999

Даже в пределах ограничений 32-битного int это должно оставить много места для расширения (может даже использовать пробелы в 100 000 000, если вы беспокоитесь), и это по сути гарантирует уникальность всей системы.

1 голос
/ 08 апреля 2010

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

Вы можете использовать GUIDS. Но 5 миллионов - ничто с точки зрения данных и, вероятно, не потребует изменений. В нашей системе работает более 10 000 000 разных людей, и у нас есть только база данных среднего размера, без разметки и без необходимости использования GUID.

0 голосов
/ 08 апреля 2010

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

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

Существуют следующие два решения, которые я бы порекомендовал.

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

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

Я понимаю, что второе решение немного запутанно и сложно, но все же лучше, чем использовать Guids в качестве PK. но если применимо решение 1, продолжайте.

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

С уважением Mubashar

0 голосов
/ 08 апреля 2010

Если вы используете MSSQL, вы можете создать PK вашей таблицы как UNIQUEIDENTIFIER и установить для значения по умолчанию или привязки значение NEWID ().

0 голосов
/ 08 апреля 2010

GUID являются мусором в качестве ключей при кластеризации. Если нет кластеризации, вам все равно понадобится кластеризованный индекс для другого столбца.

Используйте целочисленный ключ и для каждого new узла / сайта

  • Увеличение с шагом 10. Когда вы добавляете узлы, просто начните с 2, 3 и т. Д.
  • Используйте диапазоны, например, 1-> 1000000, 1000000 -> 1999999 и т. Д.
  • И не забудь -ве тоже. Например, вы можете иметь IDENTITY (-1, -1) для второго узла

Если у вас есть узлы / сайты, тогда будет работать и второй столбец с SiteID.

0 голосов
/ 08 апреля 2010

GUID - это простой выход, но ...

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

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

...