Pull to refresh

Comments 175

Разделите пожалуйста абзацы, сейчас все слитно и тяжело читать. Спасибо за ваш перевод :)
Разделил. Рад что понравилось.
Только вчера обсуждали с коллегой, что программист должен быть полностью абстрагирован от БД. SQL, NOSQL — на уровне приложения это не должно играть абсолютно никакой роли. ОРМ (ну или у кого там что в зависимости от парадигмы), должна быть гибкой и позволять безболезнено сменить используемую БД на любом этапе разработки. Звучит конечно утопично, но имхо в будущем так и будет

Перевод очень качественный, спасибо.
ОРМ (ну или у кого там что в зависимости от парадигмы), должна быть гибкой и позволять безболезнено сменить используемую БД на любом этапе разработки. Звучит конечно утопично, но имхо в будущем так и будет

Я такие же слова много раз встречал в отношении ООП «можно безболезненно заменить одно на другое и всё будет работать». Это не работает, моё личное мнение. Всегда нужно держать в уме весь стек используемых технологий, иначе случаются казусы и глюки.
Полностью согласен. Кроме казусов и глюков еще чаще бывает неэффективное использование — например многие БД имеют полезные особенности, не доступные через слой абстракции.

Ну и стоит вспомнить еще и о законе текучих абстракций:

www.joelonsoftware.com/articles/LeakyAbstractions.html
Я и сказал в конце коммента
>Звучит конечно утопично, но имхо в будущем так и будет
UFO just landed and posted this here
Как апи может не зависеть от имплементации? Они непосредственно связаны, и API предоставляет доступ к имплементации. Это фантик над ней. И этот фантик может подходить к другим конфетам, а может и не подходить. Так вот тот который подходит — это обычный фантик, им удобно оборачивать разные конфеты, а если фантик уникален — то им обернешь только один вид конфеты, но зато КАК!

Это компромисс между перфомансом, удобством и доп фичами в случае специализированного API, и обобщенностью и заменяемостью в случае обобщенного.

Не нужно говорить хорошая\плохая. В жизни почти везде компромиссы. Полярность — это чаще следствие максимализма.
UFO just landed and posted this here
Как пример — посмотрите на статью Спольски про текущие абстракции
но имхо в будущем так и будет

В будущем терабайты данных будут хранится в памяти, а сбрасывание их на диск будет занимать сотые доли секунды. :)
Насчёт последнего хочу вас сильно разочаровать. Скорость СХД растёт много медленее, чем ёмкость. Если в 2000ых нормой для HDD было 30Мб/с, то сейчас — 130. На SSD — около 270. Т.е. даже на порядок не выросла. Ёмкость с тех пор выросла примерно на 2 порядка.
Зато появились системы вроде zfs, которые умеют работать с только измененными участками данных. Вероятно, схожие алгоритмы найдут свое применение и для работы с данными в памятью и параллельном сохранении на диск.
Будет все проще! Будет кэш процессора и просто память. Та которая рядом и та которая далеко. В нее пишешь и не думаешь, что еще нужно потом скинуть в долговременную память.

Не будет оперативной и долговременной памяти. Только просто память!
ну когда-то так и будет, но умное сбрасывание данных на диск появится гораздо раньше. Точнее, будет развиваться то, что уже есть
Лет восемь назад думал о том, что было бы неплохо скрестить оперативку с флешкой. Если на одном чипе, то сохранение памяти во флеш займет очень мало времени. Чуть ли не тригер возле тригера можно сделать.
Теоретически конечно… помню тогда интересовался этим, и что-то там мне показалось слабо реализуемым на уровне техпроцессов. Но уже восемь лет прошло…
А зачем это делать? Гебернейт уже давно есть, если сбрасывать на ssd то и будет примерно то, о чем вы говорите.
Восемь лет назад ssd еще не было.
Но не в этом суть — тут время в секундах измеряется. Это много.
За это время может потеряться питание, произойти глюк и т.п.
И делается процессором.
А это ненадежно надежно.
Он может зависнуть, остаться без питания и т.п.
Та было, просто называлось иначе и не в таком широком доступе было;)

Вопрос в том, как вы представляете себе дублирование оперативы на флешку. Она во-первых медленнее в разы, во вторых сдохнет быстро, если ее в схожем режиме с оперативой использовать
Оперативка, обычная DDR3 на два гигабайта… Внутри — 2гб озу и 2гб флеш.
Но только не так чтобы 8 чипов озу и 1 чип флеш, а именно восемь чипов общей памяти (ну или 16, не суть). Внутри каждого чипа есть оперуха и флеша.
Падает питание, подается команда «сохраняйся». И чип делает запись на флеш.
Поскольку тут доли секунды то хватит и конденсатора для питания.

Если сохраняться десять раз в день, то лет на тридцать должно хватить.
Уверенны что доли секунды? Даже сейчас скорость записи на SSD не превышает 200-400МБ если рассматривать долговременную запись по всему объему. 2ГБ это 5-10с, при том что оператива сейчас в ходу от 16, если брать стационарные компьютеры. А тогда флеш была на порядки медленее.

Эта задача решается гипернейтом (на рейд из sas дисков оно было бы быстро и 8 лет назад) + ups. Значительно дешевле и практичнее вашего решения.
Уверен.
Я же говорю — НА ОДНОМ ЧИПЕ.
Не нужно гонять по шине.
В самом идеальном случае это будет один бит памяти, за ним один бит флешки.
Т.е. выход тригера памяти идет на вход флешки… сразу, без шины.
Т.е. вся память сохраняется ОДНОВРЕМЕННО, а не блоками.

Понятно что в реалиях будет немного не так, ибо «служебная» логика вырастет в разы, но тем не менее близость носителей была бы очень быстрым решением.
В шину сейчас ничего и так не упирается — только в производительность самой флеш-памяти и алгоритмы контроллера (не производительность контроллера). И тут уже без разницы как близко вы разместите одну и вторую память. Запись в миллион потоков только понизит производительность, вместо повышения.

И главное, чем ваше решение лучше обычного УПСа?
Преимущества я написал выше.

За контроллером идет шина через которую он и работает с памятью.
Поскольку запись последовательная, то мы имеем задержку. А если шины нет, и запись параллельная то скорость записи всей памяти равна скорости записи одного бита.
Во-первых, вы не понимаете, как работает флеш-память (любая память), если говорите о том, что параллельность увеличит производительность. Повторю: в шину и сейчас ничего не упирается.

Во-вторых, любой современный ультрабук умеет мгновенно засывать при закрытии крышки и жить в таком режиме пару недель. Напряжение на память при этом подается, просыпается из такого режима за 2 секунды. Если батарея подходит к концу, то автоматиески идут гибернейт.

В материнскую плату можно встроить аккумурятор от телефона, который будет весить как один из радиаторов, при этом, обеспечит возможность проработать в спящем режиме несколько часов и потом загибернейтиться, если с питанием таки все плохо.
Технология уже есть (в последнем поколении ультрабуков), аккумулятор встроить не проблема, задача решается даже лучше, чем ваша (хоть вы и уверенны в бесконечной скорости флеш-памяти, на самом деле, это совсем не так), зачем городить огород?
Ну сейчас может и нет смысла. Единственное преимущество в том, что это было бы хардварное решение, которое более надежно. Ну в плане того что оно единое и без множества посредников.

Я об этом вспомнил чисто в контексте того, что вполне может скорость вырости революционно. Я ж не предлагаю прямо бросаться это реализовывать. Просто как концепт озвучил в ответ на:
===
Насчёт последнего хочу вас сильно разочаровать. Скорость СХД растёт много медленее, чем ёмкость. Если в 2000ых нормой для HDD было 30Мб/с, то сейчас — 130. На SSD — около 270. Т.е. даже на порядок не выросла. Ёмкость с тех пор выросла примерно на 2 порядка.
===
В вашем случае, вылетает флешк-модуль и под замену весь блок идет. К тому-же, аше решение такое-же хардварное, как и текущее в ультрабуках. И там как раз обошли ограничение в скорости СХД благодаря тому, что система может неделями в спящем режиме работать, этого хватит, чтобы на ленту оперативу сбросить.
Кэш процессора тут тоже лишний — будет просто БЫСТРАЯ ПАМЯТЬ :)
Не соглашусь. Все же будет память «рядом» и память «далеко». Та что «рядом» и есть кэш.
Отображение файлов на память есть и сейчас. Вопрос нужно ли все изменения в быстрой памяти дублировать в долговременную, а если не нужно, то как разделять в коде?
Сейчас RegMem-Cache-DRAM-HDD,
а будет нечто вроде RegMem-Cache-(MRAM|PRAM).

В коде на уровне ассемблера модель Cache программно недоступна (почти). Поэтому можно не задумываться как разделять в коде обращения в Cache и DRAM. Нужно лишь помнить о размере L1, L2, L3, DRAM и обрабатывать данные в соответствующем порядке и объеме.
Мне кажется, что автор писал не о том, чтобы абстрагироваться от БД, а вообще не рассматривать БД как обязательный элемент.

Например, большинство современных сайтов на которых есть только набор статических страниц зачем-то тянут за собой БД. Там как раз не нужно ни хитрых выборок, ни отчетов. Прекрасно можно обойтись просто файловой системой.

На самом деле в таких случаях не нужно даже PHP/Ruby/Python для обработки каждого запроса. Можно все так же удобно сделать через генераторы вроде Jekyll. Но это уже оффтоп, конечно.
Именно так!
Если начать не с технологии хранения — можно всё сделать и оптимальнее и, что важнее, правильнее.
Можно обойтись, написав строчек 200 сохранения, загрузки, валидации, управления безопасностью.

А можно просто подключить компонент и реализовать это за 5 строк. Надежно, быстро, безопасно. Да, не очень оптимально. Да, не самое рационально по CPU/RAM/HDD. Зато очень рационально по человеко-часам чтения и написания софта.

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

Но вы смотрели, нету ли каких-то уже готовых решений которые в некоторых задачах могут заменить БД не уменьшив ни эффективности разработки ни эффективности решения?

Я, например, упоминал Jekyll. На нем построены GitHub Pages, которыми пользуются достаточно многие, для сайтов проектов, блогов и т.п. И там совсем не надо писать 200 строк сохранение/загрузки. Более того, там не надо писать даже 5 строк. Есть еще некоторое количество менее известных утилит, делающих приблизительно то же самое.

Но, конечно, иногда необходим чтобы клиент мог редактировать контент в браузере и все такое. Для таких случае есть например pulsecms.com/

P.S. Действительно ли сохранение/загрузка файла на диск требует в 40 раз больше кода, чем выполнение запроса к БД?

Ruby:

File.read("content/#{id}")

File.open("content/#{id}", "w") {|f| f.write data}


PHP:

$fh = fopen("content/".$id, 'w');
fwrite($fh, $data);
fclose($fh);


Плюс — не надо подсоединяться к БД, создавать там схему и все такое.
Добавьте: десериализацию (редко когда всего одно поле данных, скорее всего хранится какая-то структура), защиту от параллельной записи, проверку на валидность имени файла (чтобы не читать /etc/passwd), защиту от одновременной чтения и записи.

Пускай не 200, но если говорить про блокировки одновременного доступа, то строк будет явно больше чем подключение к БД.

И дело даже не в строках: диска-то на лишних 500 байт не жалко. Дело в том, что чем больше кода, тем больше багов. А это уже важнее.
Да, безусловно когда количество таких моментов растет, готовое решение будет явно лучше. Возможно, что это будет именно БД.

Но, из того, что вы указали преимуществом БД является вообще говоря только одновременный доступ.

Все остальные проблемы (валидация, квотирование, сериализация) решаются или библиотекой работы с БД или кодом в вашем приложении, который с ней взаимодействует.

Точно так же вы можете решать их стандартными средствами и без БД. Например, сериализуя данные в JSON/YAML, для чего сейчас практически везде есть стандартные средства.

Много кода это очевидно хуже чем мало, да. Поэтому, где это возможно лучше использовать готовые средства. Но БД не является единственным таким средством. Например, в руби есть такая штука как PStore, он кстати и проблемы одновременного доступа решает используя атомарные переименования.

Вот когда БД вам действительно нужна — это несколько серверов, работающих с одним набором даннымх. Ну или если вы делаете какие-то выборки кроме как по ключу, конечно.

Но, если вернуться к началу ветки — я все-таки писал о «большинстве современных сайтов на которых есть только набор статических страниц». Мне кажется, что 90% их потребностей покрывают готовые средства вроде Jekyll или PulseCms. И писать строки кода, решающие описанные проблемы там не нужно ни при использовании БД ни без нее.

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

Давайте рассмотрим гипотетическую CMS реализованную без БД и использующую файлы для хранения данных.

Для каждой страницы нам нужно в файле хранить достаточно большой набор информации, это может быть: собственно содержимое страницы представленное в виде набора различных полей, конфигурация визуального представления, конфигурация виджетов и пр… Так же нам желательно хранить дополнительную информаци, такую как время модификации, автора и т.д.
Для того чтобы все это хранить нам нужно реализовать механизм сериализации/десериализации данных, механизм предотвращения одновременной модификации и т.д

Далее перед нами встанет вопрос поиска. Например, нам нужно реализовать поиск информации по заданным полям на странице. Для того чтобы это работало быстро — нам нужено будет реализовать индексирование по полям. Так же нужно будет реализовать обновление индекса при обновлении информации страниц и тд…

В конечном итоге мы получим некое подобие системы управления БД встроенной в нашу систему.
Есть такая система, называется докувики.
Полноценный вики-движок, полностью на файлах.
dokuwiki.ru/
Про сериализацию я уже писал.

По поводу поиска — если сценарии использования вашего приложения включают поиск по полям — используйте те средства, которые позволяют его просто реализовать. Например, БД. Или Сфинкс. Или ДокуВики (интересно как там это сделано, не знал про нее).

Если не включают — вы можете использовать что-то более простое.

В случае «сайтов на которых есть только набор статических страниц», пользователю не нужен поиск по полям, ему нужен поиск страниц — с этим прекрасно справляется какой-нибудь Google Site Search.

Разумеется, если вы пишите сайт магазина или социальную сеть — хранение в файлах это совсем не самое лучшее решение, и я не знаю как тут обойтись без БД.

Просто используйте те инструменты, которые подходят к вашей конкретной задаче.
А унификация?
Вот зачем мне поддерживать несколько разрозненных решений?
Зачем мне для сложных задач держать SQL-решение, для тяжелых баз noSQL а для простых и легких файловую базу?
Если у меня есть решение которое работает на простых задачах, то зачем мне делать другое? Просто потому что «так лучше»?
Вот серьезно. Практическое преимущество какое? Не нужно заморачиваться с настройками базы при установке? Ну так с правами на запись забадаешься… Скорость? Да пофиг на нее в маленьких задачах)

Ну как компромисс можно конечно sqlite брать, но в статье вроде как не об этом.
Резюмируя, можно сказать, что в современных СУБД важна не сама БД, а обвязка, которая серьезно упрощает процесс работы с данными.
Ваш вариант отлично работает для простых сайтов. Но вот когда вам нужно посмотреть страницы одного автора, которые были опубликованы между 20м числом предидущего месяца и 10м числом текущего отсортированы по количеству комментариев от большего до меньшего, то вместо соединения с базой и несложного запроса вам нужно будет нагородить довольно много кода, не так ли?
Конечно. И я несколько раз уже написал об этой ветке.

Инструмент нужно выбирать с соответствии с решаемыми задачами.
об этой ветке => об этом в этой ветке
Иногда использую в PHP:

file_put_contents("content/{$id}", serialize($content));

$content = unserialize(file_get_contents("content/{$id}"));


На любителя можно использовать json_encode/json_decode или любой другой «сериализатор», например YAML или XML.
Неоднозначно.
Недавно написал легкий движок файлообменника. Всего 20кб кода.
Функционал простой как пять копеек — загрузил, скачал, копии, абузы, просмотр в зависимости от миме (т.е. видео значит смотрим онлайн-видео, аудио значит аудио, картинка значит картинка..), защита от хотлинка… В общем то и всё.
Я решил написать его на файлах. Чистых файлах без ничего. Подумалось что информации у меня не много и не сильно она разнообразна… а базы под нагрузкой это специфика… Ну и отдельный файл для каждой записи мне показалось достаточно быстрым и защищенным от блокировок решением.

В общем на практике структура «базы» менялась раз шесть, каждый раз вместо тривиальной одной строчки в ORM приходилось все перекручивать и принимать решения. Решения не сложные, после третьей переделки я все «запросы к базе» вынес в один файл, чтоб проще было, но тем не менее — это куча телодвижений, а задача простая.

После этого я зарекся без готовых библиотек лезть в файловое хранение… Хотя в 2DO я себе записал сделать драйвер для своего ORM для хранения в файлах.
Я имел в виду в первую очередь блоги, сайты-визитки и прочее, где весь динамический функционал состоит максимум в использовании комментариев (которые сейчас все чаще подключаются на стороне клиента через внешний сервис).

В таких случаях не нужно логики на сервере вообще, Apache/Nginx может отдавать просто статичные страницы, которые заранее подготовлены чем-то вроде Jekyll.

А в вашем случае (когда пользователи как-то меняют содержимое) то или иное хранилище данных однозначно нужно, лучше использовать что-то готовое, например БД.
Нет, так нельзя. Если ОРМ позволяет сменить любую БД на любую другую, то фичи конкретных БД просто игнорируются.
Нет — если ОРМ умеет использовать фичи конкретных БД. А приложению, за слоем абстракции, будет без разницы как оно там устроено
Если ОРМ использует фичи конкретных БД, то это значит, что она прибита к этой БД гвоздями. И ни о каких сменах БД речь идти не может.

Это в принципе общая проблема всех проксей.
Окей, а вам часто в реальных проектах приходилось переходить с одной СУБД на другую? Наверное, очень редко или вообще никогда. А часто нужно было поддерживать более, чем одну СУБД одновременно? Наверное, чуть чаще, но всё равно редко. А часто приходилось выдумывать костыли из-за того что гибкий ORM не предоставляет какой-то нативной возможности СУБД? Предполагаю, что бывало такое. Ну так в чём профит гибких ORM?
>Окей, а вам часто в реальных проектах приходилось переходить с одной СУБД на другую
Нет это задача редкая.

> часто нужно было поддерживать более, чем одну СУБД одновременно?
Да, связка SQL+NOSQL имеет смысл в определенных ситуациях. Было бы просто офигенно работать с ними через единый объектный интерфейс.

>А часто приходилось выдумывать костыли из-за того что гибкий ORM не предоставляет какой-то нативной возможности СУБД?
Бывает такое, в узких местах, порой приходится по-старинке, ручками

>Ну так в чём профит гибких ORM?
Имхо за ними будущее. И в первом комменте, я говорил о будущем, а не о текущем состоянии дел (современные орм, чего греха таить, далеки от совершенства).

Это нормальная тенденция в развитии технологий — по накоплению определенного стэка знаний, происходит разделение на более узкие специальности. Кто-то например пишет компиляторы, а кто то софт, который эти компиляторы будут собирать. То же станет и с БД, помяните мое слово — будут узкие специалисты, занимающиеся созданием ОРМ, и прикладные разработчики, использующие их.
Это нормальная тенденция в развитии технологий — по накоплению определенного стэка знаний, происходит разделение на более узкие специальности.

Какое уж там разделение, если программисты не хотят понять необходимость наличия администраторов БД. Причём каждая СУБД это свой мир, свои правила, свои оптимизации и, чего уж там, хаки. Даже между двумя РСУБД столько отличий, что если в проекте используются несколько, лучше иметь несколько спциализированных АБД (либо одно Чака Норриса). Что уж говорить про различия между реляционными, объектными, иерархическими и прочими БД. А вы хотите это всё под одну гребёнку. Если уж будет разделение разработчиков, то разделятся именно по опыту работы с API разных БД.

А то, что вы говорите, это ещё более утопично, чем сказать что в будущем html/css будет полностью семантическим.
Расскажите о том какие специфические вещи связанные с СУБД приходится использовать?
Есть драйвер который выполняет основные действия, а дальше уже абстрактный слой…
На практике сталкивался с тем, что лишь несколько узких мест нужно было вручную запрос написать для ускорения, и он уже потом при переносе мог вызвать или тормоза или отказ в работе если сильно специфичный был. Но это детали, и очень редкие.
Я, видимо, как-то неточно выразился.

Я как раз против «гибких ORM» и считаю это чем-то типа premature optimization: эффективно(читай — с учётом конкретных особенностей и фич) базу надо использовать прямо сейчас, а гипотетические миграции с одной СУБД на другую то-ли будут то-ли нет. И, собственно, пытался показать, что совместить и то и другое(и эффективную работу с БД и абстрагирование от неё) не совсем возможно. Поэтому отказ от «лёгкости» — вовсе не блажь или там ошибки дизайна а сознательное решение.
С чего бы — конкретные интерфейсы для конкретных БД на уровне ОРМ + интерфейс уровня приложения
С того-бы, что этот единый интерфейс, предоставляемый ОРМ будет реализовывать только пересечение функционалов этих самых БД. Т.е. мы вернулись к самому началу: фичи конкретных БД просто игнорируются.
Не факт, он может предоставлять и объединение функциональности. В реализациях где возможно будут использоваться фичи движка, где нет — «костыли».
Все нужное переносим в ORM, и если движок база не поддерживает возможность, то делаем в ORM то, что делали бы в логике программы.
К примеру — делаем в ИННО внешние ключи, а в майисам делаем эти функции кодом драйвера. В результате с точки зрения программиста разницы нет никакой.
Да мужик просто псих же.
Нет, я серьезно. Жуткий obsession на почве БД, как можно столько лет заниматься «предупреждениями и увещеваниями», и как можно не допускать компромиссов между скоростью разработки и используемой архитектурой приложения. Он не сильно-то лучше и объективнее своих ветряных противников, маркетологов от БД.
есть такие программисты-фанатики. вот он, по-моему, из их числа
Я по привычке всегда представляю архитектуру как тонкую прослойку между базой и пользователем, которая служит обычным предохранителем от нежелательного воздействия.

Статься заставила задуматься, я не могу представить другого. Где почитать о разработке, которая не ставит БД в «серце системы»? Может автор прав?
Да, ставить БД в основу основ при проектировании системы, с одной стороны — не хорошо. Но порой в базу данных и закладывается вся предметная область, так как это, скорее всего, это удобно.

С другой стороны правильнее проектировать систему исходя из подхода который был выбран. Выбираем ООП — мыслим в терминах объектов и классов, а дальше уже думаем где у нас будут данные храниться, и главное — как храниться.
Пользователь в данном случае кто?
Если клиентское приложение то возможно так и надо, если это именно пользователь то вы уж меня извините но софт пишется для пользователя а не для БД. Так что это бред как бы.

Есть некая задача которую надо решить. Решить ее надо удобно, чтобы пользователь сделал меньше кликов, увидел меньше окон и таки добился результатов. Это всё.

И я что-то не вижу тут в этой формулировке ни слова о данных. В целом я абсолютно согласен с автором статьи. Есть набор процессов, которые следует автоматизировать, и вот они во главе угла.
Я несознательно связал базы данных с web-приложениями… А так, у самого, большой проект на С++, который хранит данные в своем бинарном формате.
Попробуйте представить, что ваше приложение живёт в оперативке вечно, объект, который вы создали никуда не исчезнет пока его явно не удалишь, память не ограничена, доступ произвольный и прочие идеальные штуки. Нужна вам будет в такой ситуации БД? А теперь рассматривайте БД лишь как контролируемый своп, в который неиспользуемая сейчас память выгружается, а когда нужно загружается.
Слава SQL-я пошатнется когда NoSQL решения смогут обеспечивать транзакционную целостность. Сейчас ни Mongo, ни CouchDB могут гарантировать лишь атомарность единичной операции.

Если же, например, у вас онлайн игра, где предмет передается от 1 персонажа другому, то ни одно NoSQL решение не может гарантировать что у вас исключена ситуация, когда предмет отобран от персонажа А, но не пришел к персонажу Б.

Для серьезных систем, особенно оперирующих деньгами и услугами, это критически важно.
OrientDB может. ACID транзакции у них заявлены.
Полностью согласен!
Надеюсь, недавно привлеченные инвестиции помогут Mongo реализовать транзакционность.
Хотя, если честно, написать очередь транзакций — это строчек 200 кода.
заставить эти транзакции работать также надёжно как в оракле — это 200 человеко-лет
Да при чём тут SQL или NoSQL. Да, NoSQL скоро подтянутся и будет в них всё, что есть в РСУБД: транзакционность, хранимые процедуры на JavaScript, блокировки разных уровней, разделение прав доступа, ссылочная целосность и всё прочее, чем обросли современные РСУБД. И какая тогда будет разница? Ну не будет SQL, будет свой API доступа к данным (пока же у документо-ориентированных БД нет и десятой доли возможностей доступа к данным, предоставляемых SQL). И опять разработчики взвоют, что им не дают конролировать данные. Как ювелир, который обрабатывает золото, преобразуя его в конечные изделия, но не имеет полного доступа к нему [золоту], так и программист только выполняет обработку данных и красиво отображает их на экране. Заказчикам в сотни раз важнее сами данные, чем процессы отображающие их на экране и позволяющие производить манипуляции с ними. Заказчики должны иметь резервные копии данных и контролировать процессы, которые могут привести к порче данных: пусть хоть сгорит сервер приложений и репозиторий исходных кодов, но если испортятся данные это практически крах бизнеса. А автору просто обидно, что крупные компании не верят в то, что он, великолепный программист, может сам безопасно хранить данные (и правильно делают).
Полностью согласен.

СУБД — лишь способ обеспечить надежное хранение данных. И покуда NoSQL не могут гарантировать надежность этого хранения, оно имеет лишь ограниченные возможности применения.

Посмотрю я на этого апологета NoSQL/файлов когда у него в системе, оперирующей деньгами, со счета одного абонента деньги снимутся, а на счет другого не придут. Как он будет выяснять что случилось и что он будет делать в этом случае.
Многие современные NoSQL вполне успешно справляются с надёжным хранением данных и обеспечивают хорошую персистентность: тот же монго при должной настройке и конфигурации системы, редис и многие другие. Да, для финансовых приложений всё равно не очень годится. Другое дело, что подход-то не меняется — те же БД только в другой обёртке. Тот же отдельный уровень в приложении. Те же администраторы БД, ведь чтобы грамотно настроить MongoDB тоже нужен квалифицированный специалист. Да что уж там говорить — Java разработчики не очень-то хотят сами писать map/reduce функции. Хотя казалось бы — вот оно, NoSQL, теперь программисты сами будут управлять данным, складывать их как захочется и извлекать, а не тут то было — от нас, администраторов БД, вам ещё не скоро удастся избавится :)
Скорость MongoDB отчасти заслуга отсутствия транзакций. Посылаешь данные, монга их принимает и ставит в очередь. Никто не может сказать, запишутся ли данные или нет, даже время точно определить нельзя.

Если не страшно потерять часть данных, то решения типа MongoDB идеально.
Ещё раз повторю: монгу можно использовать с ипользованием транзакций (1, 2), журналирования (1), можно определить записались ли данные на диск (1, 2), записать их принудительно (1) и много другое. В будущем, уверен, всё это доведут до ума и всё это будет красиво.
Хех, у меня как раз все ваши ссылки visited. А почему? Потому, что транзакции работают только в пределах одного документа, а междокументные приходится делать своими руками (1, 2), журналирование вызывает segfault, когда кончается место на диске, а при крэше процесса БД чинится дольше, чем банальный MyISAM у MySQL (10 минут на гигабайтную БД). И многое другое.

В общем, конкретно mongodb до ума не довели пока ещё :)
да тот же оракл — хранит данные в дереве — а SQL это только оболочка для программистов — и обработка транзакций в SQL ориентированных БД — к SQLю не имеет никакого отношения и ещё раз напишу есть СУБД поддерживающие не реляционные модели данных с транзакциями журналированием зеркалированием теневым копированием и прочими важными нужными и полезными штуками есть знаю и работаю с СУБД Cache — но уверен одна не одна такая

поймите SQL — не имеет никакого отношения к транзакциям — вообще никакого!
Сейчас ни Mongo, ни CouchDB могут гарантировать лишь атомарность единичной операции.

Если же, например, у вас онлайн игра, где предмет передается от 1 персонажа другому, то ни одно NoSQL решение не может гарантировать что у вас исключена ситуация, когда предмет отобран от персонажа А, но не пришел к персонажу Б.

Не знаю про Couch, но Mongo такое гарантированно умеет делать. Просто выглядеть будет несколько непривычно.
Ага, двухфазные коммиты — костыль который не везде-то и применишь. Вместо BeginTransaction...Actions...CommitTransaction десятки, если не сотни/тысячи строк кода.
Из моей практики следует, что возможность атомарной операции над набором документов нужна куда как реже, чем возможность атомарного доступа к конкретному документу. Причём, даже при сборе статистики.
Нужно редко. Но очень сильно. :)
В знак согласия — Вам +1.
Cache — древовидная СУБД — при использовании прямого доступа обеспечивает транзакционную целостность (в ней есть поддержка реляционной и объектной модели — но это только для тех кто не представляет noSQL БД)
Может разработчики монго специально не делают транзакции, т.к. хоть и удобный инструмент, но медленный.
> ни одно NoSQL решение не может гарантировать что у вас исключена ситуация, когда предмет отобран от персонажа А, но не пришел к персонажу Б.
В mongo это можно выполнить двухфазными комитами. Это конечно более сложный механизм но он не «тормозит» базу — все комиты, с одними данными, выполняются параллельно.

Но если транзакции нужны позарез, то ничего не мешает заюзать тот же mysql для конкретной задачи.
Очень много крупных проектов используют не одну БД/инструмент, хабр например использует sphinx search (не БД но там тоже данные), кто-то использует дополнительно memcache и т.п. Т.е. используется набор инструментов под задачи.

PS: Кстати вот ответ по транзакциям в FAQ:
> MongoDB does not have support for traditional locking or complex transactions with rollback. MongoDB aims to be lightweight, fast, and predictable in its performance.
«что у вас исключена ситуация,» — такая ситуация будет происходить в 0.000001% случаев. Для этого случая можно просто логировать все операции и восстановить ручками. Зато у вас приложение упростится в разы.

«собенно оперирующих деньгами» — у вас данные с гораздо большей вероятностью испортятся из-за багов. Автор все правильно пишет, мы все слишком привыкли верить во все эти маркетинговые штуки типа ACID, которые если копнуть глубже не очень-то и оправданы.
А как же целостность данных? В этих «маленьких и быстрых» нереляционных БД, в той же упомянтой Mongo, нет (пока) ни транзакций, ни даже блокировки на уровне документа.
Даже на уровне нескольких документов поддерживает (см. комментарий выше). Но от этого ни холодно, ни жарко. Вместо элегантного SQL, поддерживающего абсолютно любые транзакции, вы получаете транзакционность для пары/тройки сценариев.
Как мне заблокировать от изменений все документы, участвующие в расчётах во время транзакции?
findAndModify + ещё одно поле документа.
То есть, сначала найти все используемые в транзакции документы. При этом установить им флаг, что они используются. После чего, произвести расчёты. Если во время расчётов появились ещё документы, им тоже установить этот флаг. После чего, произвести изменения и снять эти флаги. При этом, вся остальная логика должна знать и помнить, что у документа есть такой флаг, который надо учитывать. Таким образом, вроде как можно защититься от аномалий. Я правильно понял логику? Это действительно удобно, надёжно и не создаёт проблем?
Приведите пример, когда такое нужно. Тем более, что, обычно, транзакции в sql вообще не позволяют обрабатывать документы, появившиеся в базе после начала этой самой транзакции.
«Появились» — я имел в виду, что к примеру, во время вычислений появилась необходимость обработать документы, о которых раньше не было известно.

Пример: у пользователя есть право на определённое количество голосов. При обработке запроса-голоса, производится проверка его оставшегося количества голосов и голосовал ли он за этот документ уже раньше. Если обе проверки проходят, происходят некоторые вычисления, изменения у пользователя и у документа, создание новых документов (в очереди уведомлений например), и т.д. Если некто посылает пачку одинаковых параллельных запросов, есть вероятность, что сначала будет несколько успешных проверок, а потом несколько изменений, что приведёт к недопустимым данным. Cпособ с findAndModify, по идее, должен решить такую проблему?
Можно для пользователя userId хранить множество идентификаторов статей, за которые он проголосовал.
Дальше (в терминах MongoDB) делаем $push новой статьи в это множество для пользователя userId, у которого такой статьи ещё нет и общее количество статей не превосходит максимальное количество голосов от пользователя.
В случае невыполнения условий от Монго приходит null в качестве ответа.
Итого: один атомарный запрос.
Это всё в findAndModify по текущему юзеру, насколько я понял, хорошо. А если при этом надо проверить дату документа, за который он голосует?
Так хранить можно не сами статьи, а ссылки на них (в терминах MongoDB — ObjectId).
В смысле? Я не понял, причём тут ссылки (кстати, ссылки вроде рекомендуют делать DBRef-ом). Проблема в том, что бывают случаи, когда надо проверить условия, связанные с разными документами. Например, проверить состояние двух счетов, если один из них не меньше суммы, а второй не больше какого-то предела, то перечислить сумму. Или, например, при вступлении пользователя в группу, проверить максимальное число членов группы, флаг закрытия, а у пользователя — права на вступление в группы и ограничение на количество групп. Этого часто невозможно сделать атомарным запросом, даже если перелопачивать структуру данных на каждое такое нововведение.
Из моего опыта — такое часто возникает только тогда, когда структура придумывается в реляционных терминах. В противном случае сценарии, которые нельзя свести к атомарным операциям с документами, относительно редки.
Cache — целостность транзакции журналирование теневое копирование зеркалирование — всё есть — в ней есть даже SQL с объектами — но это только для тех кто не понимает не умеет не хочет или боится работать напрямую с деревьями (глобалами)
Не согласен с автором.

Раньше системы были сконцентрированны вокруг обработки данных. Сейчас — вокруг самих данных.
Когда речь идет о сложной расчетной задаче — да, представление данных дело десятое.

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

Сценарии использования этому ничуть не противоречат, это просто верхний этаж системы.
Вот только данные и система их хранения и доступа к ним — это разные вещи. И удобным представление и изменение данных должно быть для пользователя, причём именно в его сценариях использования, а не для системы хранения.
Скажите, а что подразумевается под термином «сценарии использования»?
Согласен. Глупо — после 11 лет в интернетах не погуглить перед вопросом. Спасибо.
бред какой-то. Что важнее, файлы видео твоих днейрождений за последние 15 лет или плеер который их играет?
А что важнее, содержимое видео или формат/контейнер, в котором оно хранится? База данных, это ведь не данные, это именно контейнер.
ага только это не только контейнер но ещё и связи между контейнерами — и недооценивать (как впрочем и переоценивать) важность этих связей не есть гуд — БД это транспортная система для данных и от её архитектуры зависит будут ли пробки при извлечении этих данных или будет хайвей без ограничения по скорости

баланс между содержимым и формой всегда надо поддерживать — а класть яйца в одну корзину и явно ставить во главу угла одно или другое — глупо
Так может проектировать приложение так, чтобы оно не зависело от транспортной системы? Будут пробки в текущей — поменяем на хайвэй. Почему нам должно быть важно привезут заказ из магазина по хайвэю или по просёлку, если его привезут вовремя?
проектировать приложение не зависящее от транспортной системы — это то же самое что проектировать интернет приложения не обращая внимания на протокол http

спроектируйте город не зависящий от транспортной системы — я в нём жить не буду — гораздо разумнее проектировать город и учитывать в том числе транспортную подсистему — не ставить её во главу угла не забывать о ней а учитывать и работать над ней (для села попроще — для мегаполиса посложнее)

нет независимости — в том числе и в проектировании — есть только баланс — и к нему надо стремиться — его надо чувствовать — а тупое бездумное деление на красных и белых, sql/nosql, БД/не БД — это детский сад
Сейчас широко распространена практика независимости приложения от HTTP, запрос ы и ответы инкапсулируется в объекты или другие структуры данных. Это, в частности, позволяет тестировать функциональность приложения не пользуясь веб-сервером и клиентами.

И речь, конечно, не о полной независимости, а от независимости от конкретной реализации транспортной системы. Оставили место под дороги, а что по ним будет грузы возить и из чего дороги будут сделаны — не суть (в разумных пределах, конечно, планировать прохождение океанских танкеров по улицам города будет перебором).
в определении «разумных пределов» — как раз собака и зарыта — это именно тот баланс о котором я говорю

а автор статьи всё же склонен к бездумному — «ты не снами — значит ты против нас»
После прочтения первой части статьи думал, что автор ругает реляционные БД и предлагает всем вернуться во времена хранения данных в файликах. Эта мысль конечно же бредова. Однако во второй части автор наконец раскрыл истинный смысл статьи — ценность проекта не в том, какую систему хранения он использует, а в реальной полезности, сценариях использования. Ведь его фирма загнулась не потому, что использовала хранения в файликах, а потому что слишком много думала над системами хранения, вместо того, чтобы решать бизнес-задачи и зарабатывать баксы.

Лично я воспринял это, как урок стартаперам, которые еще на этапе идеи начинают говорить, «а вот тут мы заюзаем MongoDB и у нас будет web scale, а там мы заюзаем Redis». Для технологических стартапов это актуально, но для остальных — нет. У основателей стартапов голова часто забита тем, какие фреймворки и системы хранения заюзать в новом проекте, вместо того, чтобы думать о пользе для конечного юзера, маркетинге и прочих бизнес-задачах.
habrahabr.ru/post/204392/
для тех, кто не в курсе, причём MongoDB к web scale — вот перевод «MongoDB is web scale»
Вот этот вот пассаж: «I watched as SQL slipped through every crack and crevice in the system. I ran screaming from systems in which SQL had leaked into the UI. I railed endlessly against the practice of moving all business rules into stored procedures. I quailed and quaked and ranted and raved as I read through entire mail-merge programs written in SQL.» (извините, что не перевод) — это аккурат то, что я чувствую и наблюдаю сейчас. Гигантская система, over 90% бизнес-логики которой находится в SQL. Поддержка этого похожа на непрекращающийся кошмар.

BTW, о переводе: mail-merge — это не почтовая рассылка, это подготовка данных для нее, причем сама рассылка может быть бумажной.
> Поддержка этого похожа на непрекращающийся кошмар.

А не расскажите в чем кошмар? Я вот подумываю один проект перевести на хранимки, что бы бегало быстрее. Да, я зык странноват и нет привычной IDE но язык хранимок достаточно мощный. Так в чем же проблемы? Может там у вас просто качество кода плохое?
«А не расскажите в чем кошмар?»
Нет контроля зависимостей, нет адекватного рефакторинга, нет build-time verification, очень сложно тестировать.

«Так в чем же проблемы?»
Перечислено выше. Добавьте к этому тот знаменательный факт, что управлять версиями кода на SQL-сервере тоже сложнее, и вы получаете замечательный локальный ад.

«Может там у вас просто качество кода плохое? „
Да, там плохое качество кода. Но чтобы оно было хорошее, нужно, чтобы было все вышеперечисленное, потому что залог качества кода — рефакторинг. А его нельзя адекватно делать без поддержки на уровне инструментов и тестирования. Замкнутый круг.
Когда лучше определиться с моделью данных? Когда вы знаете, какие есть объекты данных, как они связаны и как они используются. Когда вы это узнаете? Когда все сценарии использования и бизнес правила записаны и проверенны.

Макконнелл бы не согласился. Написание кода не имеет никакого отношения к проектированию. А проектирование предшествует кодированию.
В цитате нет ничего про код.
Существуют другие точки зрения, например в XP методиках проектирование скорее пост-фактум в виде рефакторинга, чем перед кодированием.
Почему-то не забывается такой аспект как сложность рефакторинга баз данных. Изменить алгоритм обработки ничего не стоит, изменение модели данных тянет за собой груз всех накопленных до этого данных.

Понятно, что пока данных нет, ставить БД во главе угла нет особого смысла, но как только продукт подходит к релизу — модель данных надо фиксировать и проверять на расширяемость.

Модель данных — это как public API. После того, как она была запущена в жизнь любое изменение обходится очень и очень дорого.

Рефакторить базу данных так же легко, как и код, если не легче. Но вы правы, если БД работает, то рефакторить сложнее — не откуда брать данные, в случае, если они не фиксировались. Но а откуда брать данные, если рефакторить код с т.з. таких же измененний? Допустим, не держим реляционную БД. То же самое. Чудес не происходит, информацию родить нельзя.

Реляционная БД тем и хороша, что в ней более наглядно видны такие проблемы. И легко моделируется предметная область. В определенных пределах.

Проблема автора, по моему мнению, что он БД рассматривает, как нечто связанное с реализацией, нечто второстепенное. Так никто ж и не заставляет писать кривую схему непонятно чего. Если в БД моделировать предметную область (т.е. всем понятно — таблицы — сущности или связи и т.д.), то никаких проблем с юз-кейсами, от которых отталкиваться проектирование и разработка должны — нет.
Зачем в БД моделировать предметную область? Может лучше смоделировать предметную область, а потом отобразить её на БД (или любое другое хранилище)?
БД для этого хорошо подходит. А чем лучше смоделировать ее в коде, а из БД делать хранилище?

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

Реляционная БД позволяет как бы создать зависимости между данными другим (не ООП) способом. Но этот способ жестче — дает возможность применять реляционную алгебру. При этом, данные можно представить, как некий н-мерный куб. Это дает возможность обобщать. Видеть упущенные требования.

Ограниченния реляционной БД — это как статическая типизация. Если в коде вы для переменной ставите целочисленный тип, зная, что это будет счетчик, то не жалуетесь, что тип ограничен и не позволит вам в будущем там хранить число с плавающей точкой. Схема БД — это такая типизация, где на уровне схемы будет проверяться взаимосвязь с данными. И на уровне схемы выражается практически вся предметная область, еще без строчки кода.

Хотя, бывает, конечно, не всё можно выразить, но многое. Зачем же упускать такую возможность. А гибкость кода — это возможность багов.
Возможность формально все описать — это палка о двух концах. Так же как языки со статической типизацией и динмической: одни дают строгость, другие гибкость. Как видите никто еще не победил в этой вселенской битве строгость vs гибкость (waterwall vs agile, static typing vs dynamic typing, etc). Победителя и не может быть. Все зависит от требоний более выского порядка вроде бизнес-модели.
В РСУБД плохо моделируются иерархические и/или рекуррентные системы, системы с произвольными атрибутами и т. п., а такие задачи сплошь и рядом. Да банальное отношение многие-ко-многим уже не тривиально реализуется, требует введения дополнительной таблицы, которая на предметную область никак не отображается.

Выразить-то можно многое, но далеко не всегда это будет естественным и/или эффективным варажением. Я согласен с автором, что роль SQL РСУБД переоценена, они выступают в роли «серебрянной пули», разработчики зачастую выбирают не как хранить данные, а в какой SQL РСУБД их хранить, даже не задумываясь о целесообразности использования именно SQL РСУБД. Доходит до того, что настройки приложения хранят в базе данных.
«В РСУБД плохо моделируются иерархические и/или рекуррентные системы»

Насколько я понимаю, моделируются просто, работают СУБД с такими вещами неэффективно. SQL плохо подходит.

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

Системы с произвольными атрибутами реляционно не реализуются. Но не согласен, что такие задачи сплошь и рядом. Представьте себе систему, написанную на объектно-ориентированном языке без БД. Аналог этой задачи — вы не знаете во время компиляции, сколько и какого типа полей у объекта будет. И вы будете формировать тип в рантайме. Еще тот фокус. Иногда надо. Но или на динамических языках пишут или просто пишут классы, которые будут потом атрибутами другого класса в списке, а им добавляют тип, который что-то вроде перечисления. Т.е. фактически не пользуются уже типизацей языка, а выворачивают его так, чтобы создать собственную динамическую типизацию.
Точно таким же хаком и в реляционной БД поступают, если такое нужно.
ох…

Системы произвольными атрибутами реляционно реализуются. Легко и непринуждённо. Равно как и обработка иерархических данных. РСУБД потому и завоевали мир 30 лет назад — они были тупо удобней в большинстве задач чем иерархические БД коими по сути являются все эти NoSQL.
Вы не поняли. Я подразумевал, что честно реляционным способом не реализуются.
А завести табличку с называнием Attribute и с колонками что-то вроде Name, Value, Type можно.
Или делают денормализацию — лишние колонки, которые пользуют, как захочется потом и сколько надо. Или делают табличку, в которой общий тип текстовый или какой-то, которые приводят потом к чему хотят.

По сути, это подобный хак, как и в ООП (шарп, джава) со статической типизацей был бы. Просто в языках таких всё на хаках, кругом императивщина. Поэтому там не так заметно, когда язык выворачивают. Создают новое свое измерение для типизации.
Дада, реляционщики поступают бесчестно. Читят.

Повторюсь

РСУБД потому и завоевали мир 30 лет назад — они были тупо удобней в большинстве задач чем иерархические БД коими по сути являются все эти NoSQL.
да я ж только за. Наоборот защищаю реляционные БД
«Рефакторить базу данных так же легко, как и код, если не легче.»
Ась? Предположим, у нас есть _самая простая задача_ — нам надо переименовать объект (скажем, таблицу). Предположим также, что у нас идеальный случай, и БД не используется для интеграции (т.е., она не является публичным контрактом, потому что в этом случае мы обречены). Внимание, вопрос: какой инструмент позволит мне найти _все_ упоминания этого объекта в (а) коде самой БД (б) коде соседних БД (ц) прикладном коде, автоматически их изменить, а потом проверить на уровне компиляции кода, что ни одна ссылка не потерялась?

Альтернативный ход: есть два представления, одно использует другое, я подвинул часть логики из одного в другое (типичный рефакторинг). Какой инструмент позволит мне покрыть это все изолированными тестами, чтобы быть уверенным, что мои изменения ничего не повредили?
таблица это не объект. Даже не рядом. Задача поставлена неверно. Хотя анализ всех упоминаний определённой таблицы во всех процедурах и всех определениях делается одним запросом.

тесты кода к базе данных неприменимы. Там же описание связей и сущностей а не императивный язык типа с++. Если в описании таблицы стоит связь с родительской таблицей то никогда и ни при каких условиях неверное значение туда не попадёт. Это гарантируют SQL серверы и сотни человеко-лет их разработки. А вот тесты программы которая обращается к данным пишут. И тут эти тесты ничем не отличаются от любых других случаев.
«таблица это не объект»
Не объект БД? Интересно, почему.

«Задача поставлена неверно»
Что в этом неверного? Это типовая задача при рефакторинге БД.

«Хотя анализ всех упоминаний определённой таблицы во всех процедурах и всех определениях делается одним запросом.»
Замена тоже?

«Там же описание связей и сущностей, а не императивный язык типа с++»
И вы мне хотите сказать, что никогда не видели БД, в которой были бы не только сущности и связи, но еще и код: представления, хранимые процедуры, функции, триггеры?

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

«Если в описании таблицы стоит связь с родительской таблицей то никогда и ни при каких условиях неверное значение туда не попадёт. Это гарантируют SQL серверы и сотни человеко-лет их разработки. „
Да-да. Ссылочная целостность, я слышал. Между двумя БД, говорите? Не работает.

И это все только при условии, что у вас изначально правильно построена БД. А вот если вы при проектировании какое-то ограничение пропустили, а теперь пытаетесь его наложить — а это рефакторинг — то ваша жизнь будет намного сложнее.
Вопрос только в инструменте?

Сам подход — моделирование в БД ничем не хуже моделирования в шарпе. Даже лучше иногда. Чем код создания таблиц и связей так плох по сравнению с другим языком? Если вопрос только в инструменте — то это мелко. Я не базовик, там есть разные не известные мне инструменты.
ERwin например. Базовики пользуются и хвалят. Не знаю его возможностей.

VS-2010 имеет тип проекта для работы с MS-SQLSERVER. Прямо переименовываниями не вижу, чтобы занималась, но она имеет возможность делать «билд», т.е. проверить всё. А значит покажет, что что-то потерялось в случае переименования.

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

Потом, не было в наличии средства для тестирования кода БД. Существующий проект, когда пришел, многое реализовывал в хранимках. Вижуал студия позволяет писать тесты, но не на той версии, которую в конторе позволили купить. Так и написать движок для тестов заняло тоже в районе нескольких часов.

Инструменты — не такая уж проблема. Завязываться на них, выбирая технологию, не стоит. На прошлой работе, например, базовику не нравился синтаксис TRANSACT-SQL. Он прикрутил препроцессор С. Свободный. И там понаписывал макросы подмены, в результате писал на более удобном для себя синтаксисе. Циклы и ветвления похожи на С были.

Потом, при отсутствии инструмента можно вполне без проблем построить даже самому разворачивание базы из скриптов. Билд-сервер настроить. И там уже как хотите — переименовывайте. Сделаете анализатор.
Конечно, сделать полный парсер SQL сложно. Но анализ связей вполне можно. И поиск по вхождению слова без проблем. А на запросы написать тесты тоже можно.
«Вопрос только в инструменте?»
Вопрос в философии. Когда мы меняем код, мы меняем алгоритм. Когда мы меняем базу, мы меняем уже существующие данные.

«Чем код создания таблиц и связей так плох по сравнению с другим языком?»
Смотря для чего.

«VS-2010 имеет тип проекта для работы с MS-SQLSERVER. Прямо переименовываниями не вижу, чтобы занималась, но она имеет возможность делать «билд», т.е. проверить всё. А значит покажет, что что-то потерялось в случае переименования.»
Вы с ним работали? Я работал. Никакого «билда» в смысле компиляции там нет, тамошний «билд» — это расчет скриптов изменений.

«Инструмент написать можно быстро.»
Почему его до сих пор нет?

«Имена таблиц, как уже сказано, не имеет смысла покрывать тестами. „
То есть у вас никогда не было ошибок из-за того, что таблицу переименовали, а использующий ее код (не важно, в БД или в приложении) — не поправили? У меня были.

“Так и написать движок для тестов заняло тоже в районе нескольких часов.»
Интересно, как ваш «движок» изолирует тестируемый код от его зависимостей.

«Завязываться на них, выбирая технологию, не стоит.»
Не стоит? Ну если для вас двух-трехкратная разница в производительности работы сотрудника не стоит выбора технологии, то я даже не знаю, что его стоит.

«Потом, при отсутствии инструмента можно вполне без проблем построить даже самому разворачивание базы из скриптов. Билд-сервер настроить. И там уже как хотите — переименовывайте.»
Угу. Спасибо за предложение заниматься интеграционными тестами. Проблема в том, что это — дороже, чем изолированные.

А вообще, ваш пост — хорошая демонстрация того, почему базу рефакторить не так же просто, как и код. Потому что «напишите, напишите, напишите, настройте». А для кода уже все есть. Поэтому — рефакторинг и разработка на уровне БД _сложнее_. Не невозможна, нет. Просто сложнее и дороже.

Я вижу это каждый день, имея возможность сравнить стоимость типичных рефакторингов в .net-команде и sql-команде. Во второй их практически нет.
«Вопрос в философии. Когда мы меняем код, мы меняем алгоритм. Когда мы меняем базу, мы меняем уже существующие данные.»

Конечно. Если бы у вас не было БД, а вы хранили данные в файлах, например. И писали только на шарпе (или джаве и т.д.). Такой идеал, как автор предлагает. И запустили систему в продакт. А потом нужен рефакторинг кода. Упс — та же проблема. Если информация утеряна, ее из космоса получить невозможно.
Даже если у вас проект с БД и вы выкатили в продакт, а потом рефакторите код, и он затрагивает объекты, которые уже хранятся в БД — та же проблема. Потеря данных.

Если же вы не выкатывали ничего в продакт, а находитесь как положено на этапе разработки системы, то рефакторить можно и то и другое.
Алгоритмы работают с данными. Если у вас такой случай, что не надо трогать данные — то отлично, рефакторите без проблем. А если надо, то СУБД в этом не виновна. Эти проблемы будут всё равно.

«Вы с ним работали? Я работал. Никакого «билда» в смысле компиляции там нет, тамошний «билд» — это расчет скриптов изменений.»
немного. Я «олдскульный». Всё скриптами пользуюсь ))
Но «билд» — замечательная вещь. Конечно, там нет компиляции, потому что и не может для SQL-SERVER компиляции. Для скриптового языка. Но расчет скриптов изменений — это то, что нужно. Он позволяет указать любые ошибки. Вот как раз проверить все запросы на предмет соотвествия именам таблиц и колонкам.

«Интересно, как ваш «движок» изолирует тестируемый код от его зависимостей»
Тестовый движок, это отдельная база данных. Состоит из нескольких несложных хранимок. Сам тест — хранимая процедура. Этому движку указывается, к какой базе данных нужно приконектиться. И она вытягивает в свою базу требуемые для теста таблицы (пустые, только структура), хранимки, функции и т.д.
Тест начинается с указания какие таблицы нужны. Далее заполнение тестовыми данными. И прогон тестов.
Всё просто. На самом деле кода не много. А развязка от тестируемой базы неплохая. Тесты это хорошо выручают.
Но тесты эти тестируют только код. Например, зависимости между таблицами не вытягиваются. Декларативную часть бессмысленно тестировать.

«Не стоит? Ну если для вас двух-трехкратная разница в производительности работы сотрудника не стоит выбора технологии, то я даже не знаю, что его стоит»

Конечно, важна производительность сотрудника. Я только говорю о том, что часто переоценивают проблемы. Эти проблемы решаются разово и тратится на них время не такое большое. Программисты мы или кто? У нас в конторе например, выбирали ORM и боялись, что в некоторых вариантах не генерировались классы по БД. Объяснил как, и дело пошло. Людям казалось, что это сложно. А оказывается, совсем нет.

«Угу. Спасибо за предложение заниматься интеграционными тестами. Проблема в том, что это — дороже, чем изолированные.»

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

«А вообще, ваш пост — хорошая демонстрация того, почему базу рефакторить не так же просто, как и код. „

Тут другая тема есть. Кода на СУБД меньше. Следовательно и рефакторинг в этом плане будет проще. Если данные потеряны, то сложно будет и в слое над БД. Если нет, то рефакторинг в БД не сложный. Даже не знаю, как кратко описать. О рефакторинге кода писал Фаулер. Там всё строится почти на выносе метода или выносе класса. В БД — вынос сущности (не только это, конечно, но чаще всего). Была колонка, стала отдельной сущностью. Всё это — декларативное описание. Как по мне, и работы меньше.

“Я вижу это каждый день, имея возможность сравнить стоимость типичных рефакторингов в .net-команде и sql-команде. Во второй их практически нет.»

я и sql-команд не видел. Мало из базовиков вообще с программированием нормально знакомы. А уж с понятием рефакторинга или юнит-тестов, тем более. Это проблемы профессионализма, которые остро стоят в нашей отрасли. Берем тех, кто вообще что-то может.

«Если же вы не выкатывали ничего в продакт, а находитесь как положено на этапе разработки системы, то рефакторить можно и то и другое. „
К сожалению, очень многие сегодняшние системы постоянно находятся в продуктиве. Поэтому никакого “как положено на этапе разработки» не будет.

«А если надо, то СУБД в этом не виновна. Эти проблемы будут всё равно.»
Я всего лишь говорю, что рефакторить БД — не важно, какую, хоть файловую — дороже, чем рефакторить код. Вот и все.

«Но расчет скриптов изменений — это то, что нужно. Он позволяет указать любые ошибки.»
_указать_ — возможно. Но сам он их не находит.

«Вот как раз проверить все запросы на предмет соотвествия именам таблиц и колонкам.»
Вот только он этого не делает. Особенно для сторонних БД.

«Тестовый движок, это отдельная база данных. Состоит из нескольких несложных хранимок. Сам тест — хранимая процедура. Этому движку указывается, к какой базе данных нужно приконектиться. И она вытягивает в свою базу требуемые для теста таблицы (пустые, только структура), хранимки, функции и т.д.
Тест начинается с указания какие таблицы нужны. Далее заполнение тестовыми данными. И прогон тестов.
Всё просто.»
Занятное решение. Но очень медленное, к сожалению.

«Декларативную часть бессмысленно тестировать.»
Расскажите это разработчикам декларативных DSL. Тестировать осмысленно все.

«Эти проблемы решаются разово и тратится на них время не такое большое. Программисты мы или кто?»
Вы оптимист. Мы вот (простую) проблему версионирования БД решаем который месяц.

«Кода на СУБД меньше.»
Это если вам повезло.

«Если нет, то рефакторинг в БД не сложный. Даже не знаю, как кратко описать.»
А зачем описывать, по этому поводу отдельная книжка есть. И там очень неплохо видно, насколько это сложнее рефакторинга кода.

«Была колонка, стала отдельной сущностью. Всё это — декларативное описание.»
Ага. Очень просто. Теперь пошли и проапдейтили (вручную, потому что автоматических инструментов нет) все, что эту колонку использовало. Потом прогнали интеграционные (и выше) тесты, и через неделю нашли код, который не заметили на первой фазе.

Сравнить с Ctrl-R, R в решарпере — и хочется плакать.

«я и sql-команд не видел.»
Оно и заметно, простите за прямоту.
«Занятное решение. Но очень медленное, к сожалению.»

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

Да самому стыдно за движок — велосипеды сочиняю :)) Но какого-то готового решения не нашел. Может плохо искал. Майкрософтовский вместе со студией стоит дорого. Не захотели на каждого разработчика покупать такую версию студии.

Здесь описал движок, как пример, что при отсутствии инструмента — не так сложно его сделать.
Модель данных и схема БД вещи вообще говоря не связанные. Эта связь прячется или в модели (ActiveRecord) или в отдельной системе (DataMapper) и легко модифицируется как раз алгоритмами.
Определенно автор троллит.

Было бы еще так же интересно почитать статьи «не ФС», «не Сборщик Мусора», «не Виртуализация», «не Веб». Определенно найдется не мало задач, где эти технологические компоненты не нужны, но используются.
Я бы посмотрел на автора, когда количество записей измеряется в миллионах. Очень было бы интересно как бы он искал и исправлял ошибки:)
Миллион записей одного типа — легко. А вот если есть сотня-другая сущностей, между которыми нужно поддерживать ссылочную целостность и так далее, то вот тут РСУБД как раз то, что доктор прописал. Но нужно подумать, такие ли мы приложения разрабатываем каждый день? На РСУБД делают сайтики из 5 страниц — а вот это полный маразм и торжество маркетоидов, о чем и пишет автор.
Я согласен с автором с тем, что существует монополия БД на отправную точку проектирования. Однако не соглашусь с тем, что отправной точкой должны быть сценарии использования. Это нечто иное, как разработка bottopm-up, то есть от частного к общему. Все таки лучше начинать с доменной модели. Разработка от юз-кейсов — это верный путь сделать приложение как на третьей каринке: ilyasemin.com/wp-content/uploads/2012/02/googleproduct.jpg
Ну, Ябл-и-Гугл реально настолько крут, чтоб иметь моральное право навязывать тупым юзерам своё видение того, что такое Щастье… А вы — нет. Поэтому он может позволить себе делать интерфейс не как на третьей картинке. А вы — нет.
Автор, ИМХО, как-то лукавит.

БД, конечно, не главное. Главное — persistance.

БД — это способ решения persistance. Проверенный, надежный, с языком запросов и пр.

Если кто-то вдруг придумает что-то лучшее (т.е. более мощное, но более простое в использовании) для решения persistance, то это решение заменит БД.

Но что-то пока ничего не заменило…
Да правильно ругают. =) Берут какой нить ФИАС и пихают в SQL… «потому шта БД! связи! целостность!» Ага щас. Гораздо проще держать некую иерархию в файлах…
Стиль написания статьи слишком уж категоричен. Как можно отказаться от SQL в ERP, CRM, подобных системах? Почему нужно отказываться от администраторов БД?
Если в проекте ценность данных невелика, то только в этом случае можно считать идеи автора условно-верными. Но делать общие выводы о том что SQL вредна на примере частного случая, да еще и редкого (низкая ценность данных) — это просто глупость.
1С-Предприятие 7.7 прекрасно обходится без SQL.
Совсем нет! там язык запросов — это SQL без DDL и возможности манипулирования данными.
Во-первых, 1С 7.7 прекрасно работает в файловом варианте, без SQL DB. И при этом есть и транзакции, и контроль целостности, и многое другое, включая язык запросов, который нифига не SQL.

Во-вторых, содержимое файловой базы можно перенести на MSSQL без каких-либо доработок и усилий.
я и не говорил что 1С 7.7 зависима от SQL.
1С 7.7 сама по себе предоставляет SQL и язык запросов у неё самый настоящий SQL, хоть и ограниченный по сравнению с классическим SQL. А курсоры с возможностью манипулирования данными у неё только программы на внутреннем языке.
Возможно, вы путаете с 1С 8.х, в которой язык запросов действительно SQL с некоторыми ограничениями.
несовсем. В 7ке менее очевидно, но тоже SQL. правда вместо AS там знак =, нет явных джойнов и т.п. это не отменяет того что там структурированный язык запросов.
Хорошо, будем считать встроенный язык запросов разновидностью SQL. Но вернемся к исходному утверждению, что в можно запросто обходиться без этого языка запросов. Будем спорить? =)
Чисто теоретически — можно. Но это будет очень не эффективно. А в некоторых случаях чудовищно не эффективно. Платформа (в результате просчёта) предполагает(даже принуждает) для выборки данных использовать Запросы а для их изменения — объекты.
В файловом варианте выборки работают быстрее запросов. В MSSQL-варианте запросы быстрее. Но в целом эффективность примерно одинакова. Чудовищная разница только при экстремальной оптимизации — использовании прямых запросов к MSSQL.
Всё, я понял о чём мы спорим :).
Я говорю о клиенте платформы = конфигурации.
А вы про хранилища, доступные платформе.
В таком случае мы оба правы.
Просто 1с логичнее рассматривать именно как платформу.
Вам не кажется, что БД-подход очень хорошо, даже слишком хорошо, коррелирует с ООП-подходом?
А " Вам не кажется, что Не БД-подход очень хорошо, даже слишком хорошо, коррелирует с ООП-подходом?"
Ведь он детали реализации БД части оставляет «на потом». А главное внимание обращает на юз-кейсы.
Не кажется: и в ООП и в БД всё вертится вокруг «хреновин со свойствами». Строка в БД — это, пожалуй, одно из лучших отражений объекта реального мира.

Не-БД будет лучше коррелировать с не-ООП.
Чушь.

А второй абзац — отличнейшая тема для статьи на хабре.
Строка в БД

Давайте определимся, о каких именно БД идет речь.

Если вы говорите о «строках», то видимо вы имеете в виду реляционные базы данных, а под понятием «строка» вы подразумеваете так называемую запись в таблице, что вообще говоря тоже не совсем верно с точки зрения теории, но, по крайней мере, уже ближе к истине, чем абстрактное выражение «строка в БД».

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

Конечно, мы можем обратить свой взгляд в сторону объектно-ориентированных баз данных, которые были придуманы для хранения объектов, с их аттрибутами и методами. К сожалению, понятие «строка», применимо к объектам, в теории таких БД отсутствует (если только в качестве типа данных для аттрибута).

Конечно, вы можете еще вспомнить про объектно-реляционные базы данных, да только боюсь в них «строка» тоже хреново отражает объекты реального мира.
Да, «строка» = «ряд» имелась в виду в таблице БД. Способы взаимодействия с объектами (=их взаимоотношения) и множественные свойства, как и прочие отношения многие-ко-многим моделируются через таблицу пересечений. Если это делать с нормализацией, многое по мере проектирования проясняется.

Для объектно-ориентированных баз данных, если для них есть понятие «класса», и методы есть только у класса, расклад не должен сильно отличаться от реляционных БД. Объект в такой базе хорошо соответствует ряду в таблице РСУБД.
Боюсь, что ваш уровень знания теоретических основ баз данных еще ниже чем мой, и очевидно не позволяет вам вести дискуссии на такие совершенно не прикладные темы, как уровень корреляции ООП подхода с реляционной моделью хранения данных.

На ваш комментарий могу ответить, что, очевидно, да, используя реляционные СУБД вполне возможно хранить объекты со всеми их свойствами, и очень многие так и делают, и да, нормализация позволяет сделать структуру данных проще и понятней.

Но! Способы взаимодействия с объектом (то есть т.н. методы) в реляционных СУБД вообще нереализуемы (ну, можно конечно попробовать извратиться на триггерах, и даже извращаются, но это очень слабо коррелирует с ООП-подходом).

Хранение данных об 1 объекте в десятках таблиц, с использованием промежуточных и т.д. — это никак не похоже на ООП-подход, когда объект инкапсулируется внутри себя.

Наследование данных — как вы это представляете себе в случае с РСУБД? Полиморфизм? Систему прототипов?

Максимум, для чего подходит РСУБД — это сохранить какое-то фиксированное состояние объекта, при этом работать с этим объектом практически невозможно без наворачивания вокруг нее дополнительных программных слоев, типа Active Record, ORM или еще чего-то.
У меня создание нового класса идет примерно так:
data::$structure['tovar']['table'] = 'tovar';
$structure = new dummyArray();
$column = new dummyArray();
$column->name = 'id';
$column->desc = 'Номер';
$column->type =  'auto';
$column->default = 'Автомат';
$structure->id = $column;
$column = new dummyArray();
$column->name = 'name';
$column->desc = 'Название';
$column->type =  'string';
$column->default = '';
$structure->name = $column;
$column = new dummyArray();
$column->name = 'cat';
$column->desc = 'Категория';
$column->type =  'select';
$column->option = array('free'=>'Бесплатный','profi'=>'Профессиональный','none'=>'Никакой :)');
$column->default = '';
$structure->cat = $column;
$column = new dummyArray();
$column->name = 'desc';
$column->desc = 'Описание';
$column->type =  'text';
$column->default = '';
$structure->desc = $column;
data::$structure['soft']['structure'] = $structure;
data::$structure['soft']['subtable'] = 'comment,photo,pricelist';
data::$structure['soft']['access']['create'] = 'manager';
data::$structure['soft']['access']['read'] = '*';
data::$structure['soft']['access']['update'] = 'manager';
data::$structure['soft']['access']['create'] = 'admin';

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

Как мне кажется тут вполне ооп-шное решение.
Но с наследованием да, лажа пока… У каждого класса все равно своя таблица выходит, и под задачи «найти все объекты насследующие от класса document с датой создания ххх и автором ууу» к родителю не обратишься, а надо будет как-то шаманить… Но это частности.
наследованием да, лажа пока

даже слишком хорошо, коррелирует с ООП-подходом

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

С моделью тоже есть решения, но они мне не нравятся тем, что задачи такие бывают редко, а нагрузку на систему будут давать всегда… Самое очевидное это отличия присоединять как один к одному через join но это понятно почему пошло… второе решение — сообщать родителям кто их наследует, тогда можно через union брать все данные из дочерних таблиц. Учитывая что такие запросы редки, проблем не вижу особо…

Тут вопрос производительности больше и целесообразности а не реализуемости…
habrahabr.ru/post/145061/#comment_5315053

Да, и наличие у объектов сложных методов и наследование — это в значительной мере tight coupling (многие теоретики по части ООП пишут о необходимости предпочитать агрегацию наследованию), и, поэтому, bad style.
Способы взаимодействия с объектом (то есть т.н. методы) в реляционных СУБД вообще нереализуемы
А там надо что-то сложнее геттеров и сеттеров, т.е. процедур и функций, в которых все аргументы — примитивного, а не объектного типа? А то потом возникает проблема, к какому объекту отнести метод — типа перевода со счёта на счёт — к тому куда переводят, к тому с которого переводят или вообще к сумме (валюта + количество)? Так постепенно логика выносится в «менеджеры» с методом перевестиСумму(Сумма сумма, Счёт с, Счёт на), они же «визиторы» (если по глупости уcпели создать метод (Счёт с).перевестиСуммуНа(Сумма сумма, Счёт на) или (Счёт на).пополнитьСоСчёта(Сумма сумма, Счёт счёт) или (Сумма сумма).перевести(Счёт с, Счёт на) в одном из классов-участников). Если логику «менеджеров» приходится менять, то «менеджеры» «объинтерфейсиваются», чтоб можно было легко менять реализацию.

Так что вместо методов лучше сразу делать доменные функции и доменные процедуры.

Хранение данных об 1 объекте в десятках таблиц, с использованием промежуточных и т.д. — это никак не похоже на ООП-подход, когда объект инкапсулируется внутри себя.
Хранение данных об одном объекте в десятках классов со сложным управлением обратными сссылками — это сильно проще (на счёт инкапсуляции см. в т.ч. выше про «методы»)?

Наследование данных
1) Через constraints и FK (ну да, придётся ещё триггер на вставку делать) 2) В PostfreSQL и так есть.

Полиморфизм
Это, в общем, заимствование из функциональных языков программирования. Изврат на тему косвенного вызова функции — типа вызва функции в С по указателю, только безопаснее. Если нужно, можно нагородить что-то типа CLOS, но по отношению к «персистнутым» в БД данным.
Sign up to leave a comment.

Articles

Change theme settings