Хранение нескольких значений в одной ячейке в MySQL - PullRequest
0 голосов
/ 27 января 2010

Я храню несколько чисел в ячейке MySQL, используя разделитель (например, «1,5,10») и тип данных TEXT.

Как мне выполнить такой поиск?

SELECT * FROM MyTable WHERE MultiVals CONTAINS "5"

И, наконец, это предпочтительный подход для хранения таких значений? Я использую это как таблицу компоновщика, чтобы связать определенные строки с несколькими другими строками в другой таблице (через идентификаторы). Поскольку я пытаюсь минимизировать размер файла БД, я подумал, что это будет более компактный подход к компоновке вместо использования другой таблицы, подобной этой:

Person ID       Product ID
-----------     -----------
3               1
3               2
3               3
7               5
7               7

Ответы [ 4 ]

3 голосов
/ 27 января 2010

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

Project ID       Tag ID
-----------     -----------
3               1
3               2
3               3
7               5
7               7

Используя их, два внешних ключа также действуют как индекс. Таким образом, это значительно ускорит поиск по сравнению с FIND_IN_SET методом. Вы минимизируете размер файла, так как тип данных TEXT содержит пустые места для неиспользуемых битов, а числовое хранилище является лучшим и использует минимальное локальное хранилище.

В любом случае, если вы хотите сохранить свой первоначальный путь, вы идете так:

SELECT * FROM MyTable WHERE FIND_IN_SET(5,MultiVals) >0

это обеспечит совпадение значений с помощью запятых, поэтому значение 5 будет соответствовать «5», а не «15»

2 голосов
/ 27 января 2010

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

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

MySql, как и любая другая реляционная база данных, работает намного быстрее при поиске по int и т. П., Чем поиск по строкам. Не говоря уже о том, что строковые индексы требуют больше ресурсов для их обслуживания.

Все сказали, что если вы не планируете делать какие-либо серьезные действия (по крайней мере, миллион записей в MyTable или более 50 значений в одном поле MultiVal), вы можете продолжать делать то, что делали сейчас. - вы не увидите никакого прироста производительности.

1 голос
/ 27 января 2010

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

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

select * from mytable where concat(',', multivals, ',') like '%,5,%' 

, что, скорее всего, снизит производительность для чего-либо, кроме тривиальных объемов данных, или напишет функцию, которая разбивает строку (на основе вашего разделителя ",") и проверяет полученный массив, или использует полнотекстовое индексирование.

EDIT : оператор find_in_set гораздо более элегантен, чем использование like, хотя я понятия не имею, как он реализован под прикрытием.

0 голосов
/ 27 января 2010

это плохая идея, как говорили другие посты, но вы все равно можете выполнить ее с помощью простого регулярного выражения

.. where field RLIKE '(^|,)5($|,)'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...