我有一张桌子
CREATE TABLE `tableMain` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`value1` varchar(45) NOT NULL,
'value2' varchar(50) NOT NULL,
'value3' int NOT NULL,
'value4' timestamp NOT NULL,
'value5' int NOT NULL
PRIMARY KEY (`id`)
)
所以我创建了那个表,我希望它总是按value2排序,如果有两个类似它应该按value3排序并且在value4之后。
所以我试着按照
来做ALTER TABLE tableMain
ORDER BY value2 ASC, value3 ASC, value4 ASC
当我运行该代码时,我收到一个错误:
错误代码:1105。ORDER BY被忽略,因为表'tableMain'中有一个用户定义的聚簇索引
我想补充一点,我把它作为学校的家庭作业,其他有相同任务的人可以运行这个ALTER TABLE行。所以我有点困惑,不知道该怎么做。
答案 0 :(得分:4)
如果您想要特定序列中的行,请在查询中指定适当的ORDER BY
子句。
在表中需要“排序”行的想法在关系数据库理论面前浮现。
关系是一组元组;改变关系中元组的“顺序”并不会改变关系。
将理论转化为实践,使用InnoDB存储引擎,将ORDER BY
指定为表属性是没有意义的,因为InnoDB表将始终按其集群索引排序。
对于MyISAM存储引擎,指定ORDER BY
可能会提高某些查询的性能。 ALTER TABLE ... ORDER BY
语句仅重新组织表一次。运行后续DELETE
,INSERT
和UPDATE
语句时,可能无法保留行的“顺序”。
重申:如果您需要按特定顺序返回的行,则不能依赖于行物理存储在表中的“顺序”。您必须在查询中包含ORDER BY
。
要真正提高大型表的性能,可以添加适当的索引。
至于你的同学为什么要运行语句,并且你的语句返回错误...最可能的解释是他们的表使用 MyISAM 存储引擎,而你的表正在使用 InnoDB 存储引擎。
(无论您的任务是什么,更改表的存储引擎都不是正确的答案...... MyISAM存储引擎是某些用例的合适选择;但InnoDB是传统“关系数据库”的最合适选择用例。)
如果您的要求是您的InnoDB表“总是按一组列排序”(无论出于何种原因),那么让集群索引包含这些列作为前导列。您可以通过将这些列声明为表的PRIMARY KEY的前导列来实现。您可以在id
列上创建一个独特的索引。
CREATE TABLE `tableMain`
( `id` INT(11) NOT NULL AUTO_INCREMENT
, `value1` VARCHAR(45) NOT NULL
, `value2` VARCHAR(50) NOT NULL
, `value3` INT NOT NULL
, `value4` TIMESTAMP NOT NULL
, `value5` INT NOT NULL
, PRIMARY KEY (`value2`,`value3`,`value4`,`id`)
, UNIQUE KEY `tableMain_UX1` (`id`)
)
实际上,我们永远不会这样做...因为任何二级索引都会将PRIMARY KEY值作为“指针”包含在群集索引中,这将是一种令人难以置信的资源浪费。在实践中,我们将id
作为表的PRIMARY KEY,并在其他列上创建二级索引......
CREATE TABLE `tableMain`
( `id` INT(11) NOT NULL AUTO_INCREMENT
, `value1` VARCHAR(45) NOT NULL
, `value2` VARCHAR(50) NOT NULL
, `value3` INT NOT NULL
, `value4` TIMESTAMP NOT NULL
, `value5` INT NOT NULL
, PRIMARY KEY (`id`)
, KEY `tableMain_IX1` (`value2`,`value3`,`value4`)
)