MySQL: оптимизация таблицы (индексация, внешний ключ) без первичных ключей - PullRequest
0 голосов
/ 15 ноября 2011

У каждого участника есть 0 или более заказов.Каждый заказ содержит как минимум 1 товар.memberid - varchar, а не integer - это нормально (пожалуйста, не упоминайте, что это не очень хорошо, я не могу это изменить).Итак, thera 3 таблицы: члены, заказы и элементы order_items.Заказы и элементы order_items ниже:

CREATE TABLE `orders` (
`orderid` INT(11)  UNSIGNED NOT NULL AUTO_INCREMENT,
`memberid` VARCHAR( 20 ),
`Time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
`info` VARCHAR( 3200 ) NULL ,
PRIMARY KEY (orderid) ,
FOREIGN KEY (memberid) REFERENCES members(memberid)
) ENGINE = InnoDB;


CREATE TABLE `order_items` (
`orderid` INT(11)  UNSIGNED NOT NULL,
`item_number_in_cart` tinyint(1) NOT NULL , --- 5 items in cart= 5 rows
`price` DECIMAL (6,2) NOT NULL,
FOREIGN KEY (orderid) REFERENCES orders(orderid)
) ENGINE = InnoDB;

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

orderid - item_number_in_cart - цена:

...

1000456 - 1 - 24,99

1000456 - 2 - 39,99

1000456 - 3 - 4,99

1000456 - 4 - 17,97

1000457- 1 - 20,00

1000458 - 1 - 99,99

1000459 - 1 - 2,99

1000459 - 2 - 69,99

1000460 - 1 - 4,99

...

Как видите, таблица order_items не имеет первичных ключей (и я думаю, что нет смысла создавать идентификатор auto_increment для этой таблицы, потому что, как только мы захотимдля извлечения данных мы всегда извлекаем их как WHERE orderid='1000456' order by item_number_in_card asc - весь блок, идентификатор не будет полезен в запросах).После того, как данные вставлены в order_items, они не ОБНОВЛЯЮТСЯ, а просто ВЫБРАНЫ.

Вопросы:

  • Я думаю, что было бы неплохо поместить индекс в item_number_in_cart.Кто-нибудь может подтвердить это?
  • Есть ли что-то еще, что я должен сделать с order_items, чтобы увеличить производительность, или это выглядит довольно хорошо?Я мог что-то пропустить, потому что я новичок.

Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 15 ноября 2011

Ну, в любом случае, у меня будет автоинк, так как я большой сторонник суррогатных ключей, но, как подсказывает alex07 индекс или даже первичный ключ orderid, item_number_in_cart должен разобраться. Обратите внимание, что порядок по номеру item_number будет использовать двухпроходную сортировку (получить данные, а затем отсортировать их в порядке нумерации), поэтому индекс / ключ сразу же их выберут, поэтому вы захотите этот индекс даже с суррогатным ключом.

1 голос
/ 15 ноября 2011

Первичные ключи могут занимать несколько столбцов. Для этого нельзя использовать атрибут PRIMARY столбцов, но вы можете определить отдельный первичный ключ с несколькими столбцами:

CREATE TABLE `order_items` (
    `orderid` INT(11)  UNSIGNED NOT NULL,
    `item_number_in_cart` tinyint(1) NOT NULL , --- 5 items in cart= 5 rows
    `price` DECIMAL (6,2) NOT NULL,
    PRIMARY KEY (orderid, item_number_in_cart),
    FOREIGN KEY (orderid) REFERENCES orders(orderid)
) ENGINE = InnoDB;

Более того, первичный ключ - это просто уникальный ключ, в котором каждый столбец не является нулевым с определенным именем; Вы можете создавать свои собственные уникальные ключи для столбцов, не допускающих значения NULL, чтобы получить те же эффекты.

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

1 голос
/ 15 ноября 2011

Индекс на item_number_in_cart не будет использоваться.Это крошечное целое, недостаточно избирательное и даже не будет учтено движком, когда у вас будет 2 записи.Вы можете добавить его в качестве второго столбца к существующему индексу на orderid (поскольку вы создали ограничение FK на orderid, mysql автоматически добавляет индекс на это поле).
Вы говорите, что данные в order_items никогда не обновляются, но я думаю, что это можно удалить;это сделать без первичного ключа будет проблематично.

...