我有一个具有以下结构的表的主键,
Run Code Online (Sandbox Code Playgroud)**Field** **Type** nid int(10)unsigned
我知道 int(10) 的最大限制是 4294967295。但是如果超过最大值会怎样?我应该改成 bigint 吗?如果是这样,在主键中使用 int 或 big int 的最佳做法是什么?
由于您需要转到 BIGINT,因此请为磁盘空间增长做好准备。
对于每个使用 INT 且您想要切换到 BIGINT 的表,您必须预测预期需要多少额外空间。
例如,要计算mydb.mytable将所有 INT(10) 列移至 BIGINT 时会增加多少空间,请运行此查询
SELECT CONCAT('SELECT COUNT(1)*',int_column_count*4,
' SizeIncreaseInBytes FROM ',table_schema,'.',table_name,';') INTO @SQLStmt
FROM (SELECT table_schema,table_name,
COUNT(1) int_column_count from
(
SELECT table_schema,table_name,column_type
FROM information_schema.columns
where table_schema = 'mydb'
AND table_name = 'mytable'
AND column_type = 'int(10)'
) AA group by table_schema,table_name) A;
SELECT @SQLStmt;
PREPARE s FROM @SQLStmt;
EXECUTE s; DEALLOCATE PREPARE s;
Run Code Online (Sandbox Code Playgroud)
让我们使用表格dev_oxygen.bplv_reg
mysql> show create table dev_oxygen.bplv_reg\G
*************************** 1. row ***************************
Table: bplv_reg
Create Table: CREATE TABLE `bplv_reg` (
`id` int(11) NOT NULL DEFAULT '0',
`firstname` varchar(40) DEFAULT NULL,
`lastname` varchar(40) DEFAULT NULL,
`address` varchar(255) DEFAULT NULL,
`city` varchar(100) DEFAULT NULL,
`state` varchar(20) DEFAULT NULL,
`zipcode` varchar(11) DEFAULT NULL,
`email` varchar(200) NOT NULL,
`phone` bigint(20) DEFAULT NULL,
`age` int(10) DEFAULT NULL,
`newsletter` smallint(6) NOT NULL DEFAULT '0',
`ip_address` varchar(20) DEFAULT NULL,
`fb_user_id` int(20) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
请注意,该表的年龄为 int(10)
这是表计数:
mysql> SELECT COUNT(1) FROM dev_oxygen.bplv_reg;
+----------+
| COUNT(1) |
+----------+
| 2038 |
+----------+
1 row in set (0.00 sec)
mysql>
Run Code Online (Sandbox Code Playgroud)
现在让我们计算表必须增长的字节数:
mysql> SELECT CONCAT('SELECT COUNT(1)*',int_column_count*4,
-> ' SizeIncreaseInBytes FROM ',table_schema,'.',table_name,';') INTO @SQLStmt
-> FROM (SELECT table_schema,table_name,
-> COUNT(1) int_column_count from
-> (
-> SELECT table_schema,table_name,column_type
-> FROM information_schema.columns
-> where table_schema = 'dev_oxygen'
-> AND table_name = 'bplv_reg'
-> AND column_type = 'int(10)'
-> ) AA group by table_schema,table_name) A;
Query OK, 1 row affected (0.00 sec)
mysql> SELECT @SQLStmt;
+-----------------------------------------------------------------+
| @SQLStmt |
+-----------------------------------------------------------------+
| SELECT COUNT(1)*4 SizeIncreaseInBytes FROM dev_oxygen.bplv_reg; |
+-----------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> PREPARE s FROM @SQLStmt;
Query OK, 0 rows affected (0.00 sec)
Statement prepared
mysql> EXECUTE s; DEALLOCATE PREPARE s;
+--------------------+
| SizeIncreaseInBytes|
+--------------------+
| 8152 |
+--------------------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql>
Run Code Online (Sandbox Code Playgroud)
该数字只是列的大小增加(以字节为单位)age。
关于id?它不是 int(10) 而是 int(11)。您可以预测 int(11) 吗?当然,只需int(10)在查询中替换为int(11).
主键怎么样?如果主键有多个定义为 int(11) 的 int 列怎么办?
让我们选择一个不同的表,称为oxygen.history;
mysql> show create table oxygen.history\G
*************************** 1. row ***************************
Table: history
Create Table: CREATE TABLE `history` (
`uid` int(11) NOT NULL DEFAULT '0',
`nid` int(11) NOT NULL DEFAULT '0',
`timestamp` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`uid`,`nid`),
KEY `nid` (`nid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> select count(1) from oxygen.history;
+----------+
| count(1) |
+----------+
| 564 |
+----------+
1 row in set (0.00 sec)
mysql>
Run Code Online (Sandbox Code Playgroud)
该表的主键有两列,两列都是int(11)
mysql> select CONCAT('SELECT COUNT(1)*',int_column_count*4,
-> ' IndexSizeIncreaseInBytes FROM ',table_schema,'.',table_name,';')
-> INTO @SQLStmt FROM
-> (SELECT AA.table_schema,AA.table_name,
-> COUNT(1) int_column_count FROM
-> (
-> select table_schema,table_name,column_name
-> from information_schema.columns
-> where table_schema ='oxygen'
-> and table_name='history'
-> and column_type = 'int(11)'
-> ) AA INNER JOIN
-> (
-> select table_schema,table_name,column_name
-> FROM information_schema.STATISTICS
-> WHERE INDEX_NAME='PRIMARY'
-> ) BB
-> USING (table_schema,table_name,column_name)
-> GROUP BY AA.table_schema,AA.table_name) A;
Query OK, 1 row affected (0.02 sec)
mysql> SELECT @SQLStmt;
+-----------------------------------------------------------------+
| @SQLStmt |
+-----------------------------------------------------------------+
| SELECT COUNT(1)*8 IndexSizeIncreaseInBytes FROM oxygen.history; |
+-----------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> PREPARE s FROM @SQLStmt;
Query OK, 0 rows affected (0.00 sec)
Statement prepared
mysql> EXECUTE s; DEALLOCATE PREPARE s;
+--------------------------+
| IndexSizeIncreaseInBytes |
+--------------------------+
| 4512 |
+--------------------------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql>
Run Code Online (Sandbox Code Playgroud)
根据主键的预测增长量,您现在可以增加这些
| 归档时间: |
|
| 查看次数: |
3836 次 |
| 最近记录: |