MySQL «ручная» разметка - PullRequest
1 голос
/ 27 марта 2020

Я недавно унаследовал унаследованное приложение, включающее базу данных MySQL, центральным элементом которой является «таблица», которую мы назовем Foo - только это не фактическая таблица, а несколько идентичных таблиц с именем Foo01, Foo02 ... до Foo31. Записи вставляются в FooNN, когда днем ​​месяца для этой записи является NN, этот «логический раздел c» управляется на прикладном уровне.

В целом, Foo растет с постоянной скоростью ~ 100 тыс. Строк в день. Общее количество (~ 3M) и данные строк указывают на то, что каждая запись удаляется / сохраняется в истории примерно через месяц, поэтому размер не является большой проблемой. Вставка происходит с примерно постоянной скоростью с течением времени, обновления отсутствуют. Запросы на Foo происходят только из-за того, что пользователи (не так много) проводят ручной поиск, который может фильтроваться или не фильтроваться по дате «разбиения», а также может иметь или не иметь другие параметры поиска.

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

Имеет ли этот подход какой-либо смысл вообще? то есть будет ли у него какое-либо преимущество перед встроенным разделением MySQL (с учетом очевидных недостатков)?

Ответы [ 2 ]

2 голосов
/ 27 марта 2020

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

  • Запросы, требующие более одной таблицы, сложны для записи
  • . Обеспечение целостности данных hard (нет первичного ключа в таблицах)
  • поддержание структуры проблематично c (любая операция DDL должна повторяться для всех таблиц)

Если ваши данные не слишком велики, вы можете сохранить их непосредственно в одной таблице.

Если в нем много строк, вы можете использовать MySQL с собственным разделением.

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

0 голосов
/ 28 марта 2020

Я приведу несколько предварительных доводов "за":

Если предположить, что это будет PARTITION BY RANGE(TO_DAYS(...)), что является единственным полезным шаблоном,

  • Упрощенные запросы для написания пользователем. Дата и диапазон дат очень похожи и охватывают только одну таблицу (с точки зрения пользователя).
  • При переходе к / из разбиения индексы обычно необходимо изменить. При этом вы либо сохраняете, либо повышаете производительность.
  • Удаление «старых» данных происходит намного быстрее и менее инвазивно (чем отдельная таблица), поскольку это DROP PARTITION. (Хорошо, foo ## также быстр и неинвазивен.)

С другой точки зрения, существует старая поговорка: «Если ничего не сломано, не исправляйте его» .

Мои комментарии по разбиению: http://mysql.rjweb.org/doc.php/partitionmaint

...