• C# проект с поддержкой нескольких бд?

    Shedal
    @Shedal
    Если использовать ORM, то ответ очевиден. Вы будете использовать встроенные в них средства, а также бороться с их ограничениями.

    В принципе же, ответ таков: выделять классический DAL — Data Access Layer. Для этого существует много стандартных паттернов. Например:

    Самое простое — Data Mapper. Создаёте интерфейс для вашей сущности:

    interface ICarData
    {
      void Insert(Car car);
      Car GetById(int id);
      // и т.д.
    }
    

    Затем наследуете от этого интерфейса классы, его реализующие — e.g. MySqlCarData, MongDbCarData.
    Отдельная задача здесь — определение, какой класс использовать. Самый простой способ — задавать имя класса через конфигурационный файл и создавать объект нужного класса простой фабрикой (switch(className) {… } ). Более красиво — использовать IoC/DI контейнер.
    Ответ написан
    Комментировать
  • Помогите подобрать подходящуюю БД

    Shedal
    @Shedal
    Так и не понял, чем вам не подходит монга. У нее же простая и действенная масштабируемость — ключевая фича.

    С оверхедом на хранение данных это вы зря. Во-первых, он есть практически везде, а во-вторых, storage сейчас очень дешевый.
    По поводу фрагментации — разве BSON-документ может делиться на фрагменты? Насколько я помню, в дефолтной конфигурации монга этого не допускает.
    Ответ написан
    Комментировать
  • [SSAS] Универсальная расчётная мера (возможно, используя хранимую процедуру)?

    Shedal
    @Shedal Автор вопроса
    Решение помогли найти на форумах MSDN: social.msdn.microsoft.com/Forums/en-US/sqlanalysisservices/thread/04019705-5b65-48f8-b403-a6d015c9dec5
    Ответ написан
    Комментировать
  • WHERE внутри вычисляемой меры? (MDX/OLAP)?

    Shedal
    @Shedal Автор вопроса
    В итоге я пришёл к следующему универсальному решению:

    CREATE HIDDEN [Total M] =
      AGGREGATE(
        DESCENDANTS(
          AXIS( 1 ).ITEM( 0 ).DIMENSION.LEVELS( 0 ).ITEM( 0 ),
          AXIS( 1 ).ITEM( 0 ).DIMENSION.LEVELS.COUNT
        ) - AXIS( 1 ).ITEM( 0 ).DIMENSION.LEVELS( 0 ).ITEM( 0 ),
        [Measures].[M]
      );
    

    Вкратце — из множества членов нашего измерения вычитаем корневой член, и по оставшемуся множеству аггрегируем нашу меру.
    Ответ написан
    Комментировать
  • Как организовать хранение последних изменений в БД проекта?

    Shedal
    @Shedal
    Я по этому поводу когда-то большую фундаментальную статью написал, с рассмотрением разных подходов. Ознакомьтесь, если хотите: habrahabr.ru/post/121265/
    Ответ написан
    Комментировать
  • [SQL] Как вычленить значение из группы на основании условия по другому столбцу?

    Shedal
    @Shedal Автор вопроса
    Для полноты картины, вот ещё одно решение, похожее на решение tonyzorin:

    WITH CTE AS
    (
      SELECT
        *, 
        ROW_NUMBER() OVER(PARTITION BY CategoryId ORDER BY ItemValue DESC) MaxRN,
        ROW_NUMBER() OVER(PARTITION BY CategoryId ORDER BY ItemValue ASC) MinRN
      FROM Items
    )
    SELECT
      CategoryId, 
      MIN(CASE WHEN MaxRN = 1 THEN ItemId END) IdMaxValue,
      MIN(CASE WHEN MinRN = 1 THEN ItemId END) IdMinValue
    FROM CTE
    GROUP BY CategoryId
    
    Ответ написан
  • Подзапрос в условии ON для LEFT JOIN'а в MySQL

    Shedal
    @Shedal
    Не работает ваш запрос потому, что вы из подзапроса обратно выбираете тот же самый user_id, который «подали вовнутрь». Иными словами, ваш запрос идентичен следующему:

    SELECT U.*, S.*
    FROM `user` AS U
    LEFT JOIN stats AS S ON S.user_id = U.id
    WHERE U.id = 1
    

    Как правильно сделать, уже написали выше. ИМХО, вариант с группировкой будет лучше всего, и читабельнее тоже. Хотя лучше сравните производительность на реальных данных. На всякий случай, держите сам запрос:

    SELECT u.*, MAX(s.date) max_date
    FROM user u
    LEFT JOIN stats s
      ON s.user_id = u.id
    WHERE u.id = 1
    GROUP BY u.id
    
    Ответ написан
    8 комментариев
  • Sublime Text 2: Как сделать выделение строки без переноса каретки?

    Shedal
    @Shedal
    После выделения просто нажмите Shift+влево. Я понимаю, что это не совсем решение, но, по крайней мере, это самый быстрый способ добиться нужного вам выделения.
    Ответ написан
    Комментировать
  • ViewModel как передать несколько моделей?

    Shedal
    @Shedal
    Ну во-первых, если все объекты NewsEntity являются объектами одного класса, или их классы наследуются от одного класса, то можно сделать вот так:

    @model IEnumerable<BaseEntity>
    

    А если модели совсем разные, то можно их в контроллере записать во ViewBag (или ViewData):

    ViewBag.NewsEntity = new NewsEntity( /* ... */ );
    ViewBag.OtherEntity = new OtherEntity( /* ... */ );
    

    И потом во view'хе так же к ним и обращаться: ViewBag.NewsEntity....
    Ответ написан
    Комментировать
  • Голосование за статьи ограничено по времени. Зачем?

    Shedal
    @Shedal
    Первая причина — чтобы все посты были в более-менее равных условиях. Благодаря этому, есть рейтинг постов за всё время. Если бы период голосования не был ограничен, то у старых постов было бы больше голосов, чем у новых.

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

    Возможно, есть и другие причины.
    Ответ написан
    2 комментария
  • Какие языки программирования преподавать?

    Shedal
    @Shedal
    Вообще, мне немножео грустно за людей, которые начинают изучение программирования с языков, где управление памятью спрятано. Ведь в будущем, если программированием заниматься серьёзно, всё равно будет нужно понимание, что где и как хранится в памяти. А если привыкнуть к хорошему, выучить это будет сложнее.
    Поэтому мой выбор, всё-таки, C/C++.
    Ответ написан
    2 комментария
  • Многопанельный файловый менеджер под винду

    Shedal
    @Shedal
    Ответ написан
    Комментировать
  • Хранение сложной структуры в mysql. Как?

    Shedal
    @Shedal
    Делать 4 таблицы (коммент запроса, похожие фильмы запроса, коммент ответа, фильмы ответа) не очень хочется во нескольким причинам:
    слишком много запросов в БД будет на получение списка запросов на просмотр (запрос, фильмы, кто, что советует)
    слишком много лишних телодвижений будет и при ответе
    Что значит слишком много? По сравнению с чем?

    Вообще, 4 таблицы — это будет нормализированный способ хранения ваших данных. Можно и денормализировать, но это ухудшит расширяемость и возможности по манипуляци данными средствами SQL. Иногда денормализация приемлема, просто нужно в полной мере осознавать, какими будут последствия.

    Например, можно сделать две таблицы: Comments и CommentMovies. В Comments добавить поле IsQuestion, в котором хранить TRUE, если это вопрос и FALSE, если это ответ. CommentMovies будет хранить фильмы как для вопросов, так и для ответов.
    Минусом такого подхода будут проблемы функциональной расширяемости. То есть, если вы захотите добавить в таблицу Comments поле, присущее только вопросам, то у вас будет, по сути, три пути:
    1) Рефакторинг структуры: разделение на ваши исходные 4 таблицы. Это трудозатратно;
    2) Добавление ещё одной таблицы: QuestionCommentFields. Структура получается корявой;
    3) Создание поля, которое будет хранить значения только для одного типа строк. Это уже денормализация.

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

    В общем, выделите для себя какие-то приоритеты и путеводные камни. Будет ли структура часто меняться в будущем, важна ли простота поддержки? Важна ли скорость выполнения запросов, важна ли возможность менять данные напрямую SQL'ем? И т.п.
    Ответ написан
    2 комментария
  • Что установить на IPAD для Google talk?

    Shedal
    @Shedal
    Я использую imo.im. Довольно удобно, особенно учитывая, что он поддерживает и другие протоколы.
    Ответ написан
    1 комментарий
  • Как лучше сегодня продавать php скрипты?

    Shedal
    @Shedal
    Я себе так представляю, что те, кто не хочет платить за вашу CMS, всё равно за неё платить не будут. Или взломают, или найдут другую, бесплатную систему, благо, их сейчас очень много.

    Если же ваша система будет предоставлять какие-то конкурентные преимущества (функциональность, быстродействие, дизайн, etc.), то компании, которые захотят платить, даже не станут искать способа её взломать.
    На самом деле, есть ведь системы с открытым исходным кодом, которые разрешается использовать бесплатно в некоммерческих целях, в противном случае нужно платить. И люди платят — по одной из следующих причин:
    — большие компании чувствуют себя более уверенно, когда используют платный софт. В этом случае у разработчика, вроде как, есть какие-то обязательства перед клиентами;
    — платный саппорт, по той же причине;
    — просто хочется поддержать хороший проект.
    Ответ написан
    3 комментария
  • Какие есть средства локализации на уровне MySQL?

    Shedal
    @Shedal
    Как вариант, можно создать таблицу translations (text, culture, translation).

    Определить функцию translate(text, culture), которая будет возвращать или перевод, если он есть, или изначальную строку, если перевода нет.
    Использовать её можно будет с любой таблицей:

    SELECT Id, translate(Value), translate(Value2) ...
    

    Конечно, для разных ситуаций подходят разные решения. Например, из вашего описания непонятно, нужно ли вам переводит данные из одной или многих таблиц, могут ли строки текста переводиться по-разному в зависимости от контекста, и т.д.
    Ответ написан
    1 комментарий
  • Каким образом организовать локализацию Backbone.js-приложения?

    Shedal
    @Shedal
    А по-моему, у вас достаточно красиво получилось. Единственное, я бы поместил объект LocaleModel вовнутрь MyAppView. Так как-то более структурированно получается.

    А чем вас не устраивает такое решение?

    P.S. bind() и unbind() это устаревшие функции underscore. Начиная с какой-то там версии нужно использовать on() и off().
    Ответ написан
    1 комментарий
  • HTTP заголовок Expires. Почему браузер тем не менее обращается к серверу?

    Shedal
    @Shedal
    Когда вы обновляете страницу при помощи F5, браузеры обычно запрашивают у сервера, не изменились ли статические ресурсы, при помощи заголовка If-Modified-Since (что и видно на вашем скриншоте). А вот если вы откроете страницу заново, — закроете вкалдку, откроете новую и введёте адрес, — то ресурсы должны загрузиться из кэша, без round-trip'а к серверу.
    Это такая специфика команды перезагрузки страницы, которую вы даёте браузеру.
    Ответ написан
    3 комментария
  • +1 к защите пароля методом тройного хеширования. Бред?

    Shedal
    @Shedal
    Можно ещё по-другому поступить. Выбрать один из криптоалгоритмов, в которых шифрование можно производить открытым ключём, а дешифрование — закрытым. Передавать брузеру открытый ключ, принимать зашифрованный пароль, и дешифровать его на серверной стороне закрытым ключём.
    В этом случае, перехват открытого ключа ничего злоумышленнику не даст, т.к. им можно только зашифровать, но не расшифровать.
    Перехват зашифрованного пароля тоже ничего не даст, т.к. закрытый ключ есть только у сервера.

    Ну, и хранить пароли в БД классически: hash + salt.

    P.S. А не проще ли на страничке авторизации ввести https?
    Ответ написан