質問

理論

私には非常に包括的な座標リスト (緯度と経度を小数点以下 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).

SQLフィドル


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

これは私が地理座標を保存するために使用している方法です

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top