2012-06-06 4 views
11

КонтекстЗамените функцию UUID версии 1 MySQL?

веб-приложений, PHP 5, MySQL 5.0.91

Проблема

Я недавно перешел от использования автоинкрементных целого числа в UUID в качестве первичного ключа для некоторых моих таблиц. При генерации UUID с помощью UUID() функции MySQL, они очень похожи друг на друга:

| uuid         | 
---------------------------------------- 
| 1e5988da-afec-11e1-9877-5464f7aa6d24 | 
| 408092aa-afad-11e1-9877-5464f7aa6d24 | 
    ^------^ ^^ 
    1  8 11-12 

Как вы можете видеть, только первые 8 символов и 11-й и 12-й различны. Я понимаю, что в UUID версии 1 используется метка времени и аппаратный MAC-адрес для генерации UUID. Тем не менее, я не решаюсь использовать версию 1 из-за этих сходств (и того факта, что MAC-адрес в моем случае никогда не изменится). Кроме того, если MAC-адрес никогда не изменяется, большая часть UUID бесполезна и тратит впустую пространство.

Мой заказ UUID Функция

В качестве эксперимента, я написал собственный UUID-генератор в PHP:

public static function GenerateUUID() 
{ 
    return 
    substr(sha1(Account::GetUsername() . Account::GetUserID()), 18, 8) . "-" . 
    substr(md5(time()), rand() % 28, 4) . "-" . 
    substr(md5(date("Y")), rand() % 28, 4) . "-" . 
    substr(sha1(rand()), 20, 4) . "-" . 
    substr(sha1(rand() % PHP_INT_MAX), 17, 12); 
} 

Образец результатов:

| uuid         | 
---------------------------------------- 
| 574d18c2-5080-bac9-5597-45435f363ea1 | 
| 574d18c2-30d4-8b5b-4ffd-001744d3d287 | 

Здесь первые 8 символов идентичны для одного и того же пользователя. Это было предназначено, но не нужно.

Вопрос

Есть ли предпочтительный/рекомендуемый способ для создания версии 4 или 5 UUID в запросе MySQL?

Если нет, допустимо ли создавать пользовательский UUID в PHP (как указано выше), который не соответствует спецификации?

Ограничения

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

Примечания

  • я и не будет выполнять слияние, синхронизацию, или другие операции, требующие GUID, который содержит адрес MAC. Это не проблема.
+0

Только для нижних лучше, почему вы перестали использовать автоматические номера и подумали ли вы о создании своего рода SHA? Кроме того, существует UUID_SHORT() –

+0

@MatthewRiches: 'UUID_SHORT()' недоступен в MySQL 5.0.X (я уточнил версию в своем вопросе). Я решил переключиться с автоматически увеличивающегося целого числа после чтения http://www.codinghorror.com/blog/2007/03/primary-keys-ids-versus-guids.html. –

+0

В качестве побочного элемента: «если MAC-адрес никогда не изменяется, большая часть UUID бесполезна и тратится впустую», это неверно, хэш-адрес MAC-адреса имеет решающее значение, если вы хотите выполнять многосерверную синхронизацию. –

ответ

4

На самом деле довольно неплохо оценить наличие «подобных частей». Это позволит вам использовать MAC-адрес, чтобы иметь возможность идентифицировать «какой из моих серверов сгенерировал этот UUID?» ... что будет чрезвычайно полезно при переносе данных между удаленными точками. Вы можете даже сделать «это мои тестовые данные» и «это мои производственные данные» таким образом.

В PHP имеется большое количество библиотек UUID-генераторов.

Вот один PECL/PEAR вещь (я никогда не использовал его):

http://pecl.php.net/package/uuid

В рамках CakePHP:

http://api.cakephp.org/class/string#method-Stringuuid (торт 2.x) http://api13.cakephp.org/class/string#method-Stringuuid (кек 1,3)

Последняя опция генератора:

Рассмотрите возможность использования комманды Linux d-line uuid, которая имела бы флаг управления версией -v и связанные с ним параметры и используя это для подачи вашей базы данных. Это неэффективно, но по крайней мере вам не придется писать свои собственные функции генератора.

http://linux.die.net/man/1/uuid - мужчина страница

(пакет uuid для Debian)

я заметил, что для версий пространства имен, вы будете генерировать много «длинные человеческие имена», чтобы преобразовать в UUID-ы. Если у вас нет конфликтов с ними, это может быть очень мило. Например, пользователи регистрируются с адресами электронной почты ... Получите v5 uuid для этого адреса электронной почты ... вы всегда найдете этого человека! Кажется, что каждый раз выплевывает один и тот же UUID, и UUID будет представлять собой уникальные отношения, которые [email protected] имеет с example.com в качестве участника.

uuid -v5 ns:URL "http://example.com/member/[email protected]/"

Комментарий:

Кроме того, UUID, то, как кажется, вы должны хранить их, являются CHAR (36)? Вы можете пожалеть о том, что после того, как операторы сравнения вступили в игру.

Postgres будет обрабатывать UUID как 128-битные значения (и предположительно делать оптимизированные двоичные операции), тогда как решение CHAR (36) MYSQL рассматривает 36 байтов = 288 бит ANSI или 576-бит UTF8 плюс-минус бит/байты для ведения офиса (и, по-видимому, выполняют гораздо более медленные строковые подпрограммы с несколькими байтами-символами-мультибайтами).

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

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

В качестве альтернативы, пойти с Microsoft SQL для их GUID эквивалент, если вы готовы в конце концов, платить им много денег, чтобы работать с БД ...

Ведение UUID и MySQL просто как правило, плохая идея момент.

+0

Ох ...? После просмотра комментария @ matthew-riches UUID_SHORT() довольно круто для 90%% операторов, которым нужна малая уникальность в масштабе ... Мне все равно нужен встроенный 128-битный генератор UUID. – starlocke

+0

Я просто уточнил точную версию в своем вопросе. 'UUID_SHORT()' недоступен в MySQL 5.0.X. –

+1

Стоимость выполнения UUID как CHAR (36) смехотворно высока и становится глупой в 1+ milion, 10+ миллионах, 100+ миллионах строк, в моем скромном опыте.Было бы более рентабельным использовать кластеризацию и избыточность, чем делать резервные копии mysqldump на этих уровнях «количество простых строк uuid» и «количество взаимосвязей соединения uuid-foreign-key'd». – starlocke

9

Ваша забота о том, что «большая часть UUID бесполезна и растрачивает пространство», присуща размеру типа данных. Вы никогда не сможете иметь столько записей в своей базе данных, сколько допускает теоретический предел в 16 байт.

Фактически VU UUID более подходит, чем V4, если вы используете UUID так же, как идентификатор таблицы, потому что он использует MAC-адрес и отметку времени для предотвращения столкновений. В V4 такого механизма нет, хотя вам практически не нужно слишком беспокоиться о столкновениях :) Вы должны использовать V4 UUID вместо V1, если вам нужно, чтобы ваш UUID был непредсказуем.

Также обратите внимание, что составление, например, случайных значений 4x4 байт, может быть не таким же, как создание случайного значения по 16 байт. Как всегда с криптографией и случайностью: я бы поставил под угрозу выполнение собственной UUID :: V4.

Если вы установили на свой компьютер, вы можете воспользоваться пакетом php-uuid.

Пример кода (который может быть использован в приложении, как это) можно найти здесь: http://rommelsantor.com/clog/2012/02/23/generate-uuid-in-php/

Используйте это так:

$uuid = uuid_create(1); 

пользователей, которые могут устанавливать пакеты на своем веб-сервере, могут установить необходимый пакет, например: (здесь для ubuntu)

apt-get install php5-dev uuid-dev 
pecl install uuid 
+0

, поскольку времена меняются ... Интересно, какое влияние на картинку добавляет движение к случайным MAC-адресам (например, мобильная стратегия MAC-адреса компании Randome для увеличения анонимности для пользователей мобильных телефонов от датчиков iBeam и сниффера). Я бы подумал со всеми устройствами, всеми производителями и количеством случайных экземпляров с течением времени ... в то время как числа большие, аргумент версии 1, гарантированный уникальный, теперь разрушается. Многое изменилось за четыре года, что заставляет нас больше думать о том, что может произойти в сравнении с тем, где мы находимся сегодня. –

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