Вопрос по php, mysql – Заменить функцию MySQL UUID версии 1?

12

Context

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

The Problem

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

| 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 бесполезна и тратит пространство.

My Custom UUID Function

В качестве эксперимента я написал пользовательский 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 символов идентичны для одного и того же пользователя. Это было задумано, но не нужно.

The Question

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

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

Restrictions

  • I am using a shared hosting plan with command-line access, but cannot modify the existing MySQL installation.
  • I would prefer avoiding third-party packages/libraries.

Notes

  • I do not and will not be performing merging, synchronization, or other operations that require a GUID that contains the MAC address. That is not the issue here.
Как примечание: «если MAC-адрес никогда не изменяется, большая часть UUID бесполезна и тратит пространство», это неправильно, хэш MAC-адреса имеет решающее значение, если вы хотите выполнить многосерверную синхронизацию. Alix Axel
Просто чтобы лучше понять, почему вы перестали использовать авто номера и рассматривали ли вы создание своего рода SHA? Также есть UUID_SHORT () Matthew Riches
@AlixAxel Но я не знаю, поэтому MAC-адрес никогда не изменится. Evan Mulawski
@MatthewRiches:UUID_SHORT() недоступен в MySQL 5.0.X (я уточнил версию в моем вопросе). Я решил переключиться с автоинкрементного целого числа после прочтенияcodinghorror.com/blog/2007/03/…. Evan Mulawski
@EvanMulawski: Я понимаю, но если вы когда-нибудь это сделаете, MAC-адрес пригодится. знак равно Alix Axel

Ваш Ответ

2   ответа
4

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

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

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

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

Из фреймворка CakePHP:

http://api.cakephp.org/class/string#method-Stringuuid (торт 2.х) http://api13.cakephp.org/class/string#method-Stringuuid (торт 1.3)

Последний вариант генератора:

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

http://linux.die.net/man/1/uuid - справочная страница

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

Я заметил, что для версий пространства имен вы будете генерировать много "длинных человеческих имен". преобразовать в uuids. Пока у вас нет конфликтов с ними, это может быть очень мило. Например, пользователи, регистрирующиеся с адресами электронной почты ... Получите vuuuid для этого адреса электронной почты ... вы всегда найдете этого человека! Кажется, каждый раз выдается один и тот же UUID, и UUID будет представлять уникальное отношение [email protected] к example.com как член.

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

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

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

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

На самом деле я уделил много внимания вопросам, связанным с MySQL плюс UUID ... и я пришел к выводу, что вы хотите написать хранимую функцию, которая преобразует шестнадцатеричное представление в двоичное представление для хранения, и это все & quot; выбрать & quot; операторы требуют преобразования обратно в шестнадцатеричное представление ... и кто знает, насколько эффективно все это будет ... так что, наконец, просто переключитесь на Postgres. XD

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

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

Использование UUID и MySQL в настоящее время является плохой идеей.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededuuid()Error: User Rate Limit Exceededfunction to do that
Error: User Rate Limit Exceededuuid=UNHEX(REPLACE(?,"-",""))Error: User Rate Limit Exceeded
10

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

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

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

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

An example code (which can be used in your application as is) can be found here: 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
Error: User Rate Limit Exceeded

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