MySql主键不使用任何大小

时间:2017-07-24 07:46:43

标签: mysql indexing mysql-workbench database-schema

我有两个表架构:

CREATE TABLE `myTable` (
  id int(11) NOT NULL AUTO_INCREMENT,
  lat double NOT NULL,
  lng double NOT NULL,
  date datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  mobile bigint(11) unsigned NOT NULL,
  date_updated datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

  PRIMARY KEY (`id`),
  KEY `IDX_Datee` (`mobile`,`date`),
  CONSTRAINT `FK_DeviceLocationss` FOREIGN KEY (`mobile`) REFERENCES `device` (`serial`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

这是第二个:

CREATE TABLE `myTable2` (
  lat double NOT NULL,
  lng double NOT NULL,
  date datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  mobile bigint(11) unsigned NOT NULL,
  date_updated datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

  PRIMARY KEY `IDX_Datee2` (`mobile`,`date`),
  CONSTRAINT `FK_DeviceLocationss2` FOREIGN KEY (`mobile`) REFERENCES `device` (`serial`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

到目前为止,每张桌子都有 4,000,000 记录, 所以我正在尝试构建最合适的架构,这种架构更快,占用更少的存储空间。

当我检查Table中每个MySql Workbeanch的状态时,我感到很困惑:

第一张表:

enter image description here

第二张表

enter image description here

当我将IDX_Datee密钥从Index更改为Primary时,它不占用任何空间。

我相信第二种模式对我来说更好,但我对这种差异没有很好的理解。

请问任何人解释一下吗?

2 个答案:

答案 0 :(得分:2)

该表是索引组织的。数据记录按索引顺序存储。 见https://dev.mysql.com/doc/refman/5.5/en/optimizing-primary-keys.html

"使用InnoDB存储引擎,表格数据在物理上进行组织,以根据主键列或列进行超快速查找和排序"

所以不需要额外的索引

答案 1 :(得分:1)

PK 指定行上的所有操作(选择,插入,删除,更新)将非常快速有效。深入了解包含数据的BTree,并由PK组织,并且有一行可以使用。

PK需要占用少量空间,就像任何BTree都超过叶节点一样。作为一个经验法则,MySQL的BTrees(数据或索引)具有大约100的扇出。也就是说,每个节点下面有大约100个节点。这意味着对于PK开销的“其余”非叶节点只有大约1%的开销。

16KB / 61约为268 - 你的“扇出”。

对于初学者,我建议DOUBLE(8字节)对于纬度和经度来说是过度杀伤力,除非你试图将一只跳蚤与另一只跳蚤区分开来。这是lat / lng的表示选择的my table

INT是4个字节。如果您确定不会超过1600万,请将PK更改为MEDIUMINT UNSIGNED(3个字节)。 (我认为这太冒险了。)

PK的大小非常重要,因为它包含在每个辅助密钥中。

如果(mobile, date)是唯一的,它也可能是PK。这样可以减少id两个副本,从而加快基于mobile的查询。

如果mobile包含电话号码,则有些号码不适合。最好使用DECIMAL(11)需要5个字节; (13)需要6.如果相反,mobile在某个其他表中是AUTO_INCREMENT,则可能是SMALLINT UNSIGNED(每个表每个副本2个字节 )会更好。

您的第一个表有4个额外列(相对于第二个表):id - 两次,mobiledate