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.