进行迁移时如何创建浮动但不加倍的字段?
Posted
技术标签:
【中文标题】进行迁移时如何创建浮动但不加倍的字段?【英文标题】:How to create field that is float but not double when doing Migrations? 【发布时间】:2018-04-07 23:58:05 【问题描述】:我正在使用 Laravel 的迁移系统来重新创建现有的数据库结构。这些表需要与这个现有数据库中的表完全匹配。
表中的一个字段是这样描述的:
`frequency` float unsigned NOT NULL DEFAULT 0,
查看 Laravel 迁移文档,我看到以下选项:
$table->float('amount', 8, 2);
$table->double('column', 15, 8);
这两种列类型都会创建一个带有长度和小数点的double
类型列。但我需要一个专门定义为 float
的,没有指定长度和零小数点。
可以使用 Laravel 的迁移系统吗?
【问题讨论】:
如documentation $table->float() 中所述,创建一个浮点字段。你使用的是什么版本的 Laravel / mysql? 无小数点。那不是整数吗?顺便说一句,还有一个小数选项,比双精度要精确一些。 我正在使用最新的 Laravel Homestead Vagrant 实例。 MySQL 版本是5.7.19-0ubuntu0.16.04.1
。这是一个错误吗?因为->float('whatever')
肯定是在创建double
列。
一个谷歌搜索,我发现了这个(已关闭)Github 问题:github.com/laravel/framework/issues/9103 - 似乎是设计使然。
是的,我刚刚遇到了。真的很奇怪。 MySQL 有 FLOAT 类型是有原因的,即使 DOUBLE 在技术上是一样的。
【参考方案1】:
不要在 MySQL 中的 FLOAT
或 DOUBLE
上使用 (m,n)
。该功能仅属于DECIMAL
。如果您想要零位小数,请使用某种形式的INT
。另一方面,也许您的frequency
在千兆赫?此时FLOAT
没有精度或小数,是最合适的。
请注意,1GHz 不适合 FLOAT(8,2)
,但适合 FLOAT
。
为什么两者都有?...FLOAT
占用 4 个字节; DOUBLE
需要 8 个;两者都是几乎所有计算机硬件都实施的 IEEE-754 标准的一部分。在“旧”时代(当 1MB 的 RAM 是一台“大”机器;标准可以追溯到 80 年代初),节省 4 个字节是一件大事。如果 Laravel 将 float 变成 double,那就是它的选择; MySQL 将采取任何一个。
在几乎所有情况下FLOAT
和DOUBLE
值和变量都是可以互换的。 但是...存储在FLOAT
中的值和存储在DOUBLE
中的相同值可能会导致比较不相等的值。例如,几乎所有语言、硬件等中的 float(1.234) != double(1.234)。
MySQL 对frequency float unsigned NOT NULL DEFAULT 0
很满意。
但是,如果 Laravel 中的 $table->float('amount', 8, 2);
与 MySQL 的 FLOAT(8,2)
含义相同,那么您可能会遇到大问题。
1234567.89
将被截断为999999.99
。而1.234
将被截断为1.23
,然后四舍五入为二进制。
听起来像是 Lavaral 的错误报告。 (抱歉,我从未使用过 Lavaral,所以我猜测它的细节。我确实了解 MySQL 和 IEEE-754。)
【讨论】:
【参考方案2】:这是 laravel 中的一种错误,您不能制作浮点类型列,要使列浮动使用 DB:statement 并确保不要在 Schema::create 中写入 DB::statement将抛出一个错误,因为当时数据库中不存在表。
在 Schema::table 中编写您的 DB:statement(示例代码):
Schema::table('api_logs', function (Blueprint $table)
DB::statement('alter table `api_logs` add column `response_after` float null after request_at');
DB::statement('alter table `api_logs` add column `query_time` float null after response_after');
);
upvote 这是为了更好地接触到幼虫。
【讨论】:
以上是关于进行迁移时如何创建浮动但不加倍的字段?的主要内容,如果未能解决你的问题,请参考以下文章
Laravel Artisan Migrate 命令创建表但不将每个迁移文件填充到迁移表