Gerar GUID no MySQL para dados existentes?


100

Acabei de importar um monte de dados para uma tabela MySQL e tenho uma coluna "GUID" que quero basicamente preencher todas as linhas existentes com novos e exclusivos GUIDs aleatórios.

Como faço isso no MySQL?

eu tentei

UPDATE db.tablename
  SET columnID = UUID()
  where columnID is not null

E fazer com que todos os campos sejam iguais


2
tem certeza de que eles são iguais? Eu tentei, a maioria dos personagens são os mesmos, mas há algumas diferenças no uuid gerado
— xiaoyifang

Sim, eu confirmo, é o mesmo!
— Cyril N.

Funciona para mim - as diferenças são mínimas, mas existem. A maneira mais rápida de verificar é adicionar uma restrição UNIQUE à coluna.
— PSU

Respostas:


88

Não tenho certeza se é a maneira mais fácil, mas funciona. A ideia é criar um gatilho que faça todo o trabalho para você, então, executar uma consulta que atualize sua tabela e, finalmente, descartar este gatilho:

delimiter //
create trigger beforeYourTableUpdate  BEFORE UPDATE on YourTable
FOR EACH ROW
BEGIN
  SET new.guid_column := (SELECT UUID());
END
//

Então execute

UPDATE YourTable set guid_column = (SELECT UUID());

E DROP TRIGGER beforeYourTableUpdate;

ATUALIZAÇÃO Outra solução que não usa gatilhos, mas requer chave primária ou índice exclusivo:

UPDATE YourTable,
INNER JOIN (SELECT unique_col, UUID() as new_id FROM YourTable) new_data 
ON (new_data.unique_col = YourTable.unique_col)
SET guid_column = new_data.new_id

ATUALIZE mais uma vez: Parece que sua consulta original também deve funcionar (talvez você não precise WHERE columnID is not null, então todo o meu código extravagante não é necessário.


sim, deve funcionar mesmo no 5.0. Mas não se esqueça de soltar o gatilho!
— a1ex07

sim, claro :) apenas me perguntando se preciso verificar se há duplicatas depois ou se isso criará valores exclusivos para cada linha na coluna?
— Tom

Se UUIDfor implementado corretamente (e eu acredito que seja), você deve ser capaz de criar um índice exclusivo sem verificar se há duplicatas.
— a1ex07

Atualizei minha resposta com outra abordagem que também pode ser útil.
— a1ex07

2
seu código original funcionaria, apenas altere columnId = UUID () para columnId = (SELECT UUID ()). Funcionou muito bem para mim. todos os valores gerados estão muito próximos de serem os mesmos, mas cada um é único.
— EJay

111

Tive a necessidade de adicionar uma coluna de chave primária guid em uma tabela existente e preenchê-la com GUIDs exclusivos e esta consulta de atualização com seleção interna funcionou para mim:

UPDATE sri_issued_quiz SET quiz_id=(SELECT uuid());

Tão simples :-)


35
A princípio pensei que isso tivesse inserido UUIDs duplicados porque todos eles começam e terminam da mesma forma, mas na verdade são um pouco diferentes.
— Sam Barnum

3
@SamBarnum porque UUIDé gerado com base na máquina e no carimbo de data / hora . Como uma consulta que leva milissegundos para ser executada, eles devem estar muito próximos ... mas nunca iguais ... uma coisa boa para garantir a você, é adicionar um UNIQUEíndice a essa coluna.
— balexandre

2
A resposta aceita parece um exagero comparando com isso!
— Xtreme Biker

4
Pelo menos em mariadb (10.1.26) isso não parece funcionar, dando o mesmo uuid para todos os registros.
— johanvdw 01 de

4
Isso gerou o mesmo UUID em todos os registros para mim, provavelmente porque está em uma subconsulta e o MySQL executará a consulta interna primeiro e usará o mesmo valor para todas as linhas. Para resolvê-lo, remova a subconsulta:UPDATE sri_issued_quiz SET quiz_id=uuid();
— Chris White

22

A solução aprovada cria IDs exclusivos, mas à primeira vista eles parecem idênticos, apenas os primeiros caracteres diferem.

Se você deseja chaves visivelmente diferentes, tente isto:

update CityPopCountry set id = (select md5(UUID()));


MySQL [imran@lenovo] {world}> select city, id from CityPopCountry limit 10;
+------------------------+----------------------------------+
| city                   | id                               |
+------------------------+----------------------------------+
| A Coruña (La Coruña)   | c9f294a986a1a14f0fe68467769feec7 |
| Aachen                 | d6172223a472bdc5f25871427ba64e46 |
| Aalborg                | 8d11bc300f203eb9cb7da7cb9204aa8f |
| Aba                    | 98aeeec8aa81a4064113764864114a99 |
| Abadan                 | 7aafe6bfe44b338f99021cbd24096302 |
| Abaetetuba             | 9dd331c21b983c3a68d00ef6e5852bb5 |
| Abakan                 | e2206290ce91574bc26d0443ef50fc05 |
| Abbotsford             | 50ca17be25d1d5c2ac6760e179b7fd15 |
| Abeokuta               | ab026fa6238e2ab7ee0d76a1351f116f |
| Aberdeen               | d85eef763393862e5fe318ca652eb16d |
+------------------------+----------------------------------+

Estou usando a versão do servidor MySQL: 5.5.40-0 + wheezy1 (Debian)


5
No meu caso, eu precisava de hifens no GUID gerado. Usei isto: SELECT INSERT(INSERT(INSERT(INSERT(MD5(UUID()), 9, 0, '-'), 14, 0, '-'), 19, 0, '-'), 24, 0, '-')Query não é muito bonito, mas faz o trabalho.
— solo

9
O md5 não é menos exclusivo do que os UUIDs? Eu me preocuparia com colisões.
— Adam

15
select @i:=uuid();
update some_table set guid = (@i:=uuid());

1
perfeito perfeito perfeito !! uma coisa tão pequena pode ter um impacto enorme !!
— thekosmix de

5

Apenas uma pequena adição a fazer, pois acabei com um resultado estranho ao tentar modificar os UUIDs conforme eram gerados. Descobri que a resposta de Rakesh é a mais simples e funciona bem, exceto nos casos em que você deseja remover os travessões.

Para referência:

UPDATE some_table SET some_field=(SELECT uuid());

Isso funcionou perfeitamente sozinho. Mas quando eu tentei isso:

UPDATE some_table SET some_field=(REPLACE((SELECT uuid()), '-', ''));

Então, todos os valores resultantes eram os mesmos (não sutilmente diferentes - verifiquei quádruplamente com uma GROUP BY some_fieldconsulta). Não importa como coloquei os parênteses, acontece a mesma coisa.

UPDATE some_table SET some_field=(REPLACE(SELECT uuid(), '-', ''));

Parece que, ao cercar a subconsulta para gerar um UUID com REPLACE, ela só executa a consulta UUID uma vez, o que provavelmente faz sentido como uma otimização para desenvolvedores muito mais inteligentes do que eu, mas não para mim.

Para resolver isso, acabei de dividi-lo em duas consultas:

UPDATE some_table SET some_field=(SELECT uuid());
UPDATE some_table SET some_field=REPLACE(some_field, '-', '');

Solução simples, obviamente, mas espero que isso economize o tempo que acabei de perder.


4

Parece um erro de digitação simples. Você não quis dizer "... where columnId is null"?

UPDATE db.tablename
  SET columnID = UUID()
  where columnID is null

1
Eu tive o mesmo pensamento quando li a pergunta, mas acho que não: parece que suas colunas contêm valores, mas não valores UNIQUE. As respostas dadas muito antes de sua resposta já mostram o que é necessário. Não deve haver uma WHEREcláusula. E os valores gerados são muito semelhantes, portanto, deve-se examiná-los de perto para ver se são realmente diferentes.
— Toolmaker Steve

3

Enfrentei principalmente o mesmo problema. No meu caso, uuid é armazenado como BINARY (16) e tem restrições NOT NULL UNIQUE. E eu enfrentei o problema quando o mesmo UUID foi gerado para cada linha, e a restrição UNIQUE não permite isso. Portanto, esta consulta não funciona:

UNHEX(REPLACE(uuid(), '-', ''))

Mas para mim funcionou, quando usei essa consulta com seleção interna aninhada:

UNHEX(REPLACE((SELECT uuid()), '-', ''))

Em seguida, é produzido um resultado exclusivo para cada entrada.


1
UPDATE db.tablename SET columnID = (SELECT UUID()) where columnID is not null

2
Adicione alguma explicação sobre como o seu código funciona. Código sem comentários nem sempre é fácil de entender para outros usuários de SO
— Simas Joneliunas

se vc deseja atualizar uuid nos dados existentes, execute a consulta como acima com sua condição.
— Ashutosh Niranjan

0

MYsql UPDATE tablename SET columnName = UUID ()

oracle UPDATE tablename SET columnName = SYS_GUID ();

SQLSERVER UPDATE tablename SET columnName = NEWID () ;;


0
// UID Format: 30B9BE365FF011EA8F4C125FC56F0F50
UPDATE `events` SET `evt_uid` = (SELECT UPPER(REPLACE(@i:=UUID(),'-','')));

// UID Format: c915ec5a-5ff0-11ea-8f4c-125fc56f0f50
UPDATE `events` SET `evt_uid` = (SELECT UUID());

// UID Format: C915EC5a-5FF0-11EA-8F4C-125FC56F0F50
UPDATE `events` SET `evt_uid` = (SELECT UPPER(@i:=UUID()));
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.