![]() |
|
Модераторы: skyboy |
![]()
|
|
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
muzer, не знаю, не знаю... одно дело - так хранить строки, другое дело - ключи... если по ним присоединять вообще ничего не надобно - то на кой их хранить? а если надо будет присоединять - то конструкция REGEXP не настолько быстра, чтоб заменить джойн по равенству...
Добавлено @ 08:38 muzer, слушай, опиши структуру, при которой поребуется уйти от атомарности |
|||
|
||||
| -=Ustas=- |
|
|||
![]() Ustix IT Group ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2222 Регистрация: 21.1.2005 Где: Краснодар Репутация: 4 Всего: 69 |
Да уже читаю skyboy, спасибо за ссылку на статью. Погрузился в чтение )) -------------------- В искаженном мире все догмы одинаково произвольны, включая догму о произвольности догм. ----- |
|||
|
||||
| Grasshopper |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 31 Регистрация: 23.3.2006 Репутация: нет Всего: 1 |
при связи много-ко-многим создается отдельная таблица с двумя индексными полями - ключ от одной таблицы и ключ от другой. Другие решения представляются ГОРАЗДО более затратными по скорости |
|||
|
||||
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
||||
|
||||
| muzer |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 387 Регистрация: 31.8.2006 Репутация: 30 Всего: 31 |
Grasshopper, при связи многие ко многим не всегда обязательно иметь возможность выбирать эти данные одним запросом и именно в базе. Но нужно иметь возможность быстро редктировать один из наборов.
skyboy, приведу пример похожий на реальный, но применив другую тематику, а то получится разглашение представь, есть огромная база голосований: вопрос и несколько вариантов ответов. с одной стороны есть интерфейс их редактирования, с другой стороны есть движок, который на входе имеет некое условие, по которому отбирает вопрос, на выходе должен вернуть вопрос и все его ответы. Делать селект из двух джойнов на каждый запрос - нет смысла, не живёт, нагрузка например неск сот запросов в секунду, вопросов 5 миллионов за всю историю, ответов соответсвенно раз в 10 больше (если в одной таблице хранить индексы, то это будет 5 млн х 50 млн = 500 млн...это не для MySQL'я). Понятно что ответы повторяются, их например 2 млн. Т.е. если загружать всё это по отдельности в память движка, в хэши и т.п., то решаются все поставленные задачи - мы можем быстро отвечать на запрос, мы можем быстро редактировать список ответов. Выбрать всё и сразу - такой задачи не стоит. |
|||
|
||||
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
не понял. если под "каждым запросом" имелся в виду отдельный вопрос, то мы же с самом начала выберем только один конкретный вопрос и "всего" не будет. если под "каждым запросом" имелся в виду набор вопросов("анкета"), то внеся в базу структуру этой "анкеты" из логики работы обрабатывающей программы, мы получим возможность выбирать только то, что нам надо,опять же - без декартового произведения. может, я неверно понял, тогда растолкуй, если не сложно. а может - после "неразглашения" и "смены тематики" пример утратил адекватность? |
|||
|
||||
| muzer |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 387 Регистрация: 31.8.2006 Репутация: 30 Всего: 31 |
может и утратил, но попробую..
Давай будем по этапам. Какая структура по нормализации должна быть? Три таблицы, правильно? T1. QuestionID | bla bla bla T2. AnswerID | bla bla bla T3. QuestionID | AnswerID Сколько строк будет в таблице T3, если мы рассматриваем приведённый пример? 500 млн.. Выбрать нужно по какому-то bla-bla вопрос, и все его ответы. Т.е. SELECT .. FROM T1 INNER JOIN T3 USING(QuestionID) INNER JOIN T2 USING(AnswerID) WHERE T1.bla... |
|||
|
||||
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
а. теперь понял, что тебя смущает. только, во-первых, если речь о максимальном объеме таблицы, то можно разбить третью таблицу на несколько таблиц. Забыл, как этот процесс называется
Да, там можно ещё один столбец в третью таблицу, указывающий на порядок ответа в списке. Или на "вес" ответа. Или на признак "верности"(впрочем, нет - лучше это в четвертую таблицу). а если загонишь в одну строку типа "1, 2, 5, 29", то попробуй потом посчитай без REGEXP, какой ответ используется наиболее часто... Да, согласен с мыслью, что в зависимости от задачи может быть и рационально отступать от НФ, но, как на меня, пример не подтверждает это утверждение Добавлено @ 00:14 "репликация", что ли... черт, не буду больше пить пиво |
|||
|
||||
| muzer |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 387 Регистрация: 31.8.2006 Репутация: 30 Всего: 31 |
А вот тут неточность Сколько занимает времени подобная выборка вопрос не самый важный, самый важный вопрос - насколько быстрее будет работать схема не по НФ. Ответ - в десятки раз быстрее. А это значит, что требуется для работы ставить в десятки раз меньше серверов или сервера могут быть менее мощные. Разбить таблицу на несколько можно, но это уже кластеризация, причём даже в текущем примере по непонятному признаку, а следовательно усложнение системы в разы. (репликация - это некая схема объединения баз данных, когда, например, одна база зависит от другой (односторонняя репликация)) |
|||
|
||||
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
не знаю, не зна... там - работа со строками, при НФ - работа с индексами по числам. Протестировать не получилось: только НФ-ый вариант. Выбор 3 строк из 236000 заняло горздо меньше секунды |
|||
|
||||
| muzer |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 387 Регистрация: 31.8.2006 Репутация: 30 Всего: 31 |
Где работа со строками? В коде на cи? Сделать SELECT *, распарсить, сложить в нужные структурки и готово.
Из 236 тысяч меньше секунды, ессно. А из 500 млн? даже из 100 млн.. И не забывай, что в несколько потоков. |
|||
|
||||
| skyboy |
|
||||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
muzer, в смысле? склепай запрос, который при ненормализованном хранении соответсвий ответов и вопросов вытягивает список ответов для заданного вопроса. НЕ парсить строку "1, 2, 10, 30" на стороне клиента и динамическое формирование соотвествующимх запросов к таблице, а plain-SQL.
Добавлено @ 21:52 пущай таблица вопросов: questions idquestion(int autoinc) title(varchar) answers(varchar) - номера ответов через разделитель answers idanswer title ________________ нормализованная форма: questions idquestion(int autoinc) title(varchar) answers idanswer title questions_answers idquestion idanswer ________________ Для нормализованной формы:
Для ненормализованной ситуации(на REGEXP'ах):
Можно и без REGEXP'a, но лениво ______________ Как думаешь, что быстрее будет? |
||||
|
|||||
| Ignat |
|
|||
![]() Флудератор ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4030 Регистрация: 19.4.2004 Где: غيليندزيك مدينة Репутация: 21 Всего: 73 |
Притянуто за уши, но для примера. Имеются две таблицы: В одной какие-либо события, допустим котировки акции, скажем пару миллионов записей. Во второй какое-то конечное число других сущностей, к примеру, наименования бирж, на который торгуются акции, число ограничено десятком. Нам нужно выбрать строки с событиями, а также связать с таблицей бирж. Первый вариант (таблицы находятся в нф): вводим таблицу для связей, при этом количество строк грубо = (количество котировок*AVG(количество бирж для каждой акции)), связываем по ключам min 2 джойна при выборке 2-х миллионов строк(!). Вариант кошерный, но не оправданный. Вариант второй: список бирж через разделитель сохраняем в каждой строке Выбираем все записи из таблицы бирж, храним в памяти. Выбираем котировки без джойнов. При анализе, в случае необходимости парсим строку и связываем с наименованиями, которые уже(!) находятся в памяти. skyboy, как думаешь, какой вариант быстрее? Хоть это натянутый пример, но такое встречается чаще, чем хотелось бы. -------------------- Теперь при чем :P |
|||
|
||||
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
Ignat, принято, хоть и притянуто. Только если "отталкиваться" от котировок. А если от бирж - посмотрим, что будет быстрее. И ещё вопрос: как ты, к примеру, отбросишь все котировки, которые не котируются на определенной бирже? или наоборот - котриуются? вообще, почти любое условие по отбору, которое в случае НФ уменьшало бы количество строк в разы, при не-НФ форме превратится в мегатонны головной боли
Добавлено @ 11:29 Ignat, ха! ты из тонкого клиента одним движением сделал толстого! попробуй вернуться к тонкому клиенту и написать запрос типа моего(только у меня - REGEXP$ не лучшее решение), и посмотрим, кто - кого. Ведь маловероятно, чтоб набор котировок был конечным этапом - потом будет группировка вычисление кучи статистичесих параметров... |
|||
|
||||
| muzer |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 387 Регистрация: 31.8.2006 Репутация: 30 Всего: 31 |
skyboy, вот Игнат очень точно описал то, что пытался я
И как показывает практика, статистики намного меньше, чем множество всех возможных вариантов. Т.е. статистику имеет смысл хранить отдельно. В случае примера с голосованием, будет большое кол-во вопросов, на которые никогда не отвечали, будет большое кол-во ответов в некоторых вопросах, которые никогда не выбирали. Для них не имеет смысл хранить нули, лучше просто не хранить ничего. |
|||
|
||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | MySQL | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |