进行迁移时如何创建浮动但不加倍的字段?

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 中的 FLOATDOUBLE 上使用 (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 将采取任何一个。

在几乎所有情况下FLOATDOUBLE 值和变量都是可以互换的。 但是...存储在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 这是为了更好地接触到幼虫。

【讨论】:

以上是关于进行迁移时如何创建浮动但不加倍的字段?的主要内容,如果未能解决你的问题,请参考以下文章

添加新的唯一字段时如何正确进行迁移

PHPMYadmin 表迁移

Laravel Artisan Migrate 命令创建表但不将每个迁移文件填充到迁移表

带有迁移的生成的数据库字段

在创建新字段的迁移时,将数据从一个字段复制到另一个字段的最佳方法是什么?

如何从 Laravel 项目中删除所有迁移但保留表和字段