Я должен хранить большое количество пар данных. Пары данных имеют форму:
параметр = значение
и связаны с контейнером. Это похоже на файл INI. Например, у меня есть контейнер, который имеет следующие значения:
p1 = 32 p2 = "hello world" p3 = -54
и еще один, который имеет:
p1 = 32 p2 = 36 p5 = 42 p6 = "bye"
В контейнере есть неопределенное количество параметров. Значения представляют собой числа или строки любой длины (числа могут быть преобразованы в строки). Поиск данных производится по имени параметра ( «все значения p1» ) или значению (параметр «a» p6 со значением «bye» ). База данных будет содержать миллионы пар. Вставки и прочтения будут сделаны очень часто и будут редко удалять или обновлять запись.
Моя первая попытка заключалась в создании двух таблиц. Первый такой вот так:
CREATE TABLE IF NOT EXISTS `container` ( `id` int(11) NOT NULL AUTO_INCREMENT, OTHER CONTAINER INFO PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;
где id
будет использоваться в другой таблице, содержащей пары:
CREATE TABLE IF NOT EXISTS `data` ( `container` int(11) NOT NULL, `name` varchar(64) COLLATE utf8_unicode_ci NOT NULL, `value` text COLLATE utf8_unicode_ci NOT NULL, KEY `container` (`container`), KEY `name` (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Добавление данных:
INSERT INTO `container` (`id`) VALUES ('1'), ('2'); INSERT INTO `data` (`container`, `name`, `value`) VALUES ('1', 'p1', '32'), ('1', 'p2', 'hello world'), ('1', 'p3', '-54'), ('2', 'p1', '32'), ('2', 'p2', '36'), ('2', 'p5', '42'), ('2', 'p6', 'bye');
Он работает, но он не очень «полезен» и быстро. Например, если мне нужно найти все параметры из каждого контейнера, у которого есть p1=32
я должен сделать два SQL-запроса:
SELECT id FROM `container` WHERE id IN ( SELECT container FROM DATA WHERE name = 'p1' AND value = '32')
а затем для каждого id
контейнера получить все данные:
SELECT * FROM `data` WHERE container = '$id'
а затем выполнить пост-обработку через PHP, потому что он возвращает таблицу следующим образом:
container name value 1 p1 32 1 p2 hello world 1 p3 -54
(пост-обработка – это всего лишь пара вызовов функций array_ *, но это замедляет обработку).
Я тестировал базу данных, содержащую 50000 пар данных и перечисляя все записи, используя эту процедуру, занимает более 5 секунд. Возникает вопрос: как хранить данные такого типа? или как улучшить производительность моей реализации?
ПРИМЕЧАНИЕ . Проблема заключается не в первом запросе SQL (0'003 секунды), а во втором (0'002 секунды каждый). Проблема состоит в том, чтобы сделать SQL-запрос для каждого результата первого предложения SQL !!
ПРИМЕЧАНИЕ 2. Цель состоит в том, чтобы иметь массив PHP, содержащий каждый результат, и для каждого результата ассоциативный массив с парными значениями пар. Результат для print_r
:
Array ( [1] => Array ( [p1] => 32 [p2] => hello world [p3] => -54 ) [2] => Array ( [p1] => 32 [p2] => 36 [p5] => 42 [p6] => bye ) )
И, конечно, структура данных, которую я показал здесь, является моей первой попыткой, я исследую, это не производство, поэтому я могу изменить, не проблема.