Зачем использовать сборщики SQL?Арел против сиквела против T-SQL - PullRequest
8 голосов
/ 10 февраля 2011

Я пытаюсь понять преимущества построения SQL с помощью объектно-ориентированного компоновщика DSL по сравнению с параметризацией необработанной строки SQL. Изучив / реализовав один и тот же запрос тремя способами, я заметил, что сырой SQL намного легче читать. Возникает вопрос: зачем прыгать через обруч? Почему бы просто не объявить и использовать сырой SQL?

Вот что я придумала:

Во-первых, я предполагаю, что это делает SQL более переносимым, так как он может быть использован любой БД с адаптером. Я думаю, это важная персона, верно? Тем не менее, разве большинство T-SQL не доступно для большинства баз данных?

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

Какую окупаемость инвестиций вы получаете, создавая SQL вместо того, чтобы объявлять его?

def instances_of_sql(ttype_id) #raw sql
  ttype_id = get(ttype_id).try(:id)
  ti   = get('tmdm:type-instance')
  inst = get('tmdm:instance')
  type = get('tmdm:type')

  self.class.send :sanitize_sql, [%{
    SELECT t.*
    FROM associations a
    JOIN roles type    ON type.association_id = a.id AND type.ttype_id = ?
    JOIN roles inst    ON inst.association_id = a.id AND inst.ttype_id = ?
    JOIN topics t      ON t.id = inst.topic_id
    WHERE a.topic_map_id IN (?)
    AND a.ttype_id    = ?
    AND type.topic_id = ?
  }, type.id, inst.id, self.ids, ti.id, ttype_id]
end

def instances_of_sql(ttype_id) #sequel
  ttype_id = get(ttype_id).try(:id)
  ti = get('tmdm:type-instance')
  ir = get('tmdm:instance')
  tr = get('tmdm:type')

  DB.from(:associations.as(:a)).
    join(:roles.as(:tr), :tr__association_id => :a__id, :tr__ttype_id => tr[:id]).
    join(:roles.as(:ir), :ir__association_id => :a__id, :ir__ttype_id => ir[:id]).
    join(:topics.as(:t), :t__id => :ir__topic_id).
    where(:a__topic_map_id => self.ids).
    where(:a__ttype_id => ti[:id]).
    where(:tr__topic_id => ttype_id).
    select(:t.*).sql
end

def instances_of_sql(ttype_id) #arel
  ttype_id = get(ttype_id).try(:id)
  ti   = get('tmdm:type-instance')
  inst = get('tmdm:instance')
  type = get('tmdm:type')

  #tables
  t    = Topic.arel_table
  a    = Association.arel_table
  tr   = Role.arel_table
  ir   = tr.alias

  a.
    join(tr).on(tr[:association_id].eq(a[:id]),tr[:ttype_id].eq(type[:id])).
    join(ir).on(ir[:association_id].eq(a[:id]),ir[:ttype_id].eq(inst[:id])).
    join(t).on(t[:id].eq(ir[:topic_id])).
    where(a[:topic_map_id].in(self.ids)).
    where(a[:ttype_id].eq(ti[:id])).
    where(tr[:topic_id].eq(ttype_id)).
    project('topics.*').to_sql
end

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

Ответы [ 2 ]

9 голосов
/ 10 февраля 2011

Ссылка, которую @Kyle Heironimus дал на мысли Ника Каллена об Ареле, содержала следующую строку:

Вы заметите использование производной таблицы в подвыборке.Это ужасно, на мой взгляд.Только опытные программисты SQL знают, как написать это (я часто задавал этот вопрос на собеседованиях, я никогда не видел, чтобы кто-нибудь понял это правильно).И это не должно быть сложно!

Что ж, Каллен объясняет это отсутствием замыкания под композицией в SQL.В некоторых случаях это может быть правдой, но мой опыт гораздо более прозаичен - большинство разработчиков ужасны в SQL.Они знают только самые базовые вещи, эти базовые вещи используются неправильно, поскольку они пытаются искать процедурные решения на языке, основанном на множестве.Мне пришлось спорить о преимуществах базы данных в 3NF в одной компании, в которой я был, с всеми другими разработчиками, они просто не получили ее.Талантливые ребята (большинство из них :), но без понятия о SQL или базах данных.

Поместите его в C #, Ruby или Python.и разработчики снова счастливы.Они могут придерживаться процедурного / ОО-мышления и создавать код, который им нравится.

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


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

Это никоим образом не аннулирует мои комментарии о понимании SQL большинством разработчиков (недавно мне сказал разработчик, который говорит с другими, что нормализация была пережиткомвремя, когда место для хранения было дорогим ... о дорогой!) только то, что разработка библиотеки Sequel, очевидно, была сделана теми, кто действительно понимает базы данных.Если вы знакомы с SQL, дизайном БД и т. Д., Это даст вам больше возможностей быстрее.Я не могу сказать то же самое о других ORM, которые я использовал, но, возможно, другие подумают иначе.

4 голосов
/ 10 февраля 2011

Вы уже в значительной степени ударили по причинам.

Здесь - мысли создателя Арела.

...