[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Скорость вывода данных из БД
maximka787
Парни, привет. Посоветуйте, как правильней организовать модель таблицы в БД.

Люди проходят анкетирование. Я рассматриваю 100.000 человек, тк проект сразу просят сделать на вырост. У каждого по 200-250 вопросов.

ВАЖНЫ: скорость выборки из БД и фрагментация таблицы (тк пользователи будут постоянно добавлять/обновлять записи)


ВАРИАНТ 1 (ТЕКУЩИЙ)
CREATE TABLE `tab1` (
`id_user` int(10) unsigned NOT NULL,
`question` int(10) unsigned NOT NULL,
`value` varchar(50) NOT NULL,
KEY `id_user` (`id_user`)
)
ENGINE=MyISAM;
//
поле id_user индекс, не первичный ключ.

ОСОБЕННОСТЬ: реляционная модель, для каждого человека создается 200 строк в таблице.
недостаток 100.000 человек * 200 вопросов = 20.000.000 записей. После обновления/удаления придется постоянно делать OPTIMIZE TABLE. Вес БД будет большой. Скорость поиска нужного id_user при таких объемах снизится.

-------------------------------

ВАРИАНТ 2 (РАССМАТРИВАЕМЫЙ)
CREATE TABLE `tab2` (
`id_user` int(10) unsigned NOT NULL,
`value` varchar(250) NOT NULL,
PRIMARY KEY (`id_user`)
)
ENGINE=MyISAM;
//
тут поле id_user первичный ключ.

ОСОБЕННОСТЬ: данные будут храниться в виде массива собираться и разбираться implode/explode.



Вопрос, какой из методов грамотней?

_____________
..Работает - не трогай!
maximka787
Нашел косяк.

ВАРИАНТ 2 (РАССМАТРИВАЕМЫЙ)
Там наверное поле надо будет сделать другое, не VARCHAR, тк не влезет массив с данными. Какое-то текстовое значит.

_____________
..Работает - не трогай!
vagrand
Первый

_____________
Senior PHP developer: PHP5, MySQL, JavaScript, CakePHP, Yii/Yii2, Zend Framework, Smarty, XML/Xslt, JQuery, Jquery Mobile, Bootstrap, ExtJS, HTML, HTML5, CSS, Linux, SVN, Git, Memcached, Redis, MongoDB, Zend Guard, Ioncube, FFMpeg, PayPal, Webmoney, Qiwi, Facebook API, Vkontakte Api, Google API, Twitter Api, Steam Api.
Junior Android Developer: Android SDK, многопоточность, работа с HTTP запросами, JSON, SQLite, фрагменты.
Valick
maximka787, второй вариант мягко говоря вообще не вариант.

_____________
Стимулятор ~yoomoney - 41001303250491
vagrand
maximka787
Фактически и первый вариант недостаточно верен, поскольку не учитывает несколько вариантов ответа на вопрос.

_____________
Senior PHP developer: PHP5, MySQL, JavaScript, CakePHP, Yii/Yii2, Zend Framework, Smarty, XML/Xslt, JQuery, Jquery Mobile, Bootstrap, ExtJS, HTML, HTML5, CSS, Linux, SVN, Git, Memcached, Redis, MongoDB, Zend Guard, Ioncube, FFMpeg, PayPal, Webmoney, Qiwi, Facebook API, Vkontakte Api, Google API, Twitter Api, Steam Api.
Junior Android Developer: Android SDK, многопоточность, работа с HTTP запросами, JSON, SQLite, фрагменты.
sergeiss
Цитата (maximka787 @ 13.03.2015 - 15:06)
ENGINE=MyISAM;

Вот первая ошибка. Если это серьёзная БД, то тогда INNODB нужно взять. Потому что MyISAM не гарантирует целостность данных при сбоях.

Второе. Однозначно нужны партиции. Например, по хэшу от айди. Штук 100. Тогда в каждой части будет (в среднем) в 100 раз меньше данных, чем ты насчитал. То есть не 20 млн., а всего 200 тыс. Скорость выборки и обновлений будет существенно выше. Можно и больше взять партиций smile.gif Но слишком много тоже не нужно. Например, если ты сделаешь 10 тыс партиций, то это уже будет перебор явный.

В принципе, если у тебя не будет запросов, ищущих данные по конкретным ответам, а только их хранение без обработки, то вариант 2 тоже можно использовать.

В случае "варианта 2" и использования всего 10 партиций, в каждой будет, в максимуме, до 10 тыс. записей. Вообще "копейки", всё будет работать быстро.

И кстати. В случае варианта 2, возможно, лучше будет хранить данные в формате JSON. Эти данные можно будет собирать-разбирать как на сервере, так и в JS, в зависимости от имеющейся задачи. Но это, опять же, если ты не будешь анализировать сами вопросы-ответы средствами БД.

_____________
* Хэлп по PHP
* Описалово по JavaScript
* Хэлп и СУБД для PostgreSQL

* Обучаю PHP, JS, вёрстке. Интерактивно и качественно. За разумные деньги.

* "накапливаю умение телепатии" (С) и "гуглю за ваш счет" (С)

user posted image
maximka787
vagrand
а чего именно не учитывает?

sergeiss
спасиб, понятно всё. Да, БД ТОЛЬКО для хранения инфы.

Тогда парни такое дело. Я оставляю первый вариант.
CREATE TABLE `tab1` (
`id_user` int(10) unsigned NOT NULL,
`question` int(10) unsigned NOT NULL,
`value` varchar(50) NOT NULL,
KEY `id_user` (`id_user`)
)
ENGINE=InnoDB;


На счет партиций этим займусь чуть позже, сервер не позволяет сделать НА ДАННЫЙ момент такой конфиг.


1.
Правильно ли я делаю индекс на первое поле?

2.
Обновление ответов делается простым способом. Удаляются все данные из таблицы по user_id и добавляются в конец. Тк иногда добавляются новые вопросы и порще сразу все очистить и добавить. При этом происходит фрагментация и возможно куча неприятных моментов. После чего лучше делать OPTIMIZE TABLE Это в норме всё?

_____________
..Работает - не трогай!
Valick
Цитата (maximka787 @ 13.03.2015 - 15:34)
Да, БД ТОЛЬКО для хранения инфы.

самое распространённое заблуждение
___
это примерно вместо того чтобы зачерпнуть землю ковшом эксковатора, вы будете в ковш её бросать савочком, а эксковатор использовать, только чтобы довезти землю из пункта А в пункт В и там снова разгружать савочком

_____________
Стимулятор ~yoomoney - 41001303250491
sergeiss
Цитата (maximka787 @ 13.03.2015 - 16:34)
Да, БД ТОЛЬКО для хранения инфы.

Противоречишь сам себе smile.gif "Только хранение" - это когда один раз записали и ничего не изменяем. У тебя же идет полноценная работа с БД:
Цитата (maximka787 @ 13.03.2015 - 16:34)
Обновление ответов делается простым способом. Удаляются все данные из таблицы по user_id и добавляются в конец.



_____________
* Хэлп по PHP
* Описалово по JavaScript
* Хэлп и СУБД для PostgreSQL

* Обучаю PHP, JS, вёрстке. Интерактивно и качественно. За разумные деньги.

* "накапливаю умение телепатии" (С) и "гуглю за ваш счет" (С)

user posted image
maximka787
Цитата
Противоречишь сам себе

Прошу прощения, действительно. НО! никакой полноценной работы быть не может. Только запись, чтение, удаление и по кругу. Без расчетов, определенной выборки. (только по номеру пользователя) Всю работу делает PHP, да и она не большая, просто объемы вопросов и ответом масштабны.

Ну а на счет моих двух вопросов в предыдущем посте что скажете?

_____________
..Работает - не трогай!
sergeiss
Цитата (maximka787 @ 13.03.2015 - 17:43)
Ну а на счет моих двух вопросов в предыдущем посте что скажете?

Я бы в твоем случае сделал "вариант 2", с хранением вопросов и ответов в формате JSON - это же просто текстовая строка будет.

_____________
* Хэлп по PHP
* Описалово по JavaScript
* Хэлп и СУБД для PostgreSQL

* Обучаю PHP, JS, вёрстке. Интерактивно и качественно. За разумные деньги.

* "накапливаю умение телепатии" (С) и "гуглю за ваш счет" (С)

user posted image
Valick
Цитата (maximka787 @ 13.03.2015 - 16:43)
Всю работу делает PHP, да и она не большая

всё таки предпочитаете савочек эксковатору

Вы вообще зачем на форум пришли, раз сами всё знаете?
Ох... да уж (посмотрел на счётчик) 7 лет на форуме и такой низкий уровень. Вы уж извините, но программирование это не ваше. Попробуйте найти себя в чём-то другом.

_____________
Стимулятор ~yoomoney - 41001303250491
Valick
Цитата (maximka787 @ 13.03.2015 - 16:43)
на счет моих двух вопросов в предыдущем посте

1 там должен быть не просто индекс , а первичный ключ с автоинкрементом
2 нет это не нормально
3 одной таблицы мало их минимум должно быть три

_____________
Стимулятор ~yoomoney - 41001303250491
stump
Цитата (maximka787 @ 13.03.2015 - 15:06)
Вопрос, какой из методов грамотней?

Метод проектирование эффективной БД в этом топике будет вполне уместным. Попробуй сделать еще пару подходов к снаряду.

_____________
Трус не играет в хокей
Guest
Ну кому дано, а кому 7 лет и до сих пор "парни помогите".. smile.gif Вопрос то вроде на пару минут для ЗНАЮЩИХ, ладно я, не кодер в принципе. Я ж не прошу сделать за меня и код прислать. Идею дать, времени много не нужно.

Цитата
1 там должен быть не просто индекс , а первичный ключ с автоинкрементом

Зачем в моей БД вообще ключ с автоинкрементом? Вы наверное не прочитали первый пост совсем. Первичный ключ с автоинкрементом необходим варианту 2 и он там есть. Первому он категорически запрещен.

Цитата
2 нет это не нормально

Согласен, но вариант в UPDATE точно epic fail.

Цитата
3 одной таблицы мало их минимум должно быть три

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


Я всё же склоняюсь к варианту 2, где и автоинкремент и один ключ на человека. Данным в тексте хранятся в JSON. Хотя учитывая команды implode/explode формат хранения можно сделать вообще любой.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.