データベースに追加するときにLaravelのfloat変数の値が変更される
-
21-12-2019 - |
質問
理論
私には非常に包括的な座標リスト (緯度と経度を小数点以下 7 桁まで) があり、継続的に追加していきたいと考えています。データの重複を防ぐために、入力しようとしている座標ごとにデータベースをチェックして、同じ行に緯度と経度が存在するかどうかを確認したいと思います。
座標が存在するかどうかを確認する
$coordinate = DB::table('coordinates')
->where('lat', '=', $geocode->getLatitude())
->where('lng', '=', $geocode->getLongitude())
->count();
移行
Schema::create('coordinates', function(Blueprint $table)
{
$table->increments('id');
$table->float('lat', 10, 7);
$table->float('lng', 10, 7);
$table->timestamps();
});
ユーザーのアドレスが変換されるときに、次のことに気づきました。 dd()
緯度変数を指定すると、次のようになります。
float(53.7960957)
コードから dd($geocode->getLatitude());
後でデータベースに追加しようとすると、 dd()
, 、データベースに追加される実際の小数は次のとおりです。 53.7960968
- 座標の話になると、まったく別の場所になります。
小数点が画面上のエコーからデータベースへの追加に変わるのはなぜですか?
追加する前に浮動小数点に変換する必要がありますか?どうすればこれを解決できますか?
解決
アップデート:
しばらく MySQL を使用していなかったので、さらに調べてみました。のように見えます decimal
タイプ 最大 65 桁まで正確に測定できる機能があります。小数点以下の 7 桁と小数点の前の 3 桁だけが必要なので、次のようにスキーマを作成しても問題ありません。 decimal(10,7)
.
MySQL を使用していると仮定すると、できることはあまりありません。によると 文書, float
そして double
タイプはおおよその表現です。
FLOAT 型と DOUBLE 型は、おおよその数値データ値を表します。MySQL は、単精度値に 4 バイト、倍精度値に 8 バイトを使用します。
こちらもチェックしてください SQLフィドル, 、MySQL 5.5.32 が次の float を表すことがわかります。 53.7960957
として 53.796100616455
そして倍の 53.7960957
として 53.7960957
. 。精度を少し高めるために、代わりに double を使用するようにスキーマを更新することもできます。
次を使用して、非標準構文で float の精度を指定することもできます (他の SQL 標準への移植性を考慮すると、これはお勧めできません)。 float(m,d)
どこ m
は合計桁数であり、 d
小数点以下の桁数です。たとえば、小数点以下最大 7 桁の精度で緯度/経度の値 (-180 ~ 180) を許可したい場合は、次のようにテーブルを作成できるはずです。 float(10,7)
. 。しかし、 ご覧のとおり, 、これでも double ほど正確ではありませんでした。
他のヒント
前者が言うように...FLOAT の代わりに DOUBLE を使用します ...
1E6 表記を使用して、MySQL に保存する整数を使用することもできます。
53.7960957 * 1E6 = 537960957
537960957 / 1E6 = 53.7960957
これは私が地理座標を保存するために使用している方法です