【发布时间】:2017-10-13 04:15:29
【问题描述】:
这是我在一次采访中遇到的一个问题。
假设您有一个包含以下列的数据库:“row_id”、“payload_data”和“time_stamp”。但是您一次只能保留一列的索引。
如何为“row_id”和“time_stamp”保留索引?
【问题讨论】:
-
这没有意义。也许面试官的知识不如你。
这是我在一次采访中遇到的一个问题。
假设您有一个包含以下列的数据库:“row_id”、“payload_data”和“time_stamp”。但是您一次只能保留一列的索引。
如何为“row_id”和“time_stamp”保留索引?
【问题讨论】:
我认为这个问题应该是“聪明的”,预期的答案是:
将
row_id设为表的主键并在time_stamp上创建索引。
这样表就只有一个附加索引。无论如何都需要并创建主键。
总而言之,该表有两个索引,在我看来,这是一个低质量的面试问题。
【讨论】:
这显然是人为的要求,因为没有理由避免使用多列索引。
一种解决方案是创建一个连接row_id 和time_stamp 的虚拟列,并对虚拟列进行索引。
CREATE TABLE `artificial` (
`row_id` int NOT NULL,
`time_stamp` timestamp NULL DEFAULT NULL,
`payload_data` text,
`row_id_time_stamp` varchar(20)
GENERATED ALWAYS AS (concat(`row_id`,':',`time_stamp`)) VIRTUAL,
KEY `row_id_time_stamp` (`row_id_time_stamp`)
)
但该索引不如多列索引灵活。如果您在两列上都进行搜索,它可以工作,但如果您想使用 = 搜索特定的 row_id 值,它将无法工作。
也就是说,这个条件可以使用多列索引,但不能使用连续索引:
... WHERE row_id = '1234'
要使用连接索引,您要么必须搜索模式,要么搜索两列的连接值:
... WHERE row_id_time_stamp LIKE '1234:%'
... WHERE row_id_time_stamp = '1234:2017-10-12 22:27:00'
另一种可能的解释是,如果row_id 是主键,那么time_stamp 上的二级索引隐含地包含row_id,因为InnoDB 实现二级索引的方式。所以这可能是一个测试 MySQL/InnoDB 内部的问题。
【讨论】:
PK 列是正确的(作为隐藏列),但不能使用这样的索引按 PK 列的值进行搜索.