Página 1 de 1

Insert ou Update ?

Enviado: 31 Mai 2022 14:09
por rossine
Olá,

Como seria uma sentença em SQL para se fazer um Insert ou um update caso o registro já exista ?

Já vi que existe duas formas que são o "replace" e o "insert ... on duplicate key", mas pelo que entendi, ambos precisam de um "primary Key" e eu não estou trabalhando com "primary Key", então teria como fazer isto em uma única sentença ?

Obrigado,

Insert ou Update ?

Enviado: 31 Mai 2022 14:16
por JoséQuintas
No MySQL tem o INSERT IGNORE

Se está dizendo sobre o teste, seria fazer um SELECT antes do INSERT pra testar.

Insert ou Update ?

Enviado: 31 Mai 2022 15:44
por rossine
Olá José,

Eu preciso que caso não exista o registro, ele seja inserido ou senão seja atualizado tipo "update".

Este comando "INSERT IGNORE" faz isso, ou se já existe o registro, não faz nada e retorna um erro de execução ?

Obrigado,

Insert ou Update ?

Enviado: 31 Mai 2022 15:51
por rossine
Olá,

Como estou iniciando um novo projeto, preferi criar as chaves primárias pra deixar o SQL controlar isto, e com isto posso usar o comando "Replace Into"

Obrigado,

Insert ou Update ?

Enviado: 31 Mai 2022 15:56
por rossine
Olá,

No caso ao criar a "Primary Key" eu já tinha um Index com os mesmos campos:

Código: Selecionar todos

ALTER TABLE `Tokens`
  ADD PRIMARY KEY (`A66_AUTO`,`A66_SEQU`),
  ADD KEY `indice_princ` (`A66_AUTO`,`A66_SEQU`);
COMMIT;
Neste caso, há a necessidade de se criar este index "indice_princ" para agilizar as pesquisas, ou não precisa disto ?

Obrigado,

Insert ou Update ?

Enviado: 31 Mai 2022 16:15
por JoséQuintas
Um índice principal agiliza tudo no MySQL, mesmo que não seja usado.

Estou achando estranho o seguinte:
Como o MySQL vai saber se está duplicado sem uma chave de referência?
Ou quem ele vai atualizar sem saber qual é a chave?

Nota:

Tive certeza disso de índice numa base de uma pessoa aqui do fórum, a tabela dele tinha 100GB e não tinha índice nenhum.
Pra excluir um único registro demorava até horas.
Justamente ele estava tentando limpar a base pra deixar mais rápido.

Depois de criar um índice primário, a exclusão passou a ser quase instantânea.
E a exclusão nem usava índice nenhum, nem tinha a ver com criar índice pela chave de acesso, era exclusão direta no HeidiSQL marcando registros e excluindo.
Lógico... no caso de usar chave de acesso com índice, muito melhor e mais rápido.

Então:

1) Acostume a criar um índice pela chave primária SEMPRE, de preferência um campo incremental.
2) Ter uma chave única para a tabela é importantíssimo, mesmo se decidir não usar como chave, por exemplo numa tabela de UFs, onde a chave principal é a sigla.

Insert ou Update ?

Enviado: 31 Mai 2022 16:32
por rossine
Olá José,

Obrigado pelas informações, irei adotar o esquema de sempre criar os índices, tanto "primários", ou para ordenar por exemplo por "nome" para agilizar na hora de pesquisa por "nome".

Insert ou Update ?

Enviado: 31 Mai 2022 17:33
por alxsts
Olá!
rossine escreveu:Neste caso, há a necessidade de se criar este index "indice_princ" para agilizar as pesquisas, ou não precisa disto ?
Não, não precisa. Se você criar uma primary key para a tua tabela, o que é altamente recomendável, isto já será seu índice principal. Criar a primary key e um índice adicional com as mesmas colunas da PK será uma redundância e desperdício de recursos do sistema...
JoséQuintas escreveu:Então:
1) Acostume a criar um índice pela chave primária SEMPRE, de preferência um campo incremental.
Isto não ficou claro para mim. Você recomenda criar a PK e o índice? Ou "criar um índice pela chave primária" quer dizer criar a PK?

Lembrando que uma primary key não aceita valores duplicados ou NULL e que cada tabela pode ter apenas uma primary key. Prymary keys são semelhantes aos unique indexes mas, estes últimos podem conter NULL e uma tabela pode ter mais de um unique index. Procure evitar primary keys compostas (formadas por mais de uma coluna).
rossine escreveu:Já vi que existe duas formas que são o "replace" e o "insert ... on duplicate key"
Além das formas que você citou, existe o INSERT IGNORE, citado anteriormente.

Evite usar REPLACE. Este comando, quando necessário (quando já existe a linha desejada), ele faz um DELETE E depois um INSERT, consumindo mais recursos que um INSERT ... ON DUPLICATE KEY UPDATE que faz um INSERT OU UPDATE, como no exemplo abaixo.

Código: Selecionar todos

INSERT INTO books
    (id, title, author, year_published)
VALUES
    (@id, @title, @author, @year_published)
ON DUPLICATE KEY UPDATE
    title = @title,
    author = @author,
    year_published = @year_published;

Insert ou Update ?

Enviado: 31 Mai 2022 18:24
por JoséQuintas
alxsts escreveu:Isto não ficou claro para mim. Você recomenda criar a PK e o índice? Ou "criar um índice pela chave primária" quer dizer criar a PK?
Ter sempre uma PRIMARY KEY única, de preferência incremental.
Se tiver mais índices, vai ser pra agilizar determinadas consultas/filtros.
importante: no SQL, índices são pra consultas/filtros, e não pra relatório em ordem alfabética, por exemplo.

Muito antigamente o MySQL permitia chave composta pra índice incremental, nem sei se isso ainda existe, acho que foi removido.
E esse índice PRIMARY KEY pode até se tornar obrigatório, por enquanto mostram mais como recomendação.

Insert ou Update ?

Enviado: 31 Mai 2022 18:27
por JoséQuintas
Não entendi esse ON UPDATE, porque tá parecendo stored procedure.
Deve necessitar a definição de variáveis primeiro.
Ou vai precisar um comando grande, repetindo os campos, apesar disso não ser problema.

Insert ou Update ?

Enviado: 31 Mai 2022 19:11
por alxsts
Olá!
JoséQuintas escreveu:Ter sempre uma PRIMARY KEY única, de preferência incremental.
Se tiver mais índices, vai ser pra agilizar determinadas consultas/filtros.
Agora entendi o que quis dizer. PRIMARY KEY são sempre únicas dentro da mesma tabela.
JoséQuintas escreveu:no SQL, índices são pra consultas/filtros, e não pra relatório em ordem alfabética, por exemplo.
Eventualmente servem para ORDER BY também, se for mais barato usar o índice do que fazer a operação FileSort. Veja ORDER BY Optimization. Portanto, se quiser um relatório de clientes ordenado alfabeticamente e a tabela tiver o índice disponível, ele vai ser utilizado. O mesmo ocorre com GROUP BY (veja GROUP BY Optimization) e provavelmente com HAVING, visto que este último precisa do GROU BY.
JoséQuintas escreveu:Não entendi esse ON UPDATE, porque tá parecendo stored procedure.
Deve necessitar a definição de variáveis primeiro.
Ou vai precisar um comando grande, repetindo os campos, apesar disso não ser problema.
Depende da situação, pode usar o comando colocando os valores literais (por exemplo, no HeidiSQL) ou passar parâmetros para uma stored procedures e usar como variáveis para depois executar com PREPARE e EXECUTE, ou até montar uma string no Harbour, concatenando os valores e depois executando...

Insert ou Update ?

Enviado: 31 Mai 2022 22:53
por JoséQuintas
alxsts escreveu:Eventualmente servem para ORDER BY também, se for mais barato usar o índice do que fazer a operação FileSort. Veja ORDER BY Optimization. Portanto, se quiser um relatório de clientes ordenado alfabeticamente e a tabela tiver o índice disponível, ele vai ser utilizado.
Confusa a explicação do link.
Chamou a atenção numa parte, onde diz que se todos os campos estão no índice, é usado somente o índice - isso é algo conhecido em DBF.
De resto parece muito eventual.
alxsts escreveu:O mesmo ocorre com GROUP BY (veja GROUP BY Optimization) e provavelmente com HAVING, visto que este último precisa do GROU BY.
Discordo da comparação, são coisas distintas.
GROUP BY tem a ver com filtro e não com ordem.

Insert ou Update ?

Enviado: 31 Mai 2022 23:07
por alxsts
Olá!
JoséQuintas escreveu:Discordo da comparação, são coisas distintas.
GROUP BY tem a ver com filtro e não com ordem.
discordando ou não, há situações onde o índice é usado no GROU BY, conforme consta no manual (link acima).

Edit:
Ah... GROUP BY não tem nada a ver com filtro e sim com agrupamento. Filtro é WHERE (filtra linhas) e HAVING (filtra grupos de linhas após o GROUP BY )...

Insert ou Update ?

Enviado: 01 Jun 2022 14:04
por JoséQuintas
alxsts escreveu:discordando ou não, há situações onde o índice é usado no GROU BY, conforme consta no manual (link acima).
Edit:
Ah... GROUP BY não tem nada a ver com filtro e sim com agrupamento. Filtro é WHERE (filtra linhas) e HAVING (filtra grupos de linhas após o GROUP BY )...
Na primeira parte, ao me referir que GROUP BY faz parte do filtro, vale o que eu disse que índice pode ser usado pra agilizar filtro, apesar do GROUP BY realmente não ser filtro.

Na segunda parte tenho dúvidas sobre o HAVING, porque teoricamente o HAVING depende dos cálculos do GROUP BY, então a otimização vai ser antes dele ser usado..

Insert ou Update ?

Enviado: 06 Jun 2022 16:36
por rossine
Olá,

Alxsts, irei estudar a possibilidade de usar o "Insert ... On Duplicate Key...."

Obrigado a todos pelas informações e dicas,