Схема таблицы при использовании innodb

0

Я столкнулся с проблемой при разработке схемы таблиц для нашей системы.

Вот ситуация:

  • В нашей системе много элементов (более 20 миллионов), каждый элемент имеет уникальный идентификатор, но для каждого элемента может быть много записей. Например, для элемента с идентификатором 1 существует около 5000 записей, и каждая запись имеет более 20 атрибутов. Необходимо идентифицировать его идентификатор и статус одного или нескольких его атрибутов для использования в select, update или delete.

  • Я хочу использовать innodb

Но проблема в том, что при использовании innodb должен быть индекс кластера. Из-за описанной выше ситуации, похоже, нужно было найти индекс кластера, поэтому я могу использовать только auto_increment int в качестве ключа

Текущая конструкция выглядит следующим образом:

create table record (
item_key int(10) unsigned NOT NULL AUTO_INCREMENT,
item_id int(10) unsigned NOT NULL,
attribute_1 char(32) NOT NULL,
attribute_2 int(10) unsigned NOT NULL,
.
.
.
.
.
attribute_20 int(10) unsigned NOT NULL,
PRIMARY KEY (`item_key`),
KEY `iattribute_1` (`item_id`,`attribute_1`),
KEY `iattribute_2` (`item_id`,`attribute_2`)
) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=latin1

инструкция sql:

select * from records 
  where item_id=1 and attribute_1='a1' and attribute_2 between 10 and 1000;

Операторы update и delete похожи.

Я не думаю, что это хороший дизайн, но я не могу думать ни о чем другом; все предложения приветствуются.


Извините, если я не задал вопрос.

  • То, что я хочу получить (выбрать, обновить, удалить, вставить), это записи, а не элементы. Элементы имеют собственные атрибуты, но в приведенных выше описаниях атрибуты, о которых я упоминал, относятся к записям.

  • Каждый элемент может иметь много записей, например, элемент 1 имеет около 5000 записей.

  • Каждая запись имеет 42 атрибута, некоторые из них могут быть NULL, каждая запись имеет уникальный идентификатор, этот идентификатор уникален среди разных элементов, но этот идентификатор является строкой, а не числом

  • Я хочу получить доступ к записям следующим образом:

    а. Я буду получать (или обновлять или удалять) записи, относящиеся к одному конкретному элементу, вовремя или в одном запросе

    В. Я получаю или обновляю значения всех атрибутов или некоторых конкретных атрибутов в запросе

    С. Атрибуты, которые в состоянии запроса могут не совпадать с атрибутами, которые я хочу.

Таким образом, могут быть некоторые операторы SQL, например:

Select attribute_1, attribute_N from record_table_1 where item_id=1 and attribute_K='some value' and attribute_M between 10 and 100

И причины, по которым я думаю, что оригинальный дизайн не очень хорош:

  • Я не могу выбрать атрибут или идентификатор записи в качестве первичного ключа, потому что это бесполезно, в каждом запросе я должен назначить идентификатор элемента и некоторые атрибуты в качестве условия запроса (например, "where" item_id = 1 и attribute_1 = 'value1' и attribte_2 между 2 и 3), поэтому я могу использовать только номер auto_increment int в качестве первичного ключа. Результатом этого является то, что каждый запрос должен сканировать два b-дерева, и он выглядит например, сканирование вторичного индекса неэффективно.

  • Также составные клавиши кажутся бесполезными, поскольку условие запроса может варьироваться между многими атрибутами.

  • С оригинальным дизайном кажется, что я добавляю много индексов для удовлетворения различных запросов, в противном случае мне приходится иметь дело с полной проблемой сканирования таблицы, но очевидно, что слишком много индексов не подходит для обновлять, удалять, вставлять операции.

Теги:
schema
design
innodb

2 ответа

0

Если вам нужен индекс кластера и вы не хотите использовать механизм myisam, похоже, что вы должны использовать две таблицы: одну для уникальных свойств элементов, а другую для каждого экземпляра элемента (с указанным атрибуты).

0

Вы правы, схема неправильная. Наличие атрибута 1..20 в качестве полей в таблице не является способом сделать это, вам нужна отдельная таблица для хранения этой информации. Эта таблица будет иметь item_key из этой записи вместе со своими собственными key и value, и поэтому эта вторая таблица будет иметь индексы, которые позволяют значительно лучше искать.

Что-то вроде следующего:

Изображение 174551

Глядя на диаграмму, очевидно, что что-то не так, потому что таблица record слишком пуста, это выглядит не так, как мне кажется, мне что-то не хватает в исходном вопросе....

Составные клавиши

Я думаю, может быть, вы ищете сложный ключ, а не кластерный индекс, который другой. Вы можете достичь этого путем:

create table record (
item_id int(10) unsigned NOT NULL,
attribute_1 char(32) NOT NULL,
attribute_2 int(10) unsigned NOT NULL,
.
.
.
.
.
attribute_20 int(10) unsigned NOT NULL,
PRIMARY KEY (`item_id`,`attribute_1`,`attribute_2`),
KEY `iattribute_1` (`item_id`,`attribute_1`),
KEY `iattribute_2` (`item_id`,`attribute_2`)
) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=latin1
  • 0
    Быть осторожен. Модель «Значение атрибута сущности» является одним из анти-паттернов, описанных в следующей книге Билла Карвина: slideshare.net/billkarwin/…
  • 0
    Я знаю об ограничениях EAV - и вы правы, что это не очень хороший общий шаблон и может победить многие функции, которые должны быть спроектированы в хорошую схему. Однако я все еще думаю, что у него есть место, где атрибуты не определены заранее. В этом случае я не уверен, потому что ОП является расплывчатым, поэтому я пересмотрю, чтобы лучше объяснить, что я имею в виду.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню