Mysql одна большая база данных или маленькая много таблиц - PullRequest
3 голосов
/ 07 апреля 2011

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

Мы рассматриваем два подхода

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

b) Создание / Разработка таблицы для каждой формы, которую создает пользователь, которая соответствует ее дизайну, здесь нам не нужно поворачиваться, и мы получаем все преимущества mysql, а также у нас не будет объединений для более чем пары таблиц

Нашей главной заботой является масштабируемость, в сценарии «а», если таблица будет действительно огромной (что, очевидно, произойдет, если я рассмотрю регистрацию даже 1000 пользователей), с планом «b», если завтра наши таблицы будут расти вместе с нашим трафиком, который у нас может быть использовать MySQL кластер, но кластер имеет ограничения таблицы, как я прочитал здесь http://dev.mysql.com/doc/refman/5.0/en/mysql-cluster-limitations-database-objects.html

Обновление

Новая идея поразила нас, почему бы не создать единую таблицу (как ключ, значение), которая соответствует одному элементу формы (текстовое поле, текстовая область и т. Д.), Используя соединение (Нет объединений = Нет полей) на основе формы определение, созданное пользователем, мы можем создать горизонтальные данные, не сводя на нет то, что вы все думаете об этой идее.

Обновление от 9 апреля 2011 года

Мы протестировали поворот против соединений

Сценарий - у нас есть форма с 7 полями, данные сохраняются как (пример данных для вставки одной формы)

------------------------------
|   Key       |    Value     |
------------------------------
|   Key1      |    Value1    |
|   Key2      |    Value2    |
|   Key3      |    Value3    |
|   Key4      |    Value4    |
|   Key5      |    Value5    |
|   Key6      |    Value6    |
|   Key7      |    Value7    |
------------------------------

Для сводного запроса потребовалось 0,92 секунды, чтобы развернуть 70000 строк в 10000 вставок формы Для соединения потребовалось 17,63 секунды (woof .....), чтобы показать эти 10000 форм вставок

Мой стол

CREATE TABLE IF NOT EXISTS `vet` (
  `id` int(11) NOT NULL,
  `form_id` int(11) NOT NULL,
  `key` varchar(255) NOT NULL,
  `value` varchar(255) NOT NULL,
  KEY `id` (`id`),
  KEY `form_id` (`form_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

Сводный запрос

SELECT id, 
       GROUP_CONCAT(if(`key` = 'k1', value, NULL)) as 'key1',
       GROUP_CONCAT(if(`key` = 'k2', value, NULL)) as 'key2',
       GROUP_CONCAT(if(`key` = 'k3', value, NULL)) as 'key3',
       GROUP_CONCAT(if(`key` = 'k4', value, NULL)) as 'key4',
       GROUP_CONCAT(if(`key` = 'k5', value, NULL)) as 'key5',
       GROUP_CONCAT(if(`key` = 'k6', value, NULL)) as 'key6',
       GROUP_CONCAT(if(`key` = 'k7', value, NULL)) as 'key7'
FROM vet
WHERE form_id = 2
GROUP BY id

JOIN Query

SELECT v.id, v1.value as key1, v2.value as key2, v3.value as key3, 
       v4.value as key4, v5.value as key5, v6.value as key6, v7.value as key7
FROM vet v
LEFT JOIN vet v1 ON v1.id = v.id AND v1.`key` = "k1"
LEFT JOIN vet v2 ON v2.id = v.id AND v2.`key` = "k2"
LEFT JOIN vet v3 ON v3.id = v.id AND v3.`key` = "k3"
LEFT JOIN vet v4 ON v4.id = v.id AND v4.`key` = "k4"
LEFT JOIN vet v5 ON v5.id = v.id AND v5.`key` = "k5"
LEFT JOIN vet v6 ON v6.id = v.id AND v6.`key` = "k6"
LEFT JOIN vet v7 ON v7.id = v.id AND v7.`key` = "k7"
WHERE v.form_id = 2
GROUP BY v.id

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

Пожалуйста, предложите, какое решение лучше или есть другое лучшее решение

Sudesh

Ответы [ 3 ]

1 голос
/ 08 апреля 2011

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

Сначала таблица с данными пользователя:

Table user<br> id: integer autoincrement primary key<br> username: varchar(255)<br> other user data <p>Then a table that links the user to the form data (but does not actually hold any form data </p> <p><code> Table UserForm<br> id: integer autoincrement primary key<br> user_id: integer index<br> ... other fields for fixed data that always occurs only once in each form.

Затем таблица с данными формы
Table FormProperties<br> id: integer autoincrement primary key<br> UserForm_id: integer index<br> PropertyName: varchar(255)<br> PropertyValue: varchar(255)

Теперь, когда выхотите получить доступ к данным из формы, к которой вы используете запрос, например

select * from FormProperties
inner join UserForm on (FormProperties.UserForm_id = UserForm.id)
inner join User on (UserForm.User_id = user.id) 
where UserForm.id = 103
</code>

Таким образом, вы не будете хранить избыточные данные.Обратите внимание, что если вам никогда не требуется уникальный доступ к отдельному свойству, вы можете удалить уникальный идентификатор из таблицы свойств.

И не беспокойтесь о кластере MySQL, просто начните с vanilla MySQL (5.x) с MySAMтаблицы, и если это не достаточно быстро, то вы можете начать думать о хитрости, но я не буду беспокоиться о записи менее миллиона.

1 голос
/ 07 апреля 2011

Я предлагаю проектировать его, используя одну базу данных.Тогда вы всегда можете использовать шардинг для горизонтального масштабирования, когда это необходимо.

0 голосов
/ 27 ноября 2013

Проблемы с наличием множества небольших баз данных хорошо понятны: - неэффективное использование диска и памяти, когда индексы и таблицы малы Сервер MySQL плохо масштабируется, когда #databases> 100 и #tables> 10000 - админ / управление кошмаром Но некоторые преимущества: - изоляция клиента обеспечивает лучшую безопасность - сбросить / загрузить / заблокировать / изменить таблицы отдельных клиентов, не влияя на других - проще управлять несколькими версиями и добавлениями пользовательских схем

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

Полное раскрытие: я работаю в ParElastic. Но я искренне верю, что у нас есть единственное действительно полное решение этой проблемы с нашей виртуальной мультитенантной базой данных: - каждый клиент видит полный изолированный экземпляр своей базы данных - независимые команды администратора для своей базы данных - масштабируемый шардинг под прикрытием для распределения данных между пользователем и внутри пользователя - управление схемами для каждого клиента поддерживает непрерывные обновления и пользовательские расширения - безопасные межклиентские запросы с использованием обычного SQL

Если вам интересно, вы можете бесплатно загрузить предварительно упакованную среду ParElastic в https://aws.amazon.com/marketplace (поиск "parelastic"). Или проверить http://parelastic.com.

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