Составной индекс MySQL с уникальным подмножеством - PullRequest
3 голосов
/ 11 июля 2019

У меня есть следующая таблица ссылок один к одному

CREATE TABLE `foo_bar` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `foo_id` int(10) unsigned NOT NULL,
  `bar_id` int(10) unsigned NOT NULL,
  …
  PRIMARY KEY (`id`),
  …
) ENGINE=InnoDB 

Где foo_id и bar_id - внешние ключи к таблицам foo и bar соответственно

Естьтакже

  • Уникальный индекс на (foo_id, bar_id), который используется для сопоставления внешнего ключа foo_id для записей foo и производительности запросов, и…
  • Уникальный индекс на bar_id, который используется для сопоставления внешнего ключа с bar_id на записи баров

Примечание , что эта настройка допускает неуникальные foo_id sдо тех пор, пока они сопровождаются уникальным bar_id


Теперь я хотел бы обеспечить уникальность только для foo_id, сохраняя при этом преимущества производительности существующего составного индекса для (foo_id, bar_id)

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

В этом примере это будет выглядеть как ([foo_id], bar_id) где tКвадратные скобки указывают уникальную часть составного индекса

Я хотел бы избежать накладных расходов на отдельный индекс на (foo_id, bar_id)

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

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

В основном foo_bar.id хранится вфайл cookie клиента (после обратимого шифрования), и любые личные данные доступны с этого идентификатора.Идея состоит в том, что, если клиент запрашивает удаление, мы удаляем запись foo_bar и удаляем их данные, не уничтожая анонимные или функциональные данные в foo и bar

Это имеет дополнительный бонус, который дажеесли файл cookie сохраняется где-либо, он больше не будет разрешен до любых данных

1 Ответ

1 голос
/ 12 июля 2019

Это таблица сопоставления много-много?

Тогда избавьтесь, если id;это беспорядок и замедляет ход событий.

PRIMARY KEY(foo_id, bar_id),
INDEX(bar_id, foo_id)

Эти и другие советы: http://mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table

Это имеет дополнительный бонус, который, даже если cookie сохраняется где-либо, будетбольше не может быть разрешен для любых данных

Это подразумевает выполнение одного из следующих действий:

  • Повесьте все созданные хэши, но отметьте некоторые как «удаленные».
  • В противном случае убедитесь, что вы никогда не сгенерируете один и тот же хэш дважды.

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

Это в некоторой степени подразумевает существование ключа UNIQUE (или PRIMARY) где-то для foo_id и отдельно bar_id.

Если эти два ограничения уникальности находятся в одной таблице и вам требуетсяотделяйте id по другим причинам, тогда минимальное индексирование составляет:

PRIMARY KEY(id),
UNIQUE(foo_id),
UNIQUE(bar_id)

или

PRIMARY KEY(foo_id),
UNIQUE(bar_id),
INDEX(id)   -- This is sufficient to keep `AUTO_INCREMENT` happy.

Нет необходимости иметь какой-либо индекс (обычный или UNIQUE) для (foo_id, bar_id), поскольку ограничение единственности первого достаточно как для уникальности пары, так и дляr эффективный поиск.

foo_bar.id зашифрован и сохраняется в файле cookie клиента ... клиент запрашивает удаление, мы удаляем запись foo_bar

Какой тип шифрования?В одну сторону (md5, shar256 и т. Д.)?Или обратимый (aes ...)?Если он односторонний, вам нужен индекс где-то, который отображает CONCAT(foo_id, bar_id) (или что вы делаете) на foobar_id.

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