MySQL auto_increment列声明为float

时间:2017-05-16 19:03:48

标签: mysql database

在Ubuntu linux服务器上存储在MySQL 5.5版数据库中的表InnoDB需要一些帮助。

在此表中有一个primat键列“id”,其属性为auto increment,并声明为float。

目前,此表中存储的自动增量值已达到较高值(大约超过200万)。

现在,当我从这个表中转储(或选择)一系列记录时,我看不到从增量到达的正确值,而是一个舍入值(例如:2233937 becames 2233940用于下一个记录,依此类推其他记录)。这导致我导入MySQL转储文件时出现故障,因为自动增量值已四舍五入,并且许多记录具有相同的增量ID。

旁注。在这个数据库中,我有其他具有相同情况的表(colums主键声明为带有自动增量属性的float)但是在其中存储了一个小的增量值。在这些表中,存储的自动增量值具有正确的数字。

然后,我有这些问题:

1)为什么在这张桌子上我有这​​种行为?该列已达到最大大小?

2)如何使用此表解决此问题?

非常感谢您的回复。

洛伦佐

更新

目前,我采用这种方法来解决这个问题。

我已经执行命令ALTER TABLE将列的类型从float修改为整数,这似乎有效。

拜托,您能否向我确认这是解决这个问题的正确方法(或许是其中一种方法)?

1 个答案:

答案 0 :(得分:0)

正如文档中提到的那样:

  

B.5.4.8 Problems with Floating-Point Values

     

浮点数有时会引起混淆,因为它们是   近似值并未存储为精确值。

本地测试提供了几种替代方案,但没有保证(特别是第二种方案):

备选方案1:

mysql> DROP TABLE IF EXISTS `tbl_test`;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE IF NOT EXISTS `tbl_test` (
    ->   `id` FLOAT UNSIGNED AUTO_INCREMENT PRIMARY KEY
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW CREATE TABLE `tbl_test`\G
*************************** 1. row ***************************
       Table: tbl_test
Create Table: CREATE TABLE `tbl_test` (
  `id` float unsigned NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

mysql> INSERT INTO `tbl_test`
    ->   (`id`)
    -> VALUES
    ->   (2233937),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (16776999),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL);
Query OK, 32 rows affected (0.00 sec)
Records: 32  Duplicates: 0  Warnings: 0

mysql> SELECT `id`,
    ->        CONVERT(`id`, UNSIGNED)
    -> FROM `tbl_test`;
+----------+-------------------------+
| id       | CONVERT(`id`, UNSIGNED) |
+----------+-------------------------+
|  2233940 |                 2233937 |
|  2233940 |                 2233938 |
|  2233940 |                 2233939 |
|  2233940 |                 2233940 |
|  2233940 |                 2233941 |
|  2233940 |                 2233942 |
|  2233940 |                 2233943 |
|  2233940 |                 2233944 |
|  2233940 |                 2233945 |
|  2233950 |                 2233946 |
|  2233950 |                 2233947 |
|  2233950 |                 2233948 |
|  2233950 |                 2233949 |
|  2233950 |                 2233950 |
|  2233950 |                 2233951 |
|  2233950 |                 2233952 |
| 16777000 |                16776999 |
| 16777000 |                16777000 |
| 16777000 |                16777001 |
| 16777000 |                16777002 |
| 16777000 |                16777003 |
| 16777000 |                16777004 |
| 16777000 |                16777005 |
| 16777000 |                16777006 |
| 16777000 |                16777007 |
| 16777000 |                16777008 |
| 16777000 |                16777009 |
| 16777000 |                16777010 |
| 16777000 |                16777011 |
| 16777000 |                16777012 |
| 16777000 |                16777013 |
| 16777000 |                16777014 |
+----------+-------------------------+
32 rows in set (0.00 sec)

示例db-fiddle

备选方案2 :(小心)

mysql> DROP TABLE IF EXISTS `tbl_test`;
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE IF NOT EXISTS `tbl_test` (
    ->   `id` FLOAT UNSIGNED AUTO_INCREMENT PRIMARY KEY
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW CREATE TABLE `tbl_test`\G
*************************** 1. row ***************************
       Table: tbl_test
Create Table: CREATE TABLE `tbl_test` (
  `id` float unsigned NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

mysql> INSERT INTO `tbl_test`
    ->   (`id`)
    -> VALUES
    ->   (2233937),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (16776999),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL),
    ->   (NULL);
Query OK, 32 rows affected (0.00 sec)
Records: 32  Duplicates: 0  Warnings: 0

mysql> ALTER TABLE `tbl_test` CHANGE `id`
    ->   `id` FLOAT(8, 0) UNSIGNED AUTO_INCREMENT;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> SHOW CREATE TABLE `tbl_test`\G
*************************** 1. row ***************************
       Table: tbl_test
Create Table: CREATE TABLE `tbl_test` (
  `id` float(8,0) unsigned NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=16777016 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

mysql> SELECT `id`
    -> FROM `tbl_test`;
+----------+
| id       |
+----------+
|  2233937 |
|  2233938 |
|  2233939 |
|  2233940 |
|  2233941 |
|  2233942 |
|  2233943 |
|  2233944 |
|  2233945 |
|  2233946 |
|  2233947 |
|  2233948 |
|  2233949 |
|  2233950 |
|  2233951 |
|  2233952 |
| 16776999 |
| 16777000 |
| 16777001 |
| 16777002 |
| 16777003 |
| 16777004 |
| 16777005 |
| 16777006 |
| 16777007 |
| 16777008 |
| 16777009 |
| 16777010 |
| 16777011 |
| 16777012 |
| 16777013 |
| 16777014 |
+----------+
32 rows in set (0.00 sec)

示例db-fiddle

其他感兴趣的信息: