Rails: Как мне создать кластерный индекс для столбца без идентификатора в rails? - PullRequest
0 голосов
/ 15 июня 2019

Я хочу сохранить данные временных рядов в базе данных. Данные будут организованы следующим образом:

  • Таблица заголовков содержит информацию о наборе данных (формат, источник и т. Д.). Обычно набор данных будет иметь около 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 :: Ошибка: невозможно создать более одного кластеризованного индекса для таблицы 'dbo.big_datums'. Удалите существующий кластеризованный индекс «PK__build_te__3213E83F6568EFB2» перед созданием другого.

Похоже, это связано с тем, что rails уже дает id кластерному PK.

Вопросы:

1) Как создать таблицу, как описано?

2) Мне все еще нужен столбец id? Я никогда не буду запрашивать по столбцу идентификатора, но все же было бы хорошо иметь столбец PK для уникальной идентификации записей - тем более, что header_id + timestamp может быть не хорошим кластеризованным PK

Ответы [ 2 ]

1 голос
/ 15 июня 2019

У вас уже есть clustered index на big_datums, в таблице может быть только clustered index, потому что она определяет физическую структуру данных (как хранятся данные и т. Д.). Вы можете создать некластеризованный индекс для поддержки вашего запроса или просто оставить существующий индекс. Их может быть много, и они являются дополнительными структурами для вашего кластерного индекса / кучи.

CREATE NONCLUSTERED INDEX [data-header-index] ON [dbo].[big_datums] ( [data_header_id] ASC )

Хорошо иметь уникальный ключ в вашем clustered index, потому что в другом случае сервер sql добавит некоторые накладные расходы на ваши страницы 8 КБ, чтобы сделать строки уникальными.

0 голосов
/ 15 июня 2019

Сначала вам нужно удалить ограничение PK. И вам, вероятно, следует просто заменить существующий кластерный ПК на один составной кластерный индекс (data_header_id, id).

EG

use tempdb 

go
drop table if exists big_datums 
go

create table big_datums
(
  id int identity primary key,
  data_header_id int not null
)

go

declare @pkname sysname = (select name from sys.key_constraints where type = 'PK' and parent_object_id = object_id('big_datums'))

declare @sql nvarchar(max) = concat('alter table big_datums drop constraint [', @pkname,']')
--print (@sql)
exec (@sql)

alter table big_datums
add constraint pk_big_dautms
primary key clustered (data_header_id,id)

Кластерные индексы всегда уникальны под обложками. SQL Server добавит скрытый столбец «uniqifier» в индекс в случае дубликатов. Таким образом, вы получите похожий, но более полезный кластерный индекс, если вы предоставите второй ключевой столбец, который делает его уникальным. И если у вас нет другой причины иметь индекс для id, ваша таблица может использовать одну структуру данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...