Генерация совершенно другого UUID для MySql - PullRequest
1 голос
/ 07 мая 2020

Я видел другие похожие вопросы по SO, но на то, что я задаю здесь, нет ответа.

У меня есть поле с именем GUID в моей таблице, которое является первичным ключом.

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

Итак, я создал эту таблицу:

CREATE TABLE `myTable` (
  `id` int(6) NOT NULL,
  `first_name` varchar(64) NOT NULL,
  `last_name` varchar(64) NOT NULL,
  `GUID` char(40) NOT NULL,
   PRIMARY KEY(`GUID`) 

) ENGINE=MyISAM DEFAULT CHARSET=latin1;

DELIMITER //
CREATE TRIGGER `t_GUID` BEFORE INSERT ON `myTable`
 FOR EACH ROW begin
 SET new.GUID := (SELECT uuid());
END //
DELIMITER ;

Я вставил в это 4 новые записи таблица, и это UUID, добавленные к записям:

  • ae353781-9022-11ea-b775-1866daed31d4
  • ae353a23-9022-11ea-b775-1866daed31d4
  • ae353b4e-9022-11ea-b775-1866daed31d4
  • ae353c26-9022-11ea-b775-1866daed31d4

за исключением 3 цифр, это в основном один и тот же UUID.

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

Ответы [ 2 ]

3 голосов
/ 07 мая 2020

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

Такие большие первичные ключи действительно занимают много места, что снижает производительность.

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

Другой аргумент против этого - то, что обфускация не является безопасностью. Если есть проблема с точки зрения безопасности, когда кто-то видит что-то, чего им не следует, потому что он получил доступ, например, к URL-адресу с id=3, то такая же проблема существует, если URL-адрес id=ae353c26-9022-11ea-b775-1866daed31d4. Приложение не должно разрешать кому-либо доступ к id=3, если они не должны иметь к нему доступ.

С учетом сказанного, один обходной путь, используемый для этого типа схемы, будет иметь sh ввод.

Вы можете использовать uuid, объединенный с некоторыми данными из строки, и, возможно, с меткой времени, и чем-то случайным, и, например, запустить это через sha1 (). Это создаст большую шестнадцатеричную строку из 40 символов.

Существует вероятность столкновения, поэтому вы, вероятно, захотите проверить и исправить это.

CREATE TABLE `myTable` (
  `id` int(6) NOT NULL,
  `first_name` varchar(64) NOT NULL,
  `last_name` varchar(64) NOT NULL,
  `GUID` char(40) NOT NULL,
   PRIMARY KEY(`GUID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

DELIMITER //

CREATE TRIGGER `t_GUID` BEFORE INSERT ON `myTable`
 FOR EACH ROW begin
 SET new.GUID := (SELECT SHA1(CONCAT(new.first_name, RAND(), UUID(), new.last_name, NOW())));
END //
DELIMITER ;
0 голосов
/ 24 мая 2020

Функция uuid () генерирует UUIDv1, который определен довольно предсказуемым способом. Если вы очень быстро сгенерируете кучу новых значений, они будут отличаться всего на несколько бит, но они все равно будут уникальными.

Если вам нужны непредсказуемые значения, вам нужно переключиться на функцию, которая генерирует UUIDv4. Это только статистически уникально, но если вы не генерируете миллиарды значений в секунду в течение миллиардов лет, на практике этого достаточно. и повысить эффективность поиска. Вы можете использовать сгенерированный столбец для получения текстовой версии, если она вам нужна внутри БД для устранения неполадок.

...