Альтернатива GUID с масштабируемостью и дружественным URL

Я решил использовать GUID в качестве первичного ключа для многих таблиц БД моего проекта. Я думаю, что это хорошая практика, особенно в отношении масштабируемости, резервного копирования и восстановления. Проблема в том, что я не хочу использовать обычный GUID и искать альтернативный подход. Мне было действительно интересно узнать, что Pinterest я использовал в качестве первичного ключа. Когда вы смотрите на URL, вы видите что-то вроде этого:

http://pinterest.com/pin/275001120966638272/

Я предпочитаю числовое представление, даже если оно хранится в виде строки. Есть ли способ добиться этого?

Кроме того, YouTube также использует другую технику хэширования, которую я не могу понять:

http://www.youtube.com/watch?v=kOXFLI6fd5A

Это напоминает мне сокращенную схему, похожую на URL.

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

 DateTime dt1970 = new DateTime(1970, 1, 1);
 DateTime current = DateTime.Now;
 TimeSpan span = current - dt1970;

Пример результата:

1350433430523.66

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

Я в основном предпочитаю не-BIGINT решение с автоинкрементом, потому что оно уменьшает головную боль при масштабировании БД с использованием сторонних инструментов, а также менее проблематичные функции резервного копирования /восстановления, потому что я могу передавать данные между серверами и тому подобное, если захочу.

Еще один сложный подход - адаптировать решение к моему приложению. В базе данных первичный ключ также будет содержать имя пользователя (уникальное и не может быть изменено пользователем), поэтому я могу объединить числовое значение имени с числом в миллисекундах, что даст мне уникальную числовую строку. Поскольку пользователь не вводит данные с такой высокой скоростью, числовой идентификатор гарантированно будет уникальным. Я также могу удалить последние 5 цифр и все равно получить уникальный идентификатор, потому что я предполагаю, что пользователь не будет вставлять данные чаще, чем 1 раз в секунду, но я бы, вероятно, этого не сделал (что вы думаете о эта идея?)

Поэтому я прошу вашей помощи. Мои данные предполагают очень большой рост, 2 ТБ в год с десятью тысячами новых строк в секунду. Я хочу, чтобы URL выглядели как можно более дружественными, и предпочитаю не использовать «обычный» GUID.

Я разрабатываю свое приложение с использованием ASP.NET 4.5 и MySQL

Спасибо.

7 голосов | спросил Idan Shechter 17 +04002012-10-17T02:10:08+04:00312012bEurope/MoscowWed, 17 Oct 2012 02:10:08 +0400 2012, 02:10:08

3 ответа


0

Стол столкновения

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

Длинные первичные ключи

Я могу ошибаться, но Пинтрест выглядит так, как будто использует long (например, 275001120966638272) в качестве первичного ключа базы данных. Если вы используете GUID, то это не поможет. В Твиттере тоже есть что-то похожее.

Кодированные BaseID GUID

Вы можете использовать ShortGuid , который кодирует GUID как строку base64. Недостатком является то, что вывод немного некрасив (например, 00amyWGct0y_ze4lIsj2Mw) и чувствителен к регистру, что может быть не очень хорошо для URL, если вы ниже в корпусе.

Кодированные BaseID GUID

Существует также кодировка base32 GUID, которую вы можете увидеть этот ответ . Они немного длиннее, чем у ShortGuid (например, lt7fz44kdqlu5pt7wnyzmu4ov4), но преимущество заключается в том, что они могут быть в нижнем регистре.

Множественные факторы

Одна альтернатива, о которой я думал, - это ввести несколько факторов, например, Если Пинтрест использовал имя пользователя и идентификатор для дополнительной уникальности:

  

https://pinterest.com/some-user/1

Здесь идентификатор 1 уникален для пользователя some-user и может быть числом постов, которые они сделали, т.е. их следующий пост будет 2. Вы также можете использовать подход YouTube с их идентификатором видео, но специфичным для пользователя, это может привести к смехотворно коротким URL-адресам.

ответил Muhammad Rehan Saeed 6 J0000006Europe/Moscow 2018, 18:16:34
0

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

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

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

Универсальный уникальный идентификатор в качестве первичного ключа

Да, это хорошая практика.

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

Эта статья Генерация уникальных в глобальном масштабе Идентификаторы для использования с MongoDB Александр Марквардт (старший инженер-консультант в MongoDB) подробно освещает этот вопрос и дает некоторое представление о базе данных и информатике.

UUID имеют длину 128 бит. Они вводят количество энтропии достаточно высоко, чтобы обеспечить практическую уникальность этикеток. Они могут быть представлены 32 шестнадцатеричными символами. Достаточно написать несколько тысяч миллиардов миллиардов десятичного числа.

Вот еще несколько вопросов, которые могут возникнуть при рассмотрении общего принципа и анализа:

  1. должны первичные ключи базы данных и Уникальное расположение ресурса будет храниться как два разных объекта?

  2. должна ли эта нумерация последовательно разрушать то, что может происходить в системе?

  3. Предоставляет ли номер хоста компьютера (h), затем номер пользователя (u) и время (t) вдоль индекса записи (i) гарантировать, что PK huti останется уникальным?

.

Теперь рассмотрим систему БД:

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

Hashids

Техника хеширования на Youtube - это хеш-коды .

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

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

Рассмотрите комментарий к этому ответу, чтобы выяснить, какую энтропию можно получить из сокращенного рецепта sha1 + b64. ​​Чтобы предвидеть сценарий столкновения , требует оценки будущего измерения базы данных, то есть потенциального количества записей. Рекомендуемое чтение: Z.Bloom Как долго должен быть ID?

Миллисекунды с начала эпохи

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

  

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

ответил Flint 13 J0000006Europe/Moscow 2018, 08:06:02
0

Что вы можете сделать, это преобразовать GUID в только числовое значение, преобразовав все буквы в числа в guid. Вот пример того, как это будет выглядеть. Это ненадолго, но если это не проблема, это может быть одним из способов создания ключей.

  

1004234499987310234371029731000544986101469898102

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

    string generateKey()
    {
        Guid guid = Guid.NewGuid();
        string newKey = "";
        foreach(char c in guid.ToString().Replace("-", "").ToCharArray())
        {
            if(char.IsLetter(c))
            {
                newKey += (int)c;
            }
            else
            {
                newKey += c;
            }
        }
        return newKey;
    }

Edit:

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

ответил Daniel Frykman 12 J0000006Europe/Moscow 2018, 11:42:12

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132