Профессор сказал нам хранить сериализованные объекты Java в виде BLOB-объектов вместо определения реляционных таблиц.


21

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

id (int)  |   Serialized Object (blob)
   1               10010110110

Я вижу так много проблем с этим; избыточность данных, необходимость отслеживать идентификаторы отдельно, необходимость извлечения всей таблицы в память для поиска чего-либо, и ** если я захочу изменить свою модель в коде Java, я больше не смогу десериализовать большой двоичный объект, хранящийся в База данных в эту модель.

Либо я навсегда застрял с этой моделью, либо мне нужно сделать еще кое-что действительно уродливое, чтобы изменить свою модель. ** Все это кажется мне дурным тоном. Я оправдан в несогласии с моим профессором? Есть ли какая-то польза от этого, о которой я не думал? Если я прав, я должен сказать что-то своему профессору по этому поводу? Он проповедовал это всему моему классу и даже сказал, что он строил проекты таким образом. Второе мнение было бы здорово.

Курс называется Software Design .

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

Модель не является динамичной в любом случае.


Комментарии не для расширенного обсуждения; этот разговор был перенесен в чат .
Пол Уайт говорит GoFundMonica

Ответы:


34
  1. Само по себе это совсем не плохо. Спорить о том, «что лучше» без надлежащего контекста (= точные требования) - бесполезное упражнение.

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

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

- редактирование, после прочтения других ответов.

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

Поскольку все обсуждение должно быть о конкретных проблемах (иначе мы не можем даже определить «лучше» и «хуже»), позвольте мне привести один конкретный пример. Это полностью выдумано, но я попытался раскрыть как можно больше деталей.

Представьте, что у вас есть сайт онлайн-игр с базой данных, в которой хранится статистика игроков в различных онлайн-играх (игра в браузере, запись в GWT и кросс-компиляция в javascript). Некоторые игры являются стратегическими, некоторые - экшенами, некоторые - платформерами. База данных является реляционной и хранит игроков и историю игр и счет.

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

Теперь у вас есть два основных варианта:

  • Поскольку игры написаны на Java, вы можете легко взять модель, отправить ее на сервер, сериализовать ее в одну строку кода и сохранить в виде большого двоичного объекта. Таблица будет называться «сохраненные_игры» и будет иметь внешние ключи для игрока и так далее. С точки зрения базы данных «игра сохранения» - это непрозрачный, неделимый шарик.

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

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

Кроме того, у меня есть догадка, что Джастин Кейв считает, что то, что я представил выше, является «крайним» или «редким» случаем. Я считаю, что если он не сможет представить какие-то точные данные (основанные на репрезентативной выборке всех ИТ-проектов в мире, а не только, скажем, корпоративных приложений в США), я буду считать такое мнение классическим случаем прогноза. смещение.

На самом деле проблема сериализованных объектов Java в реляционной базе данных гораздо глубже, чем кажется. Это касается самого ядра 1NF, а именно, что является доменом атрибута? , Если вы действительно интересуетесь этой темой, есть отличная статья CJ Date в его « Date on Database: Writings 2000-2006» .


Комментарии не для расширенного обсуждения; этот разговор был перенесен в чат .
Пол Уайт говорит GoFundMonica

22

Могут ли (и делают) люди успешно реализовывать проекты, которые делают подобные вещи? К сожалению, да, они делают это достаточно часто.

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

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

Есть ли преимущества у этого подхода? Полагаю, вы можете утверждать, что реализовать первую версию приложения довольно просто. И это позволяет разработчику полностью игнорировать все, что связано с правильным взаимодействием с базой данных. Я с трудом представляю себе множество случаев, когда эти преимущества перевешивают многочисленные недостатки подхода.

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


2
То, что вы сказали, плюс мои два цента. Возможность повторного использования - это модульность и совместное использование. Объектная модель фокусируется на совместном использовании объектов и повторном использовании кода. Модель базы данных фокусируется на совместном использовании и повторном использовании данных. Ни одна модель не является полностью дебильной. Ни одна модель не является совершенством. И очень, очень трудно примирить их.
Уолтер Митти

1
Я согласен с этим, но мне неприятно, когда профессор преподает что-то и говорит, что это лучший способ, не сталкиваясь с этим. Как насчет всех других бедных учеников, тех, кто отправится в реальный мир, думая, что это правильный путь?
Кевин

Конечно. Эта формулировка сводится к объектам, притворяющимся данными. И это данные, но не очень полезные данные.
Уолтер Митти

Преимущество почти всегда исчезает, как только вы захотите выпустить v2 вашего приложения.
Энди

10

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

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

Есть ли какая-то польза от этого, о которой я не думал?

Хранение сериализованного объекта означает, что вы можете хранить данные без схемы (обратите внимание, что, несмотря на название, схема без схемы обычно не означает, что на самом деле схемы вообще нет, а есть только неявная схема). Существует много проблемных областей, в которых вы не можете заранее определить схему во время разработки, и если следование традиционному дизайну реляционной базы данных будет означать, что вам придется изменять схему базы данных каждую вторую неделю или в итоге вы получите таблицу с 80% столбцов, которые не используются в 80% случаев, или сотни разных таблиц для хранения действительно одинаковых данных, ни один из которых не указывает на хороший дизайн. Корень этой проблемы обычно в том, что вы принудительно встраиваете нереляционную проблемную область в реляционную базу данных.

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


7

Я делал это раньше - его полезная техника в определенных сценариях, однако, зависит от используемого формата сериализации. Если я делаю это, я проверяю, что я использую формат сериализации, который позволяет мне десериализовать более старые версии моей модели (например, XML).

Обычно я использую это в сценариях, где формат данных приводит к сложной реляционной модели, которая не дает никаких преимуществ (например, когда бизнес-требования не требуют какой-либо фильтрации и т. Д.), И я уже использую базу данных (для другие реляционные данные). Одним из таких случаев было приложение, которое имело пользовательские запросы - реляционная модель имела несколько таблиц для хранения таких вещей, как условия, вложенные условия (OR / AND и т. Д.), Параметры сортировки и т. Д. ... Это было довольно сложно, и когда нам нужно было добавить новую функцию, которая требовала изменения в базе данных. Я заменил все это одной таблицей запросов с сериализованным большим двоичным объектом, представляющим все остальные параметры.

Еще один случай - система, которая обрабатывает различные «задания». Было несколько разных типов заданий, и у каждого задания были разные параметры, без каких-либо бизнес-требований для возможности поиска / фильтрации заданий на основе этих параметров. Хранение этого в виде реляционной базы данных потребовало бы как минимум 1 новую таблицу для каждого типа работы, что затрудняет добавление новых типов работы. Вместо этого параметры хранятся в виде большого двоичного объекта в базе данных - каждый тип задания отвечает за сериализацию и десериализацию своих параметров.

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


6

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

Подход сериализации целого объекта в BLOB-объект не так возмутителен, как думает большинство людей. На самом деле, для некоторых приложений это может быть лучшим дизайном, который вы можете сделать, как я объяснил здесь: /programming//a/12644223/1121352 .

Действительно, сериализация объекта приводит как минимум к двум преимуществам:

1. Сокращение несоответствия импеданса : некоторые типы Java просто не доступны в SQL, особенно если вы используете много классов и пользовательских типов, поэтому преобразование объектов Java из SQL в SQL и обратно может быть огромной проблемой и даже привести к неоднозначности.

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

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

Однако вы можете получить лучшее из обоих миров, если тщательно спроектируете свою базу данных: вы все равно можете установить реляционную схему (т.е. столбцы уникальных ключей), используя атрибуты, уникальные для каждого объекта, и затем сохранить объект в BLOB-объекте. , Таким образом, вы все равно можете обеспечить быстрый поиск вашего объекта с помощью некоторого уникального идентификатора, который определяется атрибутами вашего объекта, также уменьшая избыточность, в то время как вы устраняете несоответствие импеданса и сохраняете полную гибкость объектов Java.

Напомним, что некоторые производители БД предприняли несколько попыток смешать реляционную и объектную модели, например, тип данных JSON в PostSQL и PostgreSQL, чтобы вы могли напрямую обрабатывать JSON, как любой реляционный столбец, а также SQL3 и OQL (Object Query Language) для добавления (ограниченной) поддержки объектов в SQL.

В конце концов, это все вопрос проектирования и компромисса между реляционной моделью и объектной моделью.

/ РЕДАКТИРОВАТЬ после прочтения комментариев: конечно, если ваши данные должны быть доступны для поиска («запрашиваемые»), вы НЕ должны хранить эти данные в виде большого двоичного объекта. Но если некоторые части ваших данных предназначены не для поиска , а для мета-данных, то сохранение этой части данных как объекта внутри большого двоичного объекта может быть хорошим решением, особенно если эти метаданные имеют гибкую структуру и может меняться от объекта к объекту.


5

Давайте приведем практический пример того, когда я делал это в прошлом.

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

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

  • Во-первых, если это иногда терпит неудачу, разве это не дерзко?

    • Например, если в первый раз кто-то использует новую версию приложения, он забывает об открытых им окнах, и что ...
  • Следовательно, если объекты меняются, то есть 100% запасной вариант, поэтому мы не можем прочитать блок.

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

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

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


4

Очень важный фактор: сериализация Java (одна из которых выполняется с помощью реализации Serializable) сама по себе является очень плохим форматом, поэтому вам не следует использовать его для постоянного хранения объектов.

Недостатки Java-сериализации включают в себя:

  • Данные на самом деле не читаются с других языков.
  • Нелегко поддерживать прямую совместимость сериализованных объектов, то есть: если вы добавляете (или удаляете) поля в класс, не так легко читать объекты, созданные в более ранней версии класса.
  • Это не так быстро (но ваш пробег может отличаться)

Так что, если вы используете любой другой формат сериализации, вы получите хорошее хранилище Key-Value, если вы используете Java сериализацию, вы получите беспорядок.


Факты в ответе просто ложны: 1) формат охватывается исчерпывающей спецификацией; 2) добавление полей не является проблемой, формат очень гибкий; 3) скорость зависит от фактических данных, но сопоставима (иногда быстрее, иногда медленнее) с такими форматами, как JSON или XML. По сути, весь ответ неверен, за исключением одной строки: «данные не читаются на других языках».
fdreger

1
Помимо того, 1)что было неправильно, остальная часть ответа является действительным ИМО. Если вы хотите контролировать десериализацию - что необходимо при добавлении / удалении полей (и особенно при наличии конечных полей), интерфейсы кажутся неуклюжими, и вам нужно переопределить больше методов, чем необходимо readObjectи readReplace(для конечных полей).
JB.

Вы не правы, добавление и удаление полей не требует написания каких-либо методов. Что касается последних полей - ваш первоначальный ответ не упоминает их вообще, и если бы он сделал, это было бы неактуально (проблема была бы общей для всех других форматов). Наконец, сказать: «Это не так быстро (но ваш пробег может варьироваться)» просто ничего не значит. Вы правы только в одном факте: тот, что касается других языков. Это очень слабое основание называть что-то «беспорядком».
fdreger

1
Добавление полей не требует написания каких-либо методов, но если вы хотите повлиять на их десериализацию, вам нужно указать это поведение. Я попытаюсь найти некоторые ссылки на проблемы с десериализацией схемы развивающегося объекта.
JB.

3

Это интересная ветка с хорошо продуманными ответами. Не будучи знакомым со всеми последствиями хранения и извлечения сериализованных объектов, я думаю, что было бы интересно дать ответ, который я мог бы дать команде DBA или команде разработчиков:

Ключ заключается в том, чтобы удовлетворить текущие и будущие требования и сделать решение как можно более простым, чтобы минимизировать будущую работу по поддержке. Должны выполняться как функциональные, так и нефункциональные требования (например, инфраструктура и база данных). Помните правило 80/20. Поймите важность приложения для бизнеса и какие усилия по разработке целесообразно.

Не зацикливайтесь на пространстве базы данных, скорости и памяти, если они не являются проблемами.

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

Если решение должно быть прототипом или ранней стадией / версией, то еще больше внимания будет уделяться простоте. Вы всегда можете расширить схему данных позже, если вы планируете это.

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

Стоит учесть, что все реляционные базы данных не используют чистые схемы реляционных баз данных (например, звезды, пространственные, нереляционные ...), также приложения могут использовать реляционные базы данных в качестве нереляционных хранилищ, как в вопросе. Многие основные бизнес-базы данных работают таким образом.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.