Схема таблицы при использовании innodb - PullRequest
0 голосов
/ 10 октября 2010

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

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

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

  2. Я хочу использовать 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. То, что я хочу получить доступ (выбрать, обновить, удалить, вставить), это записи, а не элементы. Элементы имеют свои собственные атрибуты, но в приведенных выше описаниях атрибуты, которые я упомянул, относятся к записям.

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

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

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

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

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

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

Так что могут быть некоторые операторы 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

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

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

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

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

Ответы [ 2 ]

0 голосов
/ 10 октября 2010

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

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

simple database diagram

Глядя на диаграмму, становится очевидно, что что-то не так, потому что таблица 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 голосов
/ 10 октября 2010

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

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