AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 9187
Accepted
Bryan Agee
Bryan Agee
Asked: 2011-12-15 15:28:54 +0800 CST2011-12-15 15:28:54 +0800 CST 2011-12-15 15:28:54 +0800 CST

Conversão do MySQL de float (10,2) para fixed(10,2)

  • 772

Eu tenho um banco de dados que contém dados financeiros armazenados como floats. Naturalmente, isso pode apresentar um problema real em momentos aleatórios (por exemplo, quando há um valor exato que não pode ser aproximado o suficiente com um algoritmo de ponto flutuante).

Minha pergunta é :

  • O uso ALTER TABLE table MODIFY field fixed(10,2)preservará o valor fixo que é mostrado atualmente pelo MySQL quando você selecionar o campo?
  • Existe alguma possibilidade do valor ser algo diferente disso?
mysql floating-point
  • 3 3 respostas
  • 19063 Views

3 respostas

  • Voted
  1. Best Answer
    RolandoMySQLDBA
    2011-12-15T15:51:28+08:002011-12-15T15:51:28+08:00

    MÁ NOTÍCIA: Acho que o valor não será preservado!!!

    Escrevi este post (25 de julho de 2011) mostrando como os números de ponto flutuante são sensíveis às conversões.

    BOAS NOTÍCIAS: Veja como você pode comparar com segurança a conversão de dados:

    Se sua mesa tem essas características

    • tabela é chamadamoneytable
    • campo que você deseja converter é chamadomoneyfield
    • chave primária é chamadamoneyid

    Em seguida, execute estes comandos:

    DROP TABLE IF EXISTS moneytabletest;
    CREATE TABLE moneytabletest LIKE moneytable;
    ALTER TABLE moneytabletest MODIFY moneyfield fixed(10,2);
    INSERT INTO moneytabletest SELECT * FROM moneytable;
    SELECT A.moneyid,A.moneyfield olddata,B.moneyfield newdata
    FROM moneytable A LEFT JOIN moneytabletest B USING (moneyid)
    WHERE A.moneyfield <> B.moneyfield;
    

    Aqui está o resultado final: se alguma linha voltar da LEFT JOINconsulta, a conversão será ruim. Você terá que modificar a definição de moneyfield, recarregar a moneytabletesttabela e executar a LEFT JOINconsulta repetidamente até que nenhuma linha volte da LEFT JOINconsulta. Quando zero (0) linhas voltarem, você saberá qual conversão será segura.

    De uma chance !!!

    • 7
  2. Bryan Agee
    2011-12-16T07:58:03+08:002011-12-16T07:58:03+08:00

    Com base na resposta de Rolando, criei um método mais fácil de fazer uma conversão em etapas e depois comparar. Nas tabelas em questão, adicionei primeiro um novo campo do mesmo tipo. Eu espelhei os valores, executei a conversão e comparei os valores resultantes. por exemplo, para Amount float(10,2) NOT NULLeu usei:

    ALTER TABLE `table` ADD `AmountStaged` float(10,2) NOT NULL;
    UPDATE `table` SET `AmountStaged` = `Amount`;
    ALTER TABLE `table` MODIFY `AmountStaged` decimal(10,2) NOT NULL;
    SELECT * FROM `table` WHERE round(`Amount`,2) <> `AmountStaged`;
    

    Surpreendentemente, com várias tabelas (algumas com mais de 30 mil linhas), havia apenas um valor que não correspondia. Felizmente, o sinalizador excluído foi definido nesse registro específico, portanto, era irrelevante de qualquer maneira. Assim, ao obter os resultados favoráveis, a etapa final consistia em dois comandos:

    ALTER TABLE `table` DROP `Amount`;
    ALTER TABLE `table` CHANGE `AmountStaged` `Amount` decimal(10,2) NOT NULL;
    

    EDIT : A alternativa de tempo de inatividade zero seria descartar a AmountStagedcoluna e converter a Amountcoluna, pois a conversão deve ser idêntica à que executamos para testar.

    ALTER TABLE `table` MODIFY `Amount` decimal(10,2) NOT NULL;
    ALTER TABLE `table` DROP `AmountStaged`;
    
    • 4
  3. derkien
    2014-10-13T23:05:24+08:002014-10-13T23:05:24+08:00

    Obrigado a todas as respostas acima!

    Eu tenho mais de 130.972 linhas no total, existem várias colunas flutuantes com dados semelhantes a dinheiro. Então, hoje preciso converter essas colunas em decimal, porque temos alguns problemas com precisão. Usei uma das soluções acima, mas o resultado não foi exatamente o que eu preciso, como disse o autor:

    Você terá que modificar a definição de moneyfield, recarregar a tabela moneytabletest e executar a consulta LEFT JOIN repetidas vezes até que nenhuma linha volte da consulta LEFT JOIN. Quando zero (0) linhas voltarem, você saberá qual conversão será segura.

    Outro teve sorte e os registros de diferença foram marcados como excluídos ... No meu caso, após essas operações:

    ALTER TABLE `target_table` ADD `dummy_price` decimal(20,2) NOT NULL;
    UPDATE `target_table` SET `dummy_price` = CAST(`float_price` as DECIMAL(20,2));
    SELECT `float_price`, `dummy_price`  FROM `target_table` WHERE round(`float_price`, 2) <> `dummy_price`;
    

    ... obtive 87 linhas, que não correspondem. Então eu decidi apenas atualizá-lo assim:

    UPDATE `target_table` 
    SET `dummy_price` = round(`float_price`, 2) 
    WHERE round( `float_price` , 2 ) <> `dummy_price`
    

    Bem, depois disso eu tenho tudo que eu preciso. Todos os dados arredondados float_pricesão iguais a dummy_price, acho que é o suficiente.

    Acho que vou ajudar alguém.

    • 0

relate perguntas

  • Existem ferramentas de benchmarking do MySQL? [fechado]

  • Onde posso encontrar o log lento do mysql?

  • Como posso otimizar um mysqldump de um banco de dados grande?

  • Quando é o momento certo para usar o MariaDB em vez do MySQL e por quê?

  • Como um grupo pode rastrear alterações no esquema do banco de dados?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Como você mostra o SQL em execução em um banco de dados Oracle?

    • 2 respostas
  • Marko Smith

    Como selecionar a primeira linha de cada grupo?

    • 6 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Posso ver Consultas Históricas executadas em um banco de dados SQL Server?

    • 6 respostas
  • Marko Smith

    Como uso currval() no PostgreSQL para obter o último id inserido?

    • 10 respostas
  • Marko Smith

    Como executar o psql no Mac OS X?

    • 11 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Marko Smith

    Passando parâmetros de array para um procedimento armazenado

    • 12 respostas
  • Martin Hope
    Manuel Leduc Restrição exclusiva de várias colunas do PostgreSQL e valores NULL 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler Quando uma chave primária deve ser declarada sem cluster? 2011-11-11 13:31:59 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    BrunoLM Guid vs INT - Qual é melhor como chave primária? 2011-01-05 23:46:34 +0800 CST
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +0800 CST
  • Martin Hope
    Patrick Como posso otimizar um mysqldump de um banco de dados grande? 2011-01-04 13:13:48 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve