купить квартиру, сделать хороший ремонт, и сдавать ее подороже,
т.е. дороже, чем квартиру, которую будешь снимать, где будут намного хуже условия.
а с учетом разных неопределенностей, и то больше нужно времени, чтобы выйти на стабильный чистый доход в 10к в мес.
для веб-проектов использую MySQL + Redis — этого вполне хватает в плане масштабируемости и высокой нагрузки
1 доллар всегда = 1 доллару
спасибо за понимание :)
в курсе Microsoft по SQL Server, там так и говорят, что порядок доступа к данным, когда делается подзапрос с IN и когда делается JOIN, — будет одинаковым.в MySQL же долгое время вообще не было подзапросов..
насчет сравнения EXISTS и IN, там, наверное, про другое — что EXISTS найдет одну запись и остановится, сразу вернув true, а для IN он будет получать все записи в подзапросе и потом проверять. Поэтому запросы на проверку существования записей в связанной таблице лучше делать с помощью EXISTS, а не IN .. и тем более не COUNT(..) >0. но это совсем другая история..
т.е. данный запрос
запрос, чтобы получить список статей с заданными авторами (например, у которых рейтинг = 5, либо начинающиеся на букву A%) + условия на сами статьи(например, за 2011 год) + пагинация (по дате публикации).
вы бы делали обычным JOIN и ничего бы не меняли в структуре БД ?
но любой инструмент (СУБД) нужно понимать как он работает и как использовать.
например, как вы будете делать следующий запрос:(например, за 2011 год) + пагинация (по дате публикации).
отчего возникли системы NOSQL ? они что нашли более лучше архитектуру, чем реляционные СУБД? нет конечно, они сделали архитектуру, оптимизированную под конкретные задачи..
полученные отфильтрованные результаты будут достаточно большими
конечно же джойн на стороне сервера БД работает быстрее, чем в коде.
мое решение возникло для задач, когда нужно делать сложный поиск.
например,(например, за 2011 год) + пагинация (по дате публикации).
В этом случае обычный джойн будет тормозить!!!т.е. нужно дальше работать с этим сджойненным набором, чтобы дальше его отсортировать по дате публикации и сделать пагинацию.
а лучше было бы так:— и уже дальше джойнить эти 10 статей с другими связанными таблицами.
Стараются максимально сократить объем данным, с которым работают, на первом этапе.
Конечно, для этого нужно сделать денормализацию.
Также когда нужно делать джойны кучи таблиц (скажем— дублирование записей (например, если к статьям приджойнить теги, когда у одной статьи будет много тегов)
Если ваш слой доступа к БД все это умеет делать — то не проблема.а дальше уже получить все справочные данные для этих статей. И такое решение будет более масштабируемым.
Но в достаточно простом примере, который привел ТС, все эти мои аргументы не имеют смысла.
в этом комменте я привел другие нюансы:суть в другом.
пожалуйста, разберитесь в решении, а потом делайте оценку с конкретными аргументами.человек как-то писал что-то похожее. оно как-то работало. он решил поделиться реализацией. получилось что-то вроде вредных советов
Моя реализация требует вместо одного большого JOIN к 4 таблицам (а может и больше), заменить на 4 отдельных запроса. С одной стороны 4 запроса медленнее, чем 1, но с другой стороны это решение имеет свои плюсы. А в случаях со сложными условиями, решение с одним большим JOIN — просто будет тормозить.
Тогда объясню с самого начала, откуда возникло это решение.
Проблема не в JOIN, а проблема в его использовании и понимании, как движок баз данных будет выполнять запрос.
DB Structure:
articles: id, title, content, .., author_id, category_id, pub_date (дата публикации), rating, etc.(могут быть еще другие вторичные ключи)
authors: id, .. (обычные справочные поля, нужные для отображения информации о статье)categories: id, title, ... (куча справочных полей)
Теги: (связь со статьями many-to-many)
tagarticle: tag_id, article_id
tags: id, title
При выполнении запроса для получения списка статей возникают такие задачки:а некоторые «поля» могут иметь набор значений. Например, список тегов для заданной статьи.
Сразу скажу основную идею, когда избегают JOIN.JOIN лучше не делать, когда используют условия WHERE над столбцами из небазовой таблицы.
1. Условия над столбцами articles:
1a
select ..(* столбцы из articles *), (* столбцы из других таблиц, связанных с базовой 1-к-1 *)и т.д.
ORDER BY pub_date DESCLIMIT ..
В этом случае, не так уж важно, как вы будете выполнять этот запрос.Лучше (быстрее), чтобы это было ОДНИМ запросом, как и показано выше.
1b.Можно вместо этого запроса сделать сначала первый запрос над таблицей articles
select ..(* столбцы из articles *)и т.д.
ORDER BY pub_date DESCLIMIT ..
Получить 10 нужных статей.
Далее идем в другие таблицы и забираем оттуда справочные данные.
Т.е. будет еще по ОДНОМУ запросу в каждую таблицу (authors, categories).
SELECT **WHERE id IN (id авторов из найденных раннее статей, будет не больше 10)
* тут не важно, что номера id в IN будут повторяться. Уверен, что движок БД достаточно грамотный, чтобы не делать лишнюю работу.
SELECT **WHERE id IN (id категорий)
Разница между 1a и 1b — минимальная.т.к. БД как раз и предназначена для подобных манипуляций с данными.
2. Когда нужно еще выбрать теги для найденных статей.В решении b, данные более удобны для дальнейшего использования, т.к. собраны вокруг статьи.
3. Если нужно вывести очень много данных связанных таблиц (категории, авторы, теги и т.д.)
Когда делается JOIN конечный результат будет в таком виде:
article.id | article. title | ...другие столбцы articles | author.name | другие столбцы authors | ... | столбцы из categories| и еще куча столбцов
1 hello world | ... | Jack London | ...2 вторая статья | ... | Jack London | ...
т.е. может дублироваться очень много текстовых данных (один и тот же автор). И эти данные перегоняются из БД в код.Если же вытягивались в этом JOIN еще и теги, то записи статей будут повторяться и дублирование данных будет огромным.
article.id | article. title | ...другие столбцы articles | tag.id | tag.name | и еще куча столбцов
1 hello world | ... | 1 | tag11 hello world | ... | 10 | tag10
2 вторая статья | ... | 1 | tag12 вторая статья | ... | 5 | tag5
В случае 1b такой проблемы нет. Из БД перегоняются только сами данные из самих таблиц.Но может понадобиться сделать чуть больше работы в коде, чтобы собрать это все в единую структуру, удобную для отображения.
3. Условия над столбцами из других связанных таблиц.Например, выбрать все статьи, у которых имя автора начинается на букву A, либо рейтинг автора = 5.
тут разница между решением 1a с JOIN и 1b c IN — огромная!Лучше сделать денормализацию, чтобы все-таки условия были над столбцами из базовых таблицы.
ИДЕЯ!Идея заключается в том, чтобы избегать такие JOIN с условиями над связанными таблицами (т.е. небазовой таблицей).
да не будет такой же ситуации.так и есть, разные связи бывают.ин и джойн не всегда дает одинаковый результат
Поэтому нужно возиться с LEFT JOIN, а если JOIN много в цепочке, то нужно очень аккуратно делать. Иначе может быть так, что если у статьи нет тегов, или у статьи нет категории (* просто для примера*), то эта запись со статьей не попадет в итогой набор.
но ведь речь сейчас не об этом.речь сейчас о конкретной структуре БД и как будет движок БД выполнять IN по сравнению с JOIN.
Ну точно такая же ситуация будет и с джойном. Ин-ы вообще если ты не в курсе разворачиваются оптимизатором в джойны в нормальных базах и работают абсолютно одинаково
так точно!
см. коммент выше.
а я вот посмотрел план запроса.
и проверил все эти запросы в SQL Server, где он не обманывает и более правильно выбирает индексы.и тут двух мнений быть не может.
вы неправильно поняли идею. идея не в том, чтобы заменить JOIN на IN.
идея в том, чтобы сначала сделать запрос к одной таблице (где будет WHERE, и пагинация), после чего получить ровно 10 записей.а не делать в одном запросе кучу JOIN и там делать кучу условий и пагинацию.
select .. where id IN (select ..)
РАВНОСИЛЬНО (план выполнения запросов будет идентичен)
select ... FROM ..
JOIN .. ON id = ..
21 запрос??? вы шутите?
не делайте в цикле запросы, как у вас
foreach ($this->data[’query’]->result() as $value)
{
$value->tags = $this->getTags($value->id); — тут подразумевается запрос к базе?
}
см. выше — я написал решение, как сделать
— проблем с join нет, если условия в WHERE используются
т.е. этот запрос вполне нормальный
select tag from tags where id in (select id_tag from tagarticle where id_article in ((тут array) ));
см. тут:
habrahabr.ru/...in/blog/137497
Гибкий Руби — значит, что есть несколько вариантов, как сделать одну и ту же задачу.
Фреймворк Rails — достаточно молодой, но очень быстро развивающийся. И уже есть очень много гемов (модулей) для разных задач.
Например, есть HAML — язык шаблонов для написания очень (очень!!!) короткого HTML.Конечно, есть подобное — HAML for Django — но насколько я знаю, это не родное и там не полный функционал.
Например, писать подобное в шаблонах Django — выглядит странно.
{% for obj in my_list %}
.. {{ .. }}
{% endfor %}
Возникает много вопросов. Зачем сделали длинные скобки {% %} или {{ .. }}, когда можно было сделать одни скобки {} (как в движке Smarty for PHP), либо разрешить настраивать разработчику, или почему нужно так длинно писать для закрытия цикла endfor, когда в коде Питона все намного короче.
Но молодость Rails может быть и его минусом — т.к. многие вещи еще сырые и не аппробированы. Например, не так давно появилась многопоточность.
В целом же, если выбирать между языками Python or Ruby — тут уже больше вопрос вкуса и стиля.Куда же пойдет развитие Ruby on Rails, особенно, когда спадет ажиотаж, — трудно сказать. Все будет зависеть от поддержки сообщества. Django — уже свое место занял.
Пока для меня — после Руби на другие языки смотреть уже не хочется.
про сравнение Python Vs Ruby можно почитать здесь:c2.com/...ki?PythonVsRuby — сравнивают по многим пунктам
jeffdickey.info/...maintainability — про maintainability