sql - Rails:如何在 rails 的非 id 列上创建聚集索引?
问题描述
我想将时间序列数据存储在数据库中。数据将按如下方式组织:
- 标题表包含有关数据集的信息(格式、来源等)。通常,一个数据集将有大约 600 行。
- “大数据”表具有实际的数据行。每行都有一个 header_id、时间戳和一些数据点。
我正在尝试在 data_header_id 列而不是 id 列上创建具有聚集索引的表。这样我就可以通过简单的SELECT * FROM big_datums WHERE data_header_id = 9001 ORDER BY timestamp ASC
.
我有以下代码,但由于 Rails 的默认设置而出错:
class CreateBigData < ActiveRecord::Migration[5.2]
def up
create_table :headers do |t|
t.string :data_format
t.timestamps
end
create_table :big_datums do |t|
t.references :data_header, null: false # This will need to be a CLUSTED index
t.integer :timestamp
t.integer :point1
t.integer :point2
end
execute "CREATE CLUSTERED INDEX [data-header-index] ON [dbo].[big_datums] ( [data_header_id] ASC )
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF,
ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]"
end
end
def down
execute "DROP INDEX [data-header-index] ON [dbo].[big_datums] WITH ( ONLINE = OFF )"
drop_table :big_datums
drop_table :headers
end
end
我收到此错误:
ActiveRecord::StatementInvalid: TinyTds::Error: 无法在表 'dbo.big_datums' 上创建多个聚集索引。在创建另一个之前删除现有的聚集索引 'PK__build_te__3213E83F6568EFB2'。
这似乎是因为 rails 已经为 id 提供了集群 PK。
问题:
1)如何按照描述创建表?
2)我还需要一个“id”列吗?我永远不会通过 ID 列进行查询,但是拥有一个 PK 列来唯一标识记录可能仍然很好——尤其是因为 header_id + timestamp 可能不是一个好的集群 PK
解决方案
您已经有一个clustered index
on big_datums
,只能clustered index
在一个表上,因为它定义了数据的物理结构(数据如何存储等)。您可以创建一个非聚集索引来支持您的查询,或者只保留现有索引。您可以拥有许多它们,它们是聚集索引/堆的附加结构。
CREATE NONCLUSTERED INDEX [data-header-index] ON [dbo].[big_datums] ( [data_header_id] ASC )
最好在您的 . 中有一个唯一键clustered index
,因为在其他情况下,sql server 会为您的 8kb 页面增加一些开销以使行唯一。