Удобный для поиска способ хранения значений флажков в MySQL? - PullRequest
1 голос
/ 30 августа 2009

Что такое удобный для поиска способ хранения значений флажков в базе данных?

В настоящее время флажки обрабатываются как массив, а значения разделяются знаком ";"

Как таковой:

<input type="checkbox" name="frequency[]" value="Daily"/> Daily
<input type="checkbox" name="frequency[]" value="Weekly"/> Weekly
<input type="checkbox" name="frequency[]" value="Monthly"/> Monthly

Бэкэнд PHP запускает implode (';', $quency) и добавляет строку в базу данных.

Это отлично работает, но это кошмар, когда дело касается поиска.

Есть ли лучший способ приблизиться к этому?

Ответы [ 7 ]

5 голосов
/ 30 августа 2009

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

Многозначные атрибуты должны хранить значения в нескольких строках:

CREATE TABLE Frequency (
  form_id INT NOT NULL,
  frequency VARCHAR(7) NOT NULL,
  PRIMARY KEY (form_id, frequency),
  FOREIGN KEY (form_id) REFERENCES FormSubmissions(form_id),
  FOREIGN KEY (frequency) REFERENCES FrequencyValues(frequency)
);
1 голос
/ 31 августа 2009

Это отлично работает, но это кошмар, когда дело доходит до поиска.

У других людей здесь есть хорошие ответы, но я бы хотел предложить вам немного по-другому взглянуть на проблему. Как это "работает нормально", если вы не можете найти его? Это все равно, что сказать «запись в / dev / null - это здорово, но чтение - это проблема».

Я предлагаю вам сначала подумать о том, как вы собираетесь использовать информацию (т.е. как это важно для бизнеса), затем подумать о том, какую информацию собирать у пользователя, а затем подумать о том, как ее хранить, чтобы она могла служить. цель. Соблазнительно перейти прямо к шагу 3, потому что в большинстве случаев это «очевидно», но когда вы столкнетесь с не столь очевидной ситуацией, вернитесь к началу, и решение будет ясным.

Желательно придумать хотя бы пару способов использования этой информации. Это помогает избежать чрезмерно специфических представлений данных. Также избегайте чрезмерного усердия «давайте соберем эту информацию, чтобы быть в безопасности». Это приводит к большому количеству дополнительной информации без четкой связи с бизнесом, что приводит к недоразумениям относительно ее значения. Когда пришло время запрашивать информацию, у вас будет беспорядок.

1 голос
/ 30 августа 2009

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

Например:

<input type="checkbox" name="frequency[]" value="2"/> Daily
<input type="checkbox" name="frequency[]" value="4"/> Weekly
<input type="checkbox" name="frequency[]" value="8"/> Monthly
  • Если в вашей базе данных хранится 12, вы знаете, что это еженедельно и ежемесячно
  • Если в вашей базе данных хранится 4, вы знаете, что это еженедельно
  • Если в вашей базе данных хранится 10, вы знаете, что это ежедневно и ежемесячно
  • и т. Д.

Этот метод может использоваться для упаковки нескольких данных в одну сумму. Было бы полезно сэкономить место и повысить производительность (работа с целыми числами вместо строк). С другой стороны, это связано с дополнительными затратами на разработку.

Другим быстрым и не масштабируемым способом было бы просто иметь три отдельных битовых / логических столбца (1 или 0), но учтите, что это не будет хорошо масштабироваться, если вы собираетесь добавить новые опции.

0 голосов
/ 21 декабря 2010

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

0 голосов
/ 13 июня 2010

Предполагая, что вы используете 5 лучших ответов на этот вопрос, как бы вы тогда начали искать заказы с частотой ежемесячно И еженедельно? Единственный способ, которым я могу думать в данный момент, - это объединить одну и ту же таблицу для каждого значения AND.

Каким будет правильный способ получать все заказы с периодичностью еженедельно И ежемесячно?

0 голосов
/ 30 августа 2009

Вы можете установить значения типа в базе данных следующим образом:

insert into myTable set frequency = 'weekly';
insert into myTable set frequency = 'daily,monthly';

выбрать все строки, которые имеют "ежемесячно"

select * from myTable where frequency like '%monthly%'

Будьте осторожны, используя поля типа набора, вы не полностью нормализуете свою базу данных. Это не должно быть проблемой само по себе (взгляните на таблицы, которые MySQL использует сам ... они используются повсеместно). Тем не менее, убедитесь, что вы знаете, что делаете.

Как указано в документации MySQL :

Тип данных MySQL SET не является идеальное решение для всех MySQL базы данных, но может быть довольно мощным когда уместно. Если вам нужно отслеживать менее 64 атрибутов для данного сущность и сделать сравнение между разные сущности, MySQL SET Тип данных может быть идеально подходит для ваших нужд.

0 голосов
/ 30 августа 2009

У вас есть два варианта,

  1. Используйте вторую таблицу для хранения частот. Что-то вроде:

    CREATE TABLE `frequencies` (
        `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
        `order_id` INT NOT NULL ,
        `frequency` ENUM( 'Daily', 'Weekly', 'Monthly' ) NOT NULL
    )
    
  2. Создайте одно поле для каждой частоты. Я бы не рекомендовал такой подход.

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