理论
我有一个非常全面的坐标列表(纬度和经度到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
- 当我们谈论坐标时,这是一个完全不同的位置!
为什么小数会从屏幕上的回显变为添加到数据库?
在添加之前,我是否需要将其转换为浮动?我该如何解决这个问题?
答案 0 :(得分:4)
<强>更新强>
我暂时没有使用过MySQL,所以我做了一些研究。看起来decimal
type能够精确到达65位数字。由于您只需要通过小数的7位数和小数点前的3位数,因此使用decimal(10,7)
创建模式应该没有问题。
假设您使用的是MySQL,那么您无能为力。根据{{3}},float
和double
类型是近似表示形式:
FLOAT和DOUBLE类型表示近似数值数据值。 MySQL对于单精度值使用四个字节,对于双精度值使用八个字节。
同时查看此the documentation,您会发现MySQL 5.5.32将代表53.7960957
为53.796100616455
的浮点数和53.7960957
的两倍53.7960957
。您可能希望更新架构以使用双精度,以获得更高的精度。
您还可以使用float(m,d)
来指定具有非标准语法的浮点数的精度(因此不建议使用其他SQL标准的可移植性),其中m
是总数位,{{1是小数点后的位数。例如,如果要允许纬度/经度值(-180到180),小数点后最多7位精度。您应该能够使用d
创建表格。但是,SQL Fiddle,这仍然不像double那么精确。
答案 1 :(得分:2)
你也可以使用1E6表示法,因此保存的整数是MySQL。
53.7960957 * 1E6 = 537960957
537960957 / 1E6 = 53.7960957
这是我用来保存地理坐标的方式