Оптимальная структура базы данных - PullRequest
0 голосов
/ 21 января 2020

Я любитель данных и создал список возможных комбинаций предметов для широко известной мобильной игры. Есть 21 000 000 комбинаций (бесполезные комбинации, отфильтрованные по логике).

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

Моя база данных предметов сейчас выглядит так:

CREATE TABLE `items` (
 `ID` int(8) unsigned NOT NULL,
 `Item1` int(2) unsigned NOT NULL,
 `Item2` int(2) unsigned NOT NULL,
 `Item3` int(2) unsigned NOT NULL,
 `Item4` int(2) unsigned NOT NULL,
 `Item5` int(2) unsigned NOT NULL,
 `Item6` int(2) unsigned NOT NULL,
 `Item7` int(2) unsigned NOT NULL,
 `Item8` int(2) unsigned NOT NULL,
 PRIMARY KEY (`ID`)
) ENGINE=InnoDB

Диапазон идентификаторов: 1 - 21.000.000

Каждый предмет известен по его номеру, например, 11. Первый номер описывает категорию, а второй номер - элемент этой категории. Например, 34 означает Item3 -> 4. Он сохранен следующим образом, так как у меня также есть изображения, которые будут отображаться на веб-сайте позже, с использованием этого номера в качестве идентификатора (34.png).

База данных Stats выглядит сейчас так :

CREATE TABLE stats (
 Stat1 FLOAT UNSIGNED NOT NULL,
 Stat2 FLOAT UNSIGNED NOT NULL,
 Stat3 FLOAT UNSIGNED NOT NULL,
 Stat4 FLOAT UNSIGNED NOT NULL,
 Stat5 FLOAT UNSIGNED NOT NULL,
 Stat6 FLOAT UNSIGNED NOT NULL,
 Stat7 FLOAT UNSIGNED NOT NULL,
 Stat8 FLOAT UNSIGNED NOT NULL,
 ID1 INT UNSIGNED,
 ID2 INT UNSIGNED,
 ID3 INT UNSIGNED,
 ID4 INT UNSIGNED,
 ID5 INT UNSIGNED,
 ID6 INT UNSIGNED,
 ID7 INT UNSIGNED,
 ID8 INT UNSIGNED
) ENGINE = InnoDB;

Где Stat * обозначает такие вещи, как атака, защита, здоровье и т. Д. c. и ID * для идентификатора базы данных предметов. Некоторые комбинации имеют одинаковые комбинации характеристик по всем 8 возможным характеристикам, поэтому я сгруппировал их, чтобы сохранить некоторые записи (не знаю, если это было еще разумно). Например, одна комбинация Stat может иметь заполненные ID1, ID2 и ID3, а другая комбинация просто имеет ID1 (максимум - 8 идентификаторов, хотя я ее вычислил).

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

В будущем я хочу позволить пользователю искать элементы или исключать определенные элементы из списка. Я знаю, что могу сделать это с некоторыми предложениями join и where (где items.ID == stats.ID1 OR items.ID == stats.ID2 et c.), Но мне интересно, является ли моя текущая структура самым умным решением за это? Я пытаюсь добиться максимальной производительности, так как я запускаю это на моем старом Pi 2.

1 Ответ

1 голос
/ 21 января 2020

Если у вас очень большие наборы данных, у которых есть только небольшое количество совпадений, часто лучше всего использовать подзапрос в предложении FROM или WHERE.

SELECT SP.TerritoryID,
       SP.BusinessEntityID,
       SP.Bonus,
       TerritorySummary.AverageBonus
FROM   (SELECT   TerritoryID,
                 AVG(Bonus) AS AverageBonus
        FROM     Sales.SalesPerson
        GROUP BY TerritoryID) AS TerritorySummary
       INNER JOIN
       Sales.SalesPerson AS SP
       ON SP.TerritoryID = TerritorySummary.TerritoryID

Скопировано отсюда

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

Вы также можете обнаружить, что использование подзапроса в предложении WHERE работает

... where items.id in (select id1 from stats union select id2 from stats)

Или выберите соответствующий stats IDs в таблицу tmp, а затем индексируйте таблицу tmp.

Все зависит в значительной степени от того, чем является ваш другой логик выбора c.

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

...