Професор сказав нам зберігати серіалізовані об’єкти Java як краплі замість визначення реляційних таблиць


21

Замість того, щоб насправді визначати таблиці з правильними атрибутами, мій професор сказав нам, що ми можемо відобразити об’єкти на ідентифікатори на зразок цього:

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

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

Або я назавжди застряг із цією моделлю, або мені потрібно зробити ще якісь по-справжньому потворні речі, щоб змінити свою модель. ** Це все для мене здається поганою формою. Чи я виправданий, не погоджуючись зі своїм професором? Чи є якась користь від цього, про що я не думав? Якщо я маю рацію, чи варто щось сказати своєму професору про це? Він проповідував це всьому моєму класу і навіть сказав, що таким чином він будував проекти. Друга думка була б чудовою.

Курс названий Software Design .

Мій професор не сказав, що це найкращий спосіб, але він сказав, що це законна альтернатива визначенню реляційних таблиць.

Модель ніяк не динамічна.


Коментарі не для розширеного обговорення; ця розмова переміщена до чату .
Пол Білий каже, що GoFundMonica

Відповіді:


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

  2. Частина жирним шрифтом неправильна. Ви можете легко розширити вже серіалізовані об'єкти, щоб додати нові поля та досягти повної бінарної сумісності зі старими об'єктами. Ви також можете просто створити нові класи замість зміни початкових.

Ваша дискусія з професором повинна зосереджуватися на плюсах і мінусах "реляційного" проти "ключового значення" в різних сценаріях, а не на абстрактній "кращості". Або ви могли б також обговорити, чи переважає Різдво День подяки.

- редагування, прочитавши інші відповіді.

Одна з інших відповідей стосується того, щоб стверджувати, що "важко уявити випадок, коли профі переважають проти мінусів".

Оскільки вся дискусія повинна стосуватися конкретних проблем (інакше ми навіть не можемо визначити «краще» та «гірше»), дозвольте навести один конкретний приклад. Він повністю складений, але я намагався сформувати якомога більше деталей.

Уявіть, що у вас є ігровий сайт в Інтернеті з базою даних, яка зберігає статистику гравців у різних онлайн-іграх (відтворених у браузері, написаних на GWT та перекладених на javascript). Деякі ігри є стратегічними, деякі - екшн-ігри, деякі - платформерами. База даних є реляційною і зберігає гравців та історію гри та рахунок.

Одного дня ви отримуєте додаткову вимогу: дозвольте гравцям зберегти ігровий стан у хмарі під час гри, щоб вони могли перезапустити гру пізніше, в той же момент. Потрібно сказати, що єдиною причиною зберігання цього тимчасового стану є повернення до гри, сама держава ніколи не буде самоаналіз.

Тепер у вас є два основні варіанти:

  • оскільки ігри написані на Java, ви можете досить легко взяти модель, надіслати її на сервер, серіалізувати її в один рядок коду і зберігати як крапку. Таблиця буде називатися "збережені_ігри", і в ній будуть сторонні ключі від гравця тощо. З точки зору бази даних, "зберегти гру" - це непрозора неподільна крапля.

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

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

Також у мене є думка, що сприйняття Джастіна Кейва полягає в тому, що те, що я представив вище, - це "край" або "рідкісний" випадок. Я вважаю, що якщо він не зможе представити якісь важкі дані (на основі репрезентативної вибірки всіх ІТ-проектів у світі, а не лише, скажімо, корпоративних програм у США), я вважатиму таку думку класичним випадком прогнозування упередженість.

Насправді проблема серіалізованих об’єктів Java у реляційній базі даних значно глибша, ніж здається. Це стосується самої основи 1NF, а саме, що є доменом атрибута? . Якщо вас справді цікавить ця тема, є чудова стаття CJ Date, в його Date on Database: Writings 2000-2006 .


Коментарі не для розширеного обговорення; ця розмова переміщена до чату .
Пол Білий каже, що GoFundMonica

22

Чи можуть (і чи можуть) люди успішно реалізовувати проекти, які роблять подібні речі? На жаль, так, вони роблять це досить часто.

Це хороший підхід? Ні це не так. Ви в основному берете свою відносно дорогу базу даних і перетворюєте її на відносно повільну файлову систему. Якщо ви дійсно хочете побудувати систему, яка зберігає її стан шляхом серіалізації та десеріалізації об'єктів, ви можете також скористатися файловою системою, а не використовувати базу даних.

Якщо ви будуєте системи, які зберігають дані шляхом серіалізації об’єктів у базі даних, ви не будете дружити зі своїм DBA. Ви закінчите зберігати зайві дані. У вас з’являться жахливо непослідовні дані - щоразу, коли спільні дані оновлюються, деякі об’єкти закінчуються новими значеннями, а деякі об’єкти - старими. Ви унеможливлюєте будь-яку звітність про дані - все, що хто хоче робити з даними, вимагатиме від когось додаткового коду. Це величезна велика проблема на більшості підприємств, оскільки вони хочуть робити такі речі, як вилучення даних з однієї системи для завантаження в іншу систему або створення системи звітності, яка може доставляти звіти з декількох прикладних програм. Крім того, як ви зазначаєте, вам постійно доведеться вирішувати проблеми, коли ви '

Чи є переваги цього підходу? Я думаю, ви можете стверджувати, що реалізувати першу версію програми досить просто. І це дозволяє розробнику повністю ігнорувати все, що стосується належної взаємодії з базою даних. Мені важко уявити багато випадків, коли ці переваги переважають численні недоліки підходу.

Щодо того, як ви маєте справу з цим конкретним професором, це окреме питання (і це, мабуть, поза сферою цього форуму). Якщо ваш професор активно розробляє проекти в реальному світі, він, мабуть, не буде дуже сприйнятливий до будь-якого аргументу студента про те, що його підхід є принципово неправильним (навіть якщо підхід дійсно принципово неправильний). Можливо, вам більше подобається робити проект так, як хоче професор, і навчитися належним чином зберігати дані самостійно (або іншим курсом).


2
Що ти сказав, плюс два мої центи. Повторність використання - це модульність та обмін. Об'єктна модель фокусується на спільному використанні об'єктів та повторному використанні коду. Модель бази даних фокусується на обміні та повторному використанні даних. Жодна з моделей не є абсолютно дивовижною. Жодна модель не є досконалістю. І дуже, дуже важко помирити це двоє.
Вальтер Мітті

1
Я погоджуюся з цим, але мені не шкода бачити, як професор щось навчає і каже, що це кращий спосіб, не стикаючись з цим. Що з усіма іншими бідними студентами класом, який піде в реальний світ, думаючи, що це правильний шлях?
Кевін

Звичайно. Ця формулювання містить об'єкти, що претендують на дані. І це дані, але не дуже корисні дані.
Вальтер Мітті

Перевага майже завжди знищується, як тільки ви хочете випустити v2 свого додатка.
Енді

10

Бувають ситуації, коли подібний дизайн є розумним, не описуючи, що стосується ваших проектів і як вони використовуються, важко сказати, підходить це чи ні.

Ваша DBA може ненавидіти вас, якщо ви зберігаєте BLOB, але у багатьох ситуаціях єдиною іншою альтернативою є перетворення таблиць у значення атрибутів Entity, що отримує ще більше ненависті від DBA. Інша альтернатива полягає у використанні нереляційних баз даних, як правило, на базі даних, що базуються на об'єктах або на словниках, або на базі даних, орієнтованої на документи, яку деякі DBA, особливо ті, що знають лише реляційні, ненавидять з ще більшою пристрастю. Нереляційна база даних має свої проблеми для вирішення, але, безумовно, може статися так, що використання об’єктної бази даних для зберігання об'єктів може виявити інші проблеми, які ви змогли б легко вирішити у реляційних системах.

Чи є якась користь від цього, про що я не думав?

Зберігання серіалізованого об'єкта означає, що ви можете зберігати без схеми дані (зауважте, що, незважаючи на ім'я, схеми зазвичай не означають, що схеми насправді взагалі немає, а скоріше є лише неявна схема). Існує багато проблемних доменів, де ви не можете визначити схему достроково на час розробки, і де дотримання традиційного дизайну реляційних баз даних означатиме, що вам потрібно змінювати схему бази даних через кожний тиждень або в кінцевому підсумку мати таблицю з 80% стовпців, які не використовуються 80% часу, або сотні різних таблиць для зберігання дійсно однакових даних, жодна з яких не вказує на гарний дизайн. Корінь цього питання, як правило, полягає в тому, що ви змушуєте вбудовувати нереляційну проблему домену у реляційну базу даних.

Звичайно, існує безліч проектів, де люди думають, що їм потрібно використовувати EAV, схематичну схему чи крамничку, яка, як виявляється, зайво спричиняє те, що могло б уникнути болю. Ви обов'язково повинні обговорити зі своїм професором, що таке його міркування, та викладати власні аргументи; прислухайтеся до аргументів і будьте готові до того, що ви можете, нарешті, погодитися з ним, чи ні, можливо, він помиляється.


7

Я робив це раніше - його корисна техніка в певних сценаріях залежить, проте від використовуваного формату серіалізації. Якщо я це роблю, я переконуюсь, що використовую формат серіалізації, який дозволяє мені десерилізувати старі версії моєї моделі (наприклад, XML).

Я зазвичай використовую це в сценаріях, коли формат даних призведе до складної реляційної моделі, яка не дає переваг (наприклад, коли для бізнес-вимог не потрібна фільтрація тощо), і я вже використовую базу даних (для інші реляційні дані). Одним із таких випадків була програма, яка мала запити користувачів - реляційна модель мала декілька таблиць для зберігання таких речей, як умови, вкладені умови (АБО / І т.д. тощо), варіанти сортування тощо ... Це було досить складно, і коли нам потрібно було додати нову функцію, яка вимагала б змінити базу даних. Я замінив все це єдиною таблицею запитів на серіалізовану крапку, що представляє всі інші параметри.

Іншою справою була система, яка обробляла різні "робочі місця". Існувало кілька різних типів завдань, і кожне завдання мало різні параметри, без вимог бізнесу, щоб мати можливість шукати / фільтрувати завдання на основі цих параметрів. Якщо зберігати це як реляційну базу даних, потрібно було б принаймні 1 нову таблицю за типом завдання, що ускладнює додавання нових типів завдань. Натомість параметри зберігаються у вигляді базу даних у базі даних - кожен тип завдань відповідає за серіалізацію та десерталізацію власних параметрів.

Не дуже часто ви натрапляєте на подібний сценарій, але раз у раз та ситуація, як вищезгадані врожаї, коли серіалізація даних про краплі економить ваші зусилля, робить вашу заявку більш рентабельною і не має реальних недоліків.


6

Джастін Кейв вірно вважає, що це може призвести до надмірних даних, але це дійсно залежить від того, як ви проектуєте свою базу даних.

Підхід серіалізації цілого об'єкта до краплі не такий кричущий, як вважає він. Насправді для деяких застосувань це може бути найкращий дизайн, який ви можете зробити, як я пояснив тут: /programming//a/12644223/1121352 .

Дійсно, серіалізація об'єкта призводить до щонайменше двох переваг:

1- Зменшення невідповідності імпедансу : деякі типи Java просто недоступні в SQL, особливо якщо ви використовуєте безліч класів і користувацьких типів, таким чином перетворення назад і назад з об’єктів Java в SQL може бути величезним клопотом і навіть призводити до неоднозначностей.

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

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

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

Як бічна примітка, є кілька спроб деяких виробників БД поєднати реляційні та об'єктні моделі разом, як тип даних JSON в PostSQL та PostgreSQL, так що ви можете безпосередньо обробляти JSON так само, як і будь-який реляційний стовпець, а також SQL3 та OQL (Object Мова запитів) для додавання (обмеженої) підтримки об'єктів у SQL.

Зрештою, це все питання дизайну та компромісу між реляційною моделлю та об'єктною моделлю.

/ Редагуйте після прочитання коментарів: звичайно, якщо ваші дані повинні бути доступними для пошуку ("підлягають запиту"), НЕ слід зберігати свої дані як крапку. Але якщо деякі частини ваших даних призначені не для пошуку , а для мета-даних, то зберігання цієї частини даних як об'єкта всередині блоку може бути хорошим рішенням, особливо якщо ці метадані мають гнучку структуру і може змінюватися від об'єкта до об'єкта.


5

Наведемо практичний приклад того, коли я це робив у минулому.

Ми маємо базу даних, яка містить усі дані для програми користувача користувача; у базі даних також є таблиця користувачів з їх правами доступу. Усі ці дані нормалізуються, як очікувалося.

Потім у нас є запит, щоб програма пам’ятала, які вікна відкрив користувач і що вони робили, щоб він міг відновити стан, коли користувач розпочне роботу наступного ранку.

  • По-перше, якщо це іноді не вдається, чи це не зухвало

    • Наприклад, якщо хтось вперше використовує нову версію програми, він забуває вікна, які вони відкрили, і що ...
  • Тому відбувається 100% запас, якщо об'єкти змінюються, і тому ми не можемо прочитати блок.

  • У нас вже є централізована база даних з контролем доступу, створення резервної копії тощо.
  • Вартість зберігання даних у файлах висока, оскільки файли доведеться розміщувати на якомусь файловому сервері, до якого мають доступ усі машини користувача, або для читання цих файлів потрібно буде написати API.

В інший раз у нас з'явилася програма, яка робила багато тривалих обчислень, і користувачі бажали перезапустити обчислення з останнього відомого пункту, якщо було відключено живлення тощо. Не існує можливості, щоб інша версія від програм можна очікувати перезапуску обчислень, і оскільки було багато об’єктів, які потребували економії, нормалізація даних була б дорогою.

Зважаючи на те, що база даних вже існує і використовується для чітко визначених нормалізованих даних програми, і немає жодної реальної причини не використовувати її для зберігання блогів, ми прийняли розумний і швидкий варіант.


4

Дуже важливий фактор: серіалізація Java (зроблена та увімкнена реалізацією Serializable) сама по собі є дуже поганим форматом, тому ви не повинні реально використовувати її для постійного зберігання об'єктів.

Недоліками серіалізації Java є:

  • Дані насправді не читаються з інших мов.
  • Підтримувати сумісність серіалізованих об'єктів у прямому напрямку непросто, тобто: якщо ви додаєте (або видалите) поля до класу, читати об’єкти, створені попередньою версією класу, не так просто.
  • Це не так швидко (але ваш пробіг може змінюватися)

Отже, якщо ви використовуєте будь-який інший формат серіалізації, ви отримуєте хороший магазин Key-Value, якщо ви використовуєте java серіалізацію, ви отримуєте безлад.


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

1
Крім того, 1)що було неправильним, решта відповідей справедлива ІМО. Якщо ви хочете мати контроль над deserialisaton - який необхідний під час додавання / видалення полів (і особливо, коли є кінцеві поля), інтерфейси здаються незграбними, і вам потрібно перекрити більше методів, необхідних readObjectі readReplace(для остаточних полів).
jb.

Ви помиляєтесь, додавання та видалення полів не вимагає написання будь-яких методів. Щодо заключних полів - ваша оригінальна відповідь взагалі їх не згадує, і якби це було, це було б неактуально (проблема була б спільною для всіх інших форматів). Нарешті, сказати "Це не так швидко (але ваш пробіг може змінюватися)" просто нічого не означає. У вас є лише один факт: той, що стосується інших мов. Це дуже слабка основа для того, щоб називати щось "безладом".
fdreger

1
Додавання полів не вимагає, щоб ви писали будь-які методи, але якщо ви хочете впливати на їх десеріалізацію, вам потрібно вказати цю поведінку. Я спробую викопати деякі посилання на проблеми з десеріалізацією схеми, що розвивається, об'єкта.
jb.

3

Це цікава нитка з кількома добре продуманими відповідями. Не знаючи всіх наслідків зберігання та отримання серіалізованих об'єктів, я думаю, було б цікаво надати відповідь, яку я можу дати команді DBA або команді розробників:

Головне - відповідати поточним та майбутнім вимогам та підтримувати рішення максимально просто, щоб мінімізувати подальшу роботу з підтримки. Необхідно виконувати як функціональні, так і нефункціональні вимоги (наприклад, інфраструктура та база даних). Запам’ятайте правило 80/20. Зрозумійте важливість програми для бізнесу та те, що зусилля з розробки підходять.

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

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

Якщо рішення має бути прототипом або ранньою стадією / версією, ще більше наголосів слід ставити на простоту речей. Ви завжди можете продовжити схему даних пізніше, доки ви плануєте її.

Пам’ятайте, що реляційна база даних не застосовує цілісність або послідовність, якщо схема не охоплює самостійну ділову область і правила бізнесу є суворими. (наприклад, рішення серіалізованого питання об'єкта може розглянути сховище стилю / онтології для забезпечення виконання правил).

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.