Я столкнулся с проблемой при разработке схемы таблицы для нашей системы.
Вот ситуация:
наша система имеет много элементов (более 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, каждая запись имеет уникальный идентификатор, этот идентификатор является уникальным среди различных элементов, но этот идентификатор является строкой, а не числом
Я хочу получить доступ к записям следующим образом:
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
И причины, по которым я считаю оригинальный дизайн нехорошим:
Я не могу выбрать атрибут или идентификатор записи в качестве первичного ключа, потому что он бесполезен, в каждом запросе я должен назначить идентификатор элемента и некоторые атрибуты в качестве условия запроса (например, «где» item_id = 1 и attribute_1 = 'value1' и attribte_2 между 2 и 3), поэтому я могу использовать в качестве первичного ключа только число int auto_increment int. В результате каждый запрос должен сканировать два b-дерева, и он выглядит как то сканирование вторичного индекса не эффективно.
Также составные ключи кажутся бесполезными, потому что условие запроса может варьироваться среди многих атрибутов.
При исходном дизайне кажется, что я добавил много индексов для удовлетворения различных запросов, в противном случае мне приходится иметь дело с проблемой полного сканирования таблицы, но очевидно, что слишком много индексов не годится для операции обновления, удаления, вставки.