Masalahnya bukan pada penyimpanan. Dalam contoh Anda, nilainya dipecah sebelum menyimpannya di tabel.
Sayangnya, jika Anda menulis 1/3, itu akan dihitung (dan disisipkan) menggunakan representasi default:
SELECT 1/3
0.333333333
yang, seperti yang Anda lihat, memiliki presisi yang tidak memadai.
Masalah tambahannya adalah ketika Anda mengirim konstanta (1, atau 3) ke server, Anda melakukannya menggunakan perpustakaan atau konektor, yang dapat memberikan kebebasan pada nilai. Misalnya, mereka mungkin percaya bahwa "1" dan "3" adalah bilangan bulat dan hasilnya harus diperlakukan sebagai bilangan bulat. Jadi Anda mendapatkan "1/3 = 0", tetapi "1./3 = 0,333333", karena titik di "1." membuat konektor menyadari bahwa ia perlu menggunakan floating point defaultnya. Dan Anda hanya mendapatkan enam angka 3 karena "floating point default" konektor memiliki 6 digit. Lalu Anda menyimpannya ke dalam database, tetapi sudah terlambat. Anda menyimpan dengan presisi tinggi nilai yang telah dipotong menjadi presisi rendah.
Anda dapat mencoba memberikan konstanta dari awal. Alih-alih "1", Anda menggunakan 1 sebagai desimal yang cukup besar. Saya menggunakan 31,30 Anda di sini, tetapi pastikan Anda tidak perlu menyimpan angka yang lebih besar. Mungkin, "31,20" akan lebih baik.
mysql> SELECT 1/3 UNION SELECT CAST(1 AS DECIMAL(31,30))/CAST(3 AS DECIMAL(31,30));
+----------------------------------+
| 1/3 |
+----------------------------------+
| 0.333333333000000000000000000000 |
| 0.333333333333333333333333333333 |
+----------------------------------+
2 rows in set (0.00 sec)
Ini sangat canggung, tetapi hasilnya seharusnya lebih baik. Selain itu, menurut saya, hanya perlu memberikan nilai satu dalam sebuah ekspresi; MySQL kemudian akan mempromosikan semua jumlah yang terlibat sesuai kebutuhan. Jadi, menambahkan CAST(0 AS DECIMAL(x,y)) ke penjumlahan dan CAST(1 AS DECIMAL(x,y)) ke perkalian mungkin sudah cukup.
mysql> SELECT 3*CAST(1 AS DECIMAL(31,30))/CAST(3 AS DECIMAL(31,30));
+-------------------------------------------------------+
| 3*CAST(1 AS DECIMAL(31,30))/CAST(3 AS DECIMAL(31,30)) |
+-------------------------------------------------------+
| 1.000000000000000000000000000000 |
+-------------------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT CAST(1 AS DECIMAL(31,30))*1/3;
+----------------------------------+
| CAST(1 AS DECIMAL(31,30))*1/3 |
+----------------------------------+
| 0.333333333333333333333333333333 |
+----------------------------------+
1 row in set (0.00 sec)
Perhatikan bahwa ini tidak berfungsi karena perkalian memiliki prioritas lebih tinggi:
mysql> SELECT CAST(0 AS DECIMAL(31,30))+1/3;
+----------------------------------+
| CAST(0 AS DECIMAL(31,30))+1/3 |
+----------------------------------+
| 0.333333333000000000000000000000 |
+----------------------------------+
1 row in set (0.00 sec)
person
LSerni
schedule
16.03.2017